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/
<< |