From e876e0bad32ccc461d73bdc3dc3c83f187e9712a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 28 Jun 2013 15:44:04 +0000 Subject: [PATCH] From John Kaniarz, "This patch modifies ReaderWriterPNG.cpp to 1. Check the bit depth of the passed Image and return an error if not 8 or 16. (not fully featured, but still an improvement over hard coded 8bit for everything) 2. Endian swap 16bit image data when on a little endian architecture. " --- src/osgPlugins/png/ReaderWriterPNG.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/osgPlugins/png/ReaderWriterPNG.cpp b/src/osgPlugins/png/ReaderWriterPNG.cpp index 1ff68cec7..83c1ab893 100644 --- a/src/osgPlugins/png/ReaderWriterPNG.cpp +++ b/src/osgPlugins/png/ReaderWriterPNG.cpp @@ -96,6 +96,7 @@ class ReaderWriterPNG : public osgDB::ReaderWriter png_structp png = NULL; png_infop info = NULL; int color; + int bitDepth; png_bytep *rows = NULL; //Create write structure @@ -112,19 +113,22 @@ class ReaderWriterPNG : public osgDB::ReaderWriter //Set compression level png_set_compression_level(png, compression_level); - int bit_depth = img.getPixelSizeInBits(); switch(img.getPixelFormat()) { case(GL_DEPTH_COMPONENT): color = PNG_COLOR_TYPE_GRAY; break; case(GL_LUMINANCE): color = PNG_COLOR_TYPE_GRAY; break; case(GL_ALPHA): color = PNG_COLOR_TYPE_GRAY; break; //Couldn't find a color type for pure alpha, using gray instead - case(GL_LUMINANCE_ALPHA): color = PNG_COLOR_TYPE_GRAY_ALPHA ; bit_depth /= 2; break; - case(GL_RGB): color = PNG_COLOR_TYPE_RGB; bit_depth /= 3; break; - case(GL_RGBA): color = PNG_COLOR_TYPE_RGB_ALPHA; bit_depth /= 4; break; - case(GL_BGR): color = PNG_COLOR_TYPE_RGB; png_set_bgr(png); bit_depth /= 3; break; - case(GL_BGRA): color = PNG_COLOR_TYPE_RGB_ALPHA; png_set_bgr(png); bit_depth /= 4; break; + case(GL_LUMINANCE_ALPHA): color = PNG_COLOR_TYPE_GRAY_ALPHA ; break; + case(GL_RGB): color = PNG_COLOR_TYPE_RGB; break; + case(GL_RGBA): color = PNG_COLOR_TYPE_RGB_ALPHA; break; + case(GL_BGR): color = PNG_COLOR_TYPE_RGB; png_set_bgr(png); break; + case(GL_BGRA): color = PNG_COLOR_TYPE_RGB_ALPHA; png_set_bgr(png); break; default: return WriteResult::ERROR_IN_WRITING_FILE; break; } + //wish there was a Image::computeComponentSizeInBits() + bitDepth = Image::computePixelSizeInBits(img.getPixelFormat(),img.getDataType())/Image::computeNumComponents(img.getPixelFormat()); + if(bitDepth!=8 && bitDepth!=16) return WriteResult::ERROR_IN_WRITING_FILE; + //Create row data rows = new png_bytep[img.t()]; for(int i = 0; i < img.t(); ++i) { @@ -133,11 +137,15 @@ class ReaderWriterPNG : public osgDB::ReaderWriter //Write header info png_set_IHDR(png, info, img.s(), img.t(), - bit_depth, color, PNG_INTERLACE_NONE, + bitDepth, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_write_info(png, info); + //must take place after png_write_info: png_set_swap verifies 16bit depth before setting transformation flag. + if(bitDepth > 8 && getCpuByteOrder()==LittleEndian) png_set_swap(png); + //Write data png_write_image(png, rows);