diff --git a/src/osgPlugins/pnm/ReaderWriterPNM.cpp b/src/osgPlugins/pnm/ReaderWriterPNM.cpp index 864be6f68..5da6bb9f6 100644 --- a/src/osgPlugins/pnm/ReaderWriterPNM.cpp +++ b/src/osgPlugins/pnm/ReaderWriterPNM.cpp @@ -22,16 +22,30 @@ template unsigned char* read_bitmap_ascii(std::istream& fin, int width, int height) { T* data = new T[width*height]; + T* end = data + width*height; + int x = 0; + T* dst = end - width; + int value = 0; + while(dst >= data) { + fin >> value; if (!fin.good()) { delete [] data; return NULL; } + // place value in the image. 0 is white and anything else is black. + *(dst++) = value ? 0 : 255; + + // At end of each row, jump back two rows + ++x; + if (x == width) { + x = 0; + dst -= 2*width; } } @@ -39,11 +53,19 @@ template } template + unsigned char* read_grayscale_ascii(std::istream& fin, int width, int height, int max_value) { T* data = new T[width*height]; + T* end = data + width*height; + int x = 0; + T* dst = end - width; + int value = 0; + float max = (sizeof(T) == 1) ? 255.0 : 65535.0; + while(dst >= data) { + fin >> value; if (!fin.good()) { delete [] data; @@ -51,17 +73,34 @@ template } // place value in the image + *(dst++) = T(float(value)/float(max_value)*max); + + // At end of each row, jump back two rows + ++x; + if (x == width) + { + x = 0; + dst -= 2*width; + } } return reinterpret_cast(data); } template + unsigned char* read_color_ascii(std::istream& fin, int width, int height, int max_value) { T* data = new T[3*width*height]; + T* end = data + 3*width*height; + int x = 0; + T* dst = end - 3*width; + int value = 0; + float max = (sizeof(T) == 1) ? 255.0 : 65535.0; + while(dst >= data) { + fin >> value; if (!fin.good()) { delete [] data; @@ -69,6 +108,15 @@ template } // place value in the image + *(dst++) = T(float(value)/float(max_value)*max); + + // At end of the row, jump back two rows + ++x; + if (x == width*3) + { + x = 0; + dst -= 6*width; + } } return reinterpret_cast(data); @@ -79,6 +127,7 @@ template { T* data = new T[width*height]; + for(int y = height-1; y >= 0; --y) { T* dst = data + (y+0)*width; T* end = data + (y+1)*width; @@ -107,30 +156,55 @@ template template unsigned char* read_grayscale_binary(std::istream& fin, int width, int height) { + T* data = new T[width*height]; + for(int y = height-1; y >= 0; --y) { + T* dst = data + y*width; + fin.read((char*)dst, sizeof(T)*width); + if (!fin.good()) + { + delete [] data; + return NULL; + } } // if the machine is little endian swap the bytes around if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian) { + unsigned char *bs = reinterpret_cast(data); + unsigned char *end = bs + sizeof(T)*width*height; + for (; bs < end; bs += 2) { std::swap(bs[0], bs[1]); } } + return reinterpret_cast(data); } template unsigned char* read_color_binary(std::istream& fin, int width, int height) { + T* data = new T[3*width*height]; + for(int y = height-1; y >= 0; --y) { + T* dst = data + y*3*width; + fin.read((char*)dst, sizeof(T)*3*width); + if (!fin.good()) + { + delete [] data; + return NULL; + } } // if the machine is little endian swap the bytes around if (sizeof(T) == 2 && getCpuByteOrder() == osg::LittleEndian) { + unsigned char *bs = reinterpret_cast(data); + unsigned char *end = bs + sizeof(T)*3*width*height; + for (; bs < end; bs+=2) { std::swap(bs[0], bs[1]); } @@ -225,9 +299,11 @@ class ReaderWriterPNM : public osgDB::ReaderWriter { case 2: // grayscale ascii pixelFormat = GL_LUMINANCE; + data = read_grayscale_ascii(fin, width, height, max_value); break; case 3: // color ascii pixelFormat = GL_RGB; + data = read_color_ascii(fin, width, height, max_value); break; case 5: // grayscale binary pixelFormat = GL_LUMINANCE; @@ -237,6 +313,9 @@ class ReaderWriterPNM : public osgDB::ReaderWriter pixelFormat = GL_RGB; data = read_color_binary(fin, width, height); break; + default: + return ReadResult::ERROR_IN_READING_FILE; + break; } } else @@ -250,9 +329,11 @@ class ReaderWriterPNM : public osgDB::ReaderWriter break; case 2: // grayscale ascii pixelFormat = GL_LUMINANCE; + data = read_grayscale_ascii(fin, width, height, max_value); break; case 3: // color ascii pixelFormat = GL_RGB; + data = read_color_ascii(fin, width, height, max_value); break; case 4: // bitmap binary pixelFormat = GL_LUMINANCE; @@ -266,6 +347,9 @@ class ReaderWriterPNM : public osgDB::ReaderWriter pixelFormat = GL_RGB; data = read_color_binary(fin, width, height); break; + default: + return ReadResult::ERROR_IN_READING_FILE; + break; } }