The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly. |
Home Reading PNG Images readpng_get_bgcolor() | |
readpng_get_bgcolor()int readpng_get_bgcolor(uch *red, uch *green, uch *blue) As before, we start with a setjmp() block to handle libpng errors, then check whether the PNG file had a bKGD chunk: if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) return 1; png_color_16p pBackground; png_get_bKGD(png_ptr, info_ptr, &pBackground); (pBackground was defined at the top of the function.)
pBackground now points at a png_color_16 struct, which is defined
as follows:
typedef struct png_color_16_struct { png_byte index; png_uint_16 red; png_uint_16 green; png_uint_16 blue; png_uint_16 gray; } png_color_16; As suggested by the struct members' names, not all of them are valid with all PNG image types. The first member, index, is only valid with palette-based images, for example, and gray is only valid with grayscale images. But it is one of libpng's handy little features (presently undocumented) that the red, green, and blue struct members are always valid, and those happen to be precisely the values we want. The other thing to note, however, is that the elements we need are defined
as png_uint_16, i.e., as 16-bit (or larger)
unsigned integers. That
Since we'll be dealing only with 8-bit samples in this program, and, in particular, since the arguments to readpng_get_bgcolor() are pointers to unsigned (8-bit) characters, we need to shift the high-order bits down in the case of 16-bit data or expand them in the case of low-bit-depth values (only possible with grayscale images). And either way, we need to pass the values back to the main program. Thus: if (bit_depth == 16) { *red = pBackground->red >> 8; *green = pBackground->green >> 8; *blue = pBackground->blue >> 8; } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { if (bit_depth == 1) *red = *green = *blue = pBackground->gray? 255 : 0; else if (bit_depth == 2) /* i.e., max value is 3 */ *red = *green = *blue = (255/3) * pBackground->gray; else /* bit_depth == 4 */ /* i.e., max value is 15 */ *red = *green = *blue = (255/15) * pBackground->gray; } else { *red = pBackground->red; *green = pBackground->green; *blue = pBackground->blue; } return 0; With that, the main program now has enough information to create an image window of the proper size and fill it with the background color, which it does. The top row of Figure C-5 in the color insert shows the two cases: the middle image is displayed with the background color specified in the PNG file itself, while the image on the right is shown with a user-specified background color.
|
|
Home Reading PNG Images readpng_get_bgcolor() |