From 86254927b9661b00fcd638e6caacccad29eb7d37 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Apr 2003 15:40:57 +0000 Subject: [PATCH] From Eric Sokolowsky - pnm (ppm, pgm, pbm) plugin --- AUTHORS.txt | 5 + Make/makedirdefs | 3 + VisualStudio/VisualStudio.dsw | 18 ++ VisualStudio/osg/osg.dsp | 8 + VisualStudio/osgPlugins/pnm/pnm.dsp | 109 ++++++++++ src/osgDB/Registry.cpp | 7 +- src/osgPlugins/pnm/GNUmakefile | 13 ++ src/osgPlugins/pnm/ReaderWriterPNM.cpp | 275 +++++++++++++++++++++++++ 8 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 VisualStudio/osgPlugins/pnm/pnm.dsp create mode 100644 src/osgPlugins/pnm/GNUmakefile create mode 100644 src/osgPlugins/pnm/ReaderWriterPNM.cpp diff --git a/AUTHORS.txt b/AUTHORS.txt index 050cedd63..38a1f8a6c 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -134,6 +134,11 @@ Rune Schmidt Jensen Romano José Magacho da Silva - pause/resume in osgGA::AnimationPathManipulator - support for managing deleted vertex programs in osg::VertexProgram. + + +Eric Sokolowsky + - pbm/pgm/ppm reader. + Indirect Contributors --------------------- diff --git a/Make/makedirdefs b/Make/makedirdefs index b9c2a0d59..0b3dd7b72 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -40,6 +40,7 @@ PLUGIN_DIRS = \ osg\ osgtgz\ pic\ + pnm\ rgb\ tga\ tgz\ @@ -139,6 +140,8 @@ EXAMPLE_DIRS = \ osgvertexprogram\ osgviewer\ +# osgautotransform\ +# osgprerendercubemap\ # osgjigsaw\ # comment in you want to compile the cluster demo. diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index 055db8515..5dc5bf176 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -1644,6 +1644,24 @@ Package=<4> ############################################################################### +Project: "osgPlugin pnm"=.\osgPlugins\pnm\pnm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Core osg + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgDB + End Project Dependency +}}} + +############################################################################### + Project: "osgPlugin dds"=.\osgPlugins\dds\dds.dsp - Package Owner=<4> Package=<5> diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 52fdbc775..5100dcc7c 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -113,6 +113,10 @@ SOURCE=..\..\src\osg\Array.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\AutoTransform.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\Billboard.cpp # End Source File # Begin Source File @@ -477,6 +481,10 @@ SOURCE=..\..\Include\osg\ApplicationUsage # End Source File # Begin Source File +SOURCE=..\..\Include\osg\AutoTransform +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\Billboard # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/pnm/pnm.dsp b/VisualStudio/osgPlugins/pnm/pnm.dsp new file mode 100644 index 000000000..3382fe9fc --- /dev/null +++ b/VisualStudio/osgPlugins/pnm/pnm.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="osgPlugin pnm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=osgPlugin pnm - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pnm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pnm.mak" CFG="osgPlugin pnm - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "osgPlugin pnm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "osgPlugin pnm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "osgPlugin pnm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../../lib" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_pnm.dll" /libpath:"../../../lib" +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "osgPlugin pnm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../../../lib" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WIN32" /D "_DEBUG" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_pnmd.dll" /pdbtype:sept /libpath:"../../../lib" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "osgPlugin pnm - Win32 Release" +# Name "osgPlugin pnm - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\pnm\ReaderWriterPNM.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 4e6cf7003..43e7dd9a0 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -99,7 +99,12 @@ Registry::Registry() // wont't add type1 and type2 until resolve extension collision with Peformer binary and ascii files. // addFileExtensionAlias("pfb", "freetype"); // type1 binary // addFileExtensionAlias("pfa", "freetype"); // type2 ascii - + + + // portable bitmap, greyscale and colour/pixmap image formats + addFileExtensionAlias("pbm", "pnm"); + addFileExtensionAlias("pgm", "pnm"); + addFileExtensionAlias("ppm", "pnm"); } diff --git a/src/osgPlugins/pnm/GNUmakefile b/src/osgPlugins/pnm/GNUmakefile new file mode 100644 index 000000000..376dd6ac7 --- /dev/null +++ b/src/osgPlugins/pnm/GNUmakefile @@ -0,0 +1,13 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + ReaderWriterPNM.cpp\ + +LIBS += $(OSG_LIBS) $(OTHER_LIBS) + +TARGET_BASENAME = png +include $(TOPDIR)/Make/cygwin_plugin_def +PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgPlugins/pnm/ReaderWriterPNM.cpp b/src/osgPlugins/pnm/ReaderWriterPNM.cpp new file mode 100644 index 000000000..a23c90e10 --- /dev/null +++ b/src/osgPlugins/pnm/ReaderWriterPNM.cpp @@ -0,0 +1,275 @@ +// PNM Reader -- Written by Eric Sokolowsky +// Reads Ascii and Binary files in the PPM, PGM, and PBM formats. + +#include +#include + +#include +#include + +#include + +using namespace osg; + + +class ReaderWriterPNM : public osgDB::ReaderWriter +{ + public: + virtual const char* className() { return "PNM Image Reader/Writer"; } + virtual bool acceptsExtension(const std::string& extension) + { + return osgDB::equalCaseInsensitive(extension, "pnm") || + osgDB::equalCaseInsensitive(extension, "ppm") || + osgDB::equalCaseInsensitive(extension, "pgm") || + osgDB::equalCaseInsensitive(extension, "pbm"); + } + + virtual ReadResult readImage(const std::string& fileName, const osgDB::ReaderWriter::Options*) + { + if( !acceptsExtension(osgDB::getFileExtension(fileName) )) + return ReadResult::FILE_NOT_HANDLED; + + FILE *fp = NULL; + char line[300]; + int ppmtype = 0; /* P1, P2, etc. */ + int width = 0; + int height = 0; + int max_value = 0; + + bool binary_flag = false; + int shift_value = 0; // if greater than 8 bits + + + // Open file. + fp = fopen(fileName.c_str(), "rb"); + + // Read header items. + int row; + for (row = 1; row <= 3; row++) + { + fgets(line, 300, fp); + + char *cp = line; + while (*cp && isspace(*cp)) + cp++; + if (! *cp || *cp == '#') + { + // Skip comment lines. + row--; + } + else if (row == 1) + { + // Get the image type. + if (line[0] == 'p' || line[0] == 'P') + { + ppmtype = line[1] - '0'; + } + } + else if (row == 2) + { + // Get the image size. + width = atoi(line); + char *cp = line + strspn(line, "\t \n\r"); + cp += strspn(cp, "0123456789"); + cp += strspn(line, "\t \n\r"); + height = atoi(cp); + + // pbm files don't have row 3 + if (ppmtype == 1 || ppmtype == 4) + { + max_value = 1; + break; + } + } + else if (row == 3) + { + // Get the maximum value + max_value = atoi(line); + } + } + + // Check for valid values. + if (width <= 0 || height <= 0 || max_value <= 0 || ppmtype < 1 || + ppmtype > 6) + { + fclose(fp); + return ReadResult::FILE_NOT_HANDLED; + } + + // Check for binary file. + if (ppmtype >= 4 && ppmtype <= 6) + binary_flag = true; + + // Warn the user if the full image cannot be used. + if (max_value > 255) + { + osg::notify(osg::NOTICE) << "PNM file " << fileName << + " has channels larger than " + " 8 bits. Color resolution will be lost." << std::endl; + + while (max_value > 255) + { + max_value >>= 1; + shift_value++; + } + } + + // We always create a RGB image, no matter what type of + // source it was. + unsigned char *data = new unsigned char [width * height * 3]; + + + + // For the ascii files + if (!binary_flag) + { + unsigned char *end = data + width * height * 3; + unsigned char *dst = data; + + char s_num[300]; + int s_num_count; + int value = fgetc(fp); + + while (dst < end) + { + if (feof(fp) || ferror(fp)) + { + fclose(fp); + delete[] data; + return ReadResult::FILE_NOT_HANDLED; + } + + // Read any extra whitespace + //while (isspace(value)) + while (!isdigit(value)) + { + value = fgetc(fp); + } + + // Read any numeric digits + s_num_count = 0; + while (isdigit(value)) + { + s_num[s_num_count++] = value; + value = fgetc(fp); + } + // Don't forget to terminate the string! + s_num[s_num_count] = 0; + + if (s_num_count == 0) + { + fclose(fp); + delete[] data; + return ReadResult::FILE_NOT_HANDLED; + } + + unsigned int data_value = atoi(s_num) >> shift_value; + + // Now we have our value. Put it into the array + // in the appropriate place. + if (ppmtype == 1) + { + if (data_value == 1) + data_value = 0; + else + data_value = 255; + + *(dst++) = data_value; + *(dst++) = data_value; + *(dst++) = data_value; + } + else if (ppmtype == 2) + { + *(dst++) = data_value; + *(dst++) = data_value; + *(dst++) = data_value; + } + else if (ppmtype == 3) + { + *(dst++) = data_value; + } + } + } + + // If we have a binary bitmap + else if (ppmtype == 4) + { + unsigned char *end = data + width * height * 3; + unsigned char *dst = data; + + while (dst < end) + { + unsigned char b = (unsigned char) fgetc(fp); + if (feof(fp) || ferror(fp)) + { + fclose(fp); + delete[] data; + return ReadResult::FILE_NOT_HANDLED; + } + + int i; + for (i = 7; i >= 0 && dst < end; i--) + { + // 1 means black, 0 means white + int data_value = (b & (1<= data) + { + *(--dst) = *(--src); + *(--dst) = *src; + *(--dst) = *src; + } + } + + // If we have a binary ppm, reading is very easy. + else if (ppmtype == 6) + { + int result = fread(data, width * height * 3, 1, fp); + if (result != 1) + { + fclose(fp); + delete[] data; + return ReadResult::FILE_NOT_HANDLED; + } + } + + if (fp) + fclose(fp); + + osg::Image* pOsgImage = new osg::Image(); + + pOsgImage->setFileName(fileName.c_str()); + pOsgImage->setImage(width, height, 1, + 3,// int internalFormat, + GL_RGB, // unsigned int pixelFormat + GL_UNSIGNED_BYTE,// unsigned int dataType + data, + osg::Image::USE_NEW_DELETE); + pOsgImage->flipVertical(); + + return pOsgImage; + } +}; + +// now register with Registry to instantiate the above +// reader/writer. +osgDB::RegisterReaderWriterProxy g_readerWriter_PNM_Proxy;