DevNote Dec-03-2009

ImageIO doesn't properly handle PNG transparency (part 2)

You can read the first part here.

Dec-03-2009

After some hours of investigation, I found the cause of another half of my problem (PNG with transparency got black edges). The alpha channel of an RGBA image is completely ignored. The cause apparently is that GL_UNSIGNED_INT_8_8_8_8_REV is specified for the data type in calling osg_image::setImage() for 32 bpp images, but this somehow makes OpenGL (or osg::Image) ignore the alpha channel. I tried so many combinations of data_type, pixel_format, and internal_format for avoiding this but none worked well. After tons of trial, I tried GL_UNSIGNED_BYTE for data_type, and this worked like a charm!!

So I tried this workaround on ppc Mac (using rosetta). I got weird colors on the first try so I made some tweaks like changing data_type, pixel_format, or internal_format, but none gave me a good result. After many failures, I decided to swap the endian of each pixel for ppc before un-multiplying the color values.... And that worked great!! Though I think there is some smarter ways than this, it is enough at this moment at least for me.

Now it's time to check if these workarounds work on different image formats. I tried osgviewer with this image in several different formats (like tiff, tga, psd, and gif converted by Gimp) on both intel and ppc (using rosetta). The results are shown in the table below.

formatpixel formatsizeresult
GIFINDEXED/dithered256x256OK
PNGRGBA256x256OK
PSDRGBA256x256OK
TGARGBA256x256OK
TIFFRGBA256x256OK
GIFINDEXED Grayscale/dithered256x256OK
PNGGrayscale+A256x256OK
PSDGrayscale+A256x256OK
TGAGrayscale+A256x256N/A(image converted by Gimp seems corrupted)
TIFFGrayscale+A256x256OK
GIFINDEXED Grayscale/dithered300x300OK
PNGGrayscale+A300x300OK
PSDGrayscale+A300x300OK
TGAGrayscale+A300x300N/A(image converted by Gimp seems corrupted)
TIFFGrayscale+A300x300OK

It seems working on almost all supported formats. I also tried these images with the original imageio plugin for comparison, and all of images had black edges. This means that this problem is not only on the PNG but on all supported images....

Anyways, I'm very happy that I can use PNG textures with no problem!

By the way, I found that the osgdb_bmp plugin also has the same problem (sigh....). I will look at the code if I have time.

You can get the patch for OpenSceneGraph/src/osgPlugins/imageio/ReaderWriterImageio.cpp.