Fix for libpng 1.5.

png_struct and png_info are no longer transparent, so we have to go
through the proper libpng functions. There still appear to be some
issues; see http://www.schaik.com/pngsuite/pngsuite.html and
http://www.libpng.org/pub/png/pngsuite.html
This commit is contained in:
Sean Bartell 2012-03-15 20:17:15 -04:00
parent 7f466dc054
commit d1656941c1

View file

@ -94,7 +94,15 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
png_struct *png_ptr;
png_info *info_ptr;
double screen_gamma;
png_uint_32 raw_width, raw_height, rowbytes;
int bit_depth, color_type, interlace_type, compression_type, filter_type;
png_uint_32 have_palette;
png_colorp palette;
int num_palette;
png_uint_16p hist = NULL;
double gamma, screen_gamma;
png_byte *png_pixels=NULL, **row_pointers=NULL;
int i, j;
@ -176,20 +184,26 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
/* setup other stuff using the fields of png_info. */
*width = (int)png_ptr->width;
*height = (int)png_ptr->height;
png_get_IHDR(png_ptr, info_ptr, &raw_width, &raw_height, &bit_depth,
&color_type, &interlace_type, &compression_type,
&filter_type);
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
have_palette = png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
*width = (int)raw_width;
*height = (int)raw_height;
#ifndef DISABLE_TRACE
if (srcTrace) {
fprintf(stderr,"\n\nBEFORE\nheight = %d\n", (int)png_ptr->width);
fprintf(stderr,"width = %d\n", (int)png_ptr->height);
fprintf(stderr,"bit depth = %d\n", info_ptr->bit_depth);
fprintf(stderr,"color type = %d\n", info_ptr->color_type);
fprintf(stderr,"compression type = %d\n", info_ptr->compression_type);
fprintf(stderr,"filter type = %d\n", info_ptr->filter_type);
fprintf(stderr,"interlace type = %d\n", info_ptr->interlace_type);
fprintf(stderr,"num colors = %d\n",info_ptr->num_palette);
fprintf(stderr,"rowbytes = %d\n", info_ptr->rowbytes);
fprintf(stderr,"\n\nBEFORE\nwidth = %d\n", *width);
fprintf(stderr,"height = %d\n", *height);
fprintf(stderr,"bit depth = %d\n", bit_depth);
fprintf(stderr,"color type = %d\n", color_type);
fprintf(stderr,"compression type = %d\n", compression_type);
fprintf(stderr,"filter type = %d\n", filter_type);
fprintf(stderr,"interlace type = %d\n", interlace_type);
fprintf(stderr,"num colors = %d\n", num_palette);
fprintf(stderr,"rowbytes = %d\n", rowbytes);
}
#endif
@ -212,16 +226,16 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
#endif
/* strip pixels in 16-bit images down to 8 bits */
if (info_ptr->bit_depth == 16)
if (bit_depth == 16)
png_set_strip_16(png_ptr);
/* If it is a color image then check if it has a palette. If not
then dither the image to 256 colors, and make up a palette */
if (info_ptr->color_type==PNG_COLOR_TYPE_RGB ||
info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
if (color_type==PNG_COLOR_TYPE_RGB ||
color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
if(! (info_ptr->valid & PNG_INFO_PLTE)) {
if(!have_palette) {
#ifndef DISABLE_TRACE
if (srcTrace) {
@ -239,9 +253,7 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
/* this should probably be dithering to
Rdata.colors_per_inlined_image colors */
png_set_dither(png_ptr, std_color_cube,
216,
216, NULL, 1);
png_set_quantize(png_ptr, std_color_cube, 216, 216, NULL, 1);
} else {
#ifndef DISABLE_TRACE
@ -250,10 +262,9 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
}
#endif
png_set_dither(png_ptr, info_ptr->palette,
info_ptr->num_palette,
get_pref_int(eCOLORS_PER_INLINED_IMAGE),
info_ptr->hist, 1);
png_get_hIST(png_ptr, info_ptr, &hist);
png_set_quantize(png_ptr, palette, num_palette,
get_pref_int(eCOLORS_PER_INLINED_IMAGE), hist, 1);
}
}
@ -262,14 +273,14 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
small as they can. This expands pixels to 1 pixel per byte, and
if a transparency value is supplied, an alpha channel is
built.*/
if (info_ptr->bit_depth < 8)
if (bit_depth < 8)
png_set_packing(png_ptr);
/* have libpng handle the gamma conversion */
if (get_pref_boolean(eUSE_SCREEN_GAMMA)) { /*SWP*/
if (info_ptr->bit_depth != 16) { /* temporary .. glennrp */
if (bit_depth != 16) { /* temporary .. glennrp */
screen_gamma=(double)(get_pref_float(eSCREEN_GAMMA));
#ifndef DISABLE_TRACE
@ -277,13 +288,13 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
fprintf(stderr,"screen gamma=%f\n",screen_gamma);
}
#endif
if (info_ptr->valid & PNG_INFO_gAMA) {
if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
#ifndef DISABLE_TRACE
if (srcTrace) {
printf("setting gamma=%f\n",info_ptr->gamma);
printf("setting gamma=%f\n", gamma);
}
#endif
png_set_gamma(png_ptr, screen_gamma, (double)info_ptr->gamma);
png_set_gamma(png_ptr, screen_gamma, gamma);
}
else {
#ifndef DISABLE_TRACE
@ -296,34 +307,39 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
}
}
if (info_ptr->interlace_type)
if (interlace_type)
png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &raw_width, &raw_height, &bit_depth,
&color_type, &interlace_type, &compression_type,
&filter_type);
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
have_palette = png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
#ifndef DISABLE_TRACE
if (srcTrace) {
fprintf(stderr,"\n\nAFTER\nheight = %d\n", (int)png_ptr->width);
fprintf(stderr,"width = %d\n", (int)png_ptr->height);
fprintf(stderr,"bit depth = %d\n", info_ptr->bit_depth);
fprintf(stderr,"color type = %d\n", info_ptr->color_type);
fprintf(stderr,"compression type = %d\n", info_ptr->compression_type);
fprintf(stderr,"filter type = %d\n", info_ptr->filter_type);
fprintf(stderr,"interlace type = %d\n", info_ptr->interlace_type);
fprintf(stderr,"num colors = %d\n",info_ptr->num_palette);
fprintf(stderr,"rowbytes = %d\n", info_ptr->rowbytes);
fprintf(stderr,"\n\nAFTER\nwidth = %d\n", *width);
fprintf(stderr,"height = %d\n", *height);
fprintf(stderr,"bit depth = %d\n", bit_depth);
fprintf(stderr,"color type = %d\n", color_type);
fprintf(stderr,"compression type = %d\n", compression_type);
fprintf(stderr,"filter type = %d\n", filter_type);
fprintf(stderr,"interlace type = %d\n", interlace_type);
fprintf(stderr,"num colors = %d\n",num_palette);
fprintf(stderr,"rowbytes = %d\n", rowbytes);
}
#endif
/* allocate the pixel grid which we will need to send to
png_read_image(). */
png_pixels = (png_byte *)malloc(info_ptr->rowbytes *
(*height) * sizeof(png_byte));
png_pixels = (png_byte *)malloc(rowbytes * (*height) * sizeof(png_byte));
row_pointers = (png_byte **) malloc((*height) * sizeof(png_byte *));
for (i=0; i < *height; i++)
row_pointers[i]=png_pixels+(info_ptr->rowbytes*i);
row_pointers[i]=png_pixels+(rowbytes*i);
/* FINALLY - read the darn thing. */
@ -332,13 +348,13 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
/* now that we have the (transformed to 8-bit RGB) image, we have
to copy the resulting palette to our colormap. */
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) {
if (info_ptr->valid & PNG_INFO_PLTE) {
if (color_type & PNG_COLOR_MASK_COLOR) {
if (have_palette) {
for (i=0; i < info_ptr->num_palette; i++) {
colrs[i].red = info_ptr->palette[i].red << 8;
colrs[i].green = info_ptr->palette[i].green << 8;
colrs[i].blue = info_ptr->palette[i].blue << 8;
for (i=0; i < num_palette; i++) {
colrs[i].red = palette[i].red << 8;
colrs[i].green = palette[i].green << 8;
colrs[i].blue = palette[i].blue << 8;
colrs[i].pixel = i;
colrs[i].flags = DoRed|DoGreen|DoBlue;
}
@ -373,7 +389,7 @@ ReadPNG(FILE *infile,int *width, int *height, XColor *colrs)
/* if there is an alpha channel, we have to get rid of it in the
pixmap, since I don't do anything with it yet */
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) {
if (color_type & PNG_COLOR_MASK_ALPHA) {
#ifndef DISABLE_TRACE
if (srcTrace) {