PNG Decoder in C++   

ysflight.com

Introduction


If you buy a product from the above links (you can choose a different product after opening Amazon.com web page,) I can earn some referral fee.  Please help maintain ysflight.com!  Thank you!

From this page you can download a PNG decoder that I've written for my fun.  I've been using BMP file if I need to include a picture in my program for both my job and my hobby.  However, it easily blows the total size of the project directory because BMP format doesn't include any compression scheme.  So, I wrote a PNG decoder.  I suppose some of you have the same problem, so I open the PNG decoder.  It covers most practical bit depths although not all of the bit depths are supported.

PNG is good for hand written pictures, and not as efficient for photos as JPEG because it uses lossless compression scheme.  However, I figured that the compression rate heavily depends on the program you use.  For example,  Paint Shop Pro creates 20 to 30% smaller PNG of a photo than Microsoft Photo Editor, which comes with MS Office.  So, if you need to put a picture in your program, why don't you use PNG?

By the way, YSFLIGHT project is running with marginal budget.  Please visit the following page, and help this project.  Thank you very much for your support!

http://supportysflight.en.ysflight.com

Disclaimer

The source codes you can download from this page -- files included in yspng.zip -- are free to use for any purposes.  You can use it in a free software or a commercial software, open-source or proprietary.  In any cases, you don't need to contact me for permissions.  You even don't have to mention about this web page, but I'll be happy if you put a reference to this page.

However, I do not take any responsibility for the consequence resulted by the use of these codes.  Please use these codes on your own risks.

Download

yspng.zip (including sample.cpp, yspng.h, yspng.cpp, and win32sample)

Updates

05/15/2005
An easy Linux (GLX) sample PNG viewer is added in the archive (yspng.zip).

05/07/2005
An easy Win32 sample PNG viewer is added in the archive (yspng.zip).

04/08/2005
Started this page.  Still, far from intensively-tested.  So, there can be loads of bugs in it.

Tested Compilers

I have tested this code with Visual C++ 6.0, Visual C++ .NET, and g++.

Supported Bit-Depths

Non-Interlace Interlace
1bit Grayscale (B & W) Alpha not supported Not Supported
4bit Indexed Color OK Not Supported
8bit Grayscale OK OK
8bit Grayscale with Alpha OK OK
8bit Indexed Color OK OK
24bit True Color (*1) OK OK
24bit True Color with Alpha (*1) OK OK
48bit True Color (*2) OK OK

(*1) The PNG specification describes 24bit true color as 8 bit true color (8 bit per component).  But, I think we commonly say "24bit true color" for describing 8-bit-per-component color.  So, I describe it as 24 bit true color here.

(*2) Same as the logic of (*1) I describe 16bit-per-component color as 48bit true color here.

Usage of PNG Decoder Classes

To use the PNG decoder classes, the source code that uses the classes must include yspng.h, and yspng.cpp must be added to the project.

The source codes yspng.h and yspng.cpp include two classes YsGenericPngDecoder and YsRawPngDecoder  YsGenericPngDecoder reads header information and decompress the compressed bitmap data.  However, it does not organize pixels into a format that can directly be transferred to the screen.

YsRawPngDecoder class reads PNG file, and makes an array of R, G, B, and A values, 8bit per component.  The array can be passed to a function like glDrawPixels directly to draw the bitmap image.  (But, if you use glDrawPixels will draw the picture upside-down.  So, you need to flip it before drawing.  You can do it by using Flip member function.  Please see sample.cpp for more details.)  I suppose you only need YsRawPngDecoder for practical purposes.

I describe a brief explanation of each class below.

Please see also sample.cpp for the usage. 

YsGenericPngDecoder

YsGenericPngDecoder itself does nothing unless you inherit the class and override the member functions -- PrepareOutput, Output, and EndOutput.  If you just need a quick and easy method for getting an array of bitmap, please use YsRawPngDecoder class.

Functions

  • void Initialize(void);
    It initializes the content of the class variable.
  • int Decode(const char fn[]);
    It decodes a PNG file specified by fn.
  • virtual int PrepareOutput(void);
    Decode function first calls this function.
  • virtual int Output(unsigned char dat);
    Decode function passes a byte from the stream of bitmap as it is uncompressed.
  • virtual int EndOutput(void);
    Decode function calls this function after reading all the content of the PNG file.

Variables

  • YsPngHeader hdr;
    Header information.  hdr.width and hdr.height will give the number of pixels.
  • YsPngPalette plt;
    Palette information.
  • YsPngTransparency trns;
    Transparency information.
  • unsigned int gamma;
    Gamma value.  Please read [1] for more details.

YsRawPngDecoder

YsRawPngDecoder class reads a PNG file and makes an array of pixels with R, G, B, and A, 8bit per component.  I think you only need this class practically.

Functions

  • int Decode(const char fn[]);
    It decodes a PNG file specified by fn, and stores the number of pixels in member variables wid and hei, and a pointer to the array of the bitmap in member variable rgba.  If the function succeeds, it returns a macro YSOK, otherwise it returns YSERR.  If your program needs to use the bitmap decoded by this function after the lifetime of the YsRawPngDecoder variable, zero must be set to member variable autoDeleteRgbaBuffer.  Otherwise, the class will automatically delete the array in the destructor.

  • void Flip(void);
    It inverts the image upside-down.  One of the purposes of this class is to draw a PNG bitmap image with OpenGL, but glDrawPixels itself draws a picture upside-down, so I added this function.

Variables

  • int wid,hei;
    The number of pixels of the decoded PNG file.
  • unsigned char *rgba;
    A pointer to the array of bitmaps of the decoded PNG.  Each pixel consists of four components, R, G, B, and A (A is inverse of the transparency.)  Each of R, G, B, and A is 8bit (one unsigned char.)

  • int autoDeleteRgbaBuffer;
    If this variable is non-zero, the memory block that is pointed by rgba is deleted in the destructor of YsRawPngDecoder class.  If your program needs to use the array of the bitmap of the decoded PNG, zero must be set to this variable.  In that case, the memory block must be deleted by your program (like by delete [] rgba;), or the memory block will be remain allocated as memory leak.

References

[1] W3C, Portable Network Graphics (PNG) Specification (Second Edition),  http://www.w3.org/TR/PNG/

<<

Comments are welcome.  Send E-Mail to: 

Back to http://www.ysflight.com

@