Content-Type: multipart/mixed; boundary="y0ulUmNC+osPPQO6" Content-Disposition: inline --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hello, NetPBM's tools "pngtopnm", "pamrgbatopng" and "pnmtopng" cannot be compiled with version 1.5 of the PNG library because they look into and change the private data structure instead of using the documented API. I've committed a bunch of patches to NetBSD's "pkgsrc" tree which fixes these problems: http://mail-index.netbsd.org/pkgsrc-changes/2011/01/15/msg050723.html I've attached the patches for your convenience. NetPBM 10.35.78 with these patches applied compiles and works fine under NetBSD 5.1 and Mac OS 10.6.6. I've also fixed a bug where "pngtopnm" would report that the PNG file contains a history chunk if it really contain a palette. Kind regards -- Matthias Scheler http://zhadum.org.uk/ --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-ak Content-Transfer-Encoding: quoted-printable $NetBSD: patch-ak,v 1.9 2011/01/14 21:51:59 tron Exp $ Fix build with png-1.5. --- converter/other/pngtxt.c.orig 2006-08-19 04:12:28.000000000 +0100 +++ converter/other/pngtxt.c 2011-01-14 21:28:09.000000000 +0000 @@ -240,7 +240,8 @@ void -pnmpng_read_text (png_info * const info_ptr, +pnmpng_read_text (png_struct * png_ptr, + png_info * info_ptr, FILE * const tfp, bool const ztxt, bool const verbose) { @@ -250,6 +251,7 @@ unsigned int commentIdx; bool noCommentsYet; bool eof; + png_textp text_ptr; unsigned int allocatedComments; /* Number of entries currently allocated for the info_ptr->text array @@ -257,8 +259,8 @@ allocatedComments = 256; /* initial value */ - MALLOCARRAY(info_ptr->text, allocatedComments); - if (info_ptr->text == NULL) + MALLOCARRAY(text_ptr, allocatedComments); + if (text_ptr == NULL) pm_error("unable to allocate memory for comment array"); commentIdx = 0; @@ -273,7 +275,7 @@ if (lineLength == 0) { /* skip this empty line */ } else { - handleArrayAllocation(&info_ptr->text, &allocatedComments, + handleArrayAllocation(&text_ptr, &allocatedComments, commentIdx); if ((textline[0] != ' ') && (textline[0] != '\t')) { /* Line doesn't start with white space, which @@ -285,7 +287,7 @@ ++commentIdx; noCommentsYet = FALSE; - startComment(&info_ptr->text[commentIdx], + startComment(&text_ptr[commentIdx], textline, lineLength, ztxt); } else { /* Line starts with whitespace, which means it is @@ -295,20 +297,20 @@ pm_error("Invalid comment file format: " "first line is a continuation line! " "(It starts with whitespace)"); - continueComment(&info_ptr->text[commentIdx], + continueComment(&text_ptr[commentIdx], textline, lineLength); } } pm_strfree(textline); } } - if (noCommentsYet) - info_ptr->num_text = 0; - else - info_ptr->num_text = commentIdx + 1; + if (!noCommentsYet) + png_set_text(png_ptr, info_ptr, text_ptr, commentIdx + 1); if (verbose) - pm_message("%d comments placed in text chunk", info_ptr->num_text); + pm_message("%d comments placed in text chunk", commentIdx + 1); + + free(text_ptr); } --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-aj Content-Transfer-Encoding: quoted-printable $NetBSD: patch-aj,v 1.13 2011/01/14 21:51:59 tron Exp $ Fix build with png-1.5. --- converter/other/pngtxt.h.orig 2006-08-19 04:12:28.000000000 +0100 +++ converter/other/pngtxt.h 2011-01-14 21:39:26.000000000 +0000 @@ -5,7 +5,8 @@ #include void -pnmpng_read_text (png_info * const info_ptr, +pnmpng_read_text (png_struct * png_ptr, + png_info * const info_ptr, FILE * const tfp, bool const ztxt, bool const verbose); --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-al Content-Transfer-Encoding: quoted-printable $NetBSD: patch-al,v 1.5 2011/01/15 18:37:46 tron Exp $ Fix build with png-1.5. --- converter/other/pamrgbatopng.c.orig 2006-08-19 04:12:28.000000000 +0100 +++ converter/other/pamrgbatopng.c 2011-01-15 18:24:36.000000000 +0000 @@ -101,10 +101,8 @@ if (!infoP) pm_error("Could not allocate PNG info structure"); else { - infoP->width = pamP->width; - infoP->height = pamP->height; - infoP->bit_depth = 8; - infoP->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + png_set_IHDR(pngP, infoP, pamP->width, pamP->height, + 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0, 0); png_init_io(pngP, ofP); --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-af Content-Transfer-Encoding: quoted-printable $NetBSD: patch-af,v 1.15 2011/01/15 18:37:46 tron Exp $ Fix build with png-1.5. --- converter/other/pnmtopng.c.orig 2010-12-10 18:19:40.000000000 +0000 +++ converter/other/pnmtopng.c 2011-01-15 11:15:25.000000000 +0000 @@ -58,7 +58,8 @@ #include #include /* strcat() */ #include -#include /* includes zlib.h and setjmp.h */ +#include /* includes setjmp.h */ +#include #include "pm_c_util.h" #include "pnm.h" @@ -2079,6 +2080,7 @@ gray * const alpha_mask, colorhash_table const cht, coloralphahash_table const caht, + png_struct * const png_ptr, png_info * const info_ptr, xelval const png_maxval, unsigned int const depth) { @@ -2091,20 +2093,20 @@ xel p_png; xel const p = xelrow[col]; PPM_DEPTH(p_png, p, maxval, png_maxval); - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { if (depth == 16) *pp++ = PNM_GET1(p_png) >> 8; *pp++ = PNM_GET1(p_png) & 0xff; - } else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { + } else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { unsigned int paletteIndex; if (alpha) paletteIndex = lookupColorAlpha(caht, &p, &alpha_mask[col]); else paletteIndex = ppm_lookupcolor(cht, &p); *pp++ = paletteIndex; - } else if (info_ptr->color_type == PNG_COLOR_TYPE_RGB || - info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + } else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA) { if (depth == 16) *pp++ = PPM_GETR(p_png) >> 8; *pp++ = PPM_GETR(p_png) & 0xff; @@ -2117,7 +2119,7 @@ } else pm_error("INTERNAL ERROR: undefined color_type"); - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) { + if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) { int const png_alphaval = (int) alpha_mask[col] * (float) png_maxval / maxval + 0.5; if (depth == 16) @@ -2174,7 +2176,7 @@ makePngLine(line, xelrow, cols, maxval, alpha, alpha ? alpha_mask[row] : NULL, - cht, caht, pngxP->info_ptr, png_maxval, depth); + cht, caht, pngxP->png_ptr, pngxP->info_ptr, png_maxval, depth); png_write_row(png_ptr, line); } @@ -2186,12 +2188,12 @@ static void doGamaChunk(struct cmdlineInfo const cmdline, + png_struct * const png_ptr, png_info * const info_ptr) { if (cmdline.gammaSpec) { /* gAMA chunk */ - info_ptr->valid |= PNG_INFO_gAMA; - info_ptr->gamma = cmdline.gamma; + png_set_gAMA(png_ptr, info_ptr, cmdline.gamma); } } @@ -2199,20 +2201,15 @@ static void doChrmChunk(struct cmdlineInfo const cmdline, + png_struct * const png_ptr, png_info * const info_ptr) { if (cmdline.rgbSpec) { /* cHRM chunk */ - info_ptr->valid |= PNG_INFO_cHRM; - - info_ptr->x_white = cmdline.rgb.wx; - info_ptr->y_white = cmdline.rgb.wy; - info_ptr->x_red = cmdline.rgb.rx; - info_ptr->y_red = cmdline.rgb.ry; - info_ptr->x_green = cmdline.rgb.gx; - info_ptr->y_green = cmdline.rgb.gy; - info_ptr->x_blue = cmdline.rgb.bx; - info_ptr->y_blue = cmdline.rgb.by; + + png_set_cHRM (png_ptr, info_ptr, cmdline.rgb.wx, cmdline.rgb.wy, + cmdline.rgb.rx, cmdline.rgb.ry, cmdline.rgb.gx, + cmdline.rgb.gy, cmdline.rgb.bx, cmdline.rgb.by); } } @@ -2220,15 +2217,12 @@ static void doPhysChunk(struct cmdlineInfo const cmdline, + png_struct * const png_ptr, png_info * const info_ptr) { if (cmdline.sizeSpec) { /* pHYS chunk */ - info_ptr->valid |= PNG_INFO_pHYs; - - info_ptr->x_pixels_per_unit = cmdline.size.x; - info_ptr->y_pixels_per_unit = cmdline.size.y; - info_ptr->phys_unit_type = cmdline.size.unit; + png_set_pHYs(png_ptr, info_ptr, cmdline.size.x, cmdline.size.y, cmdline.size.unit); } } @@ -2237,13 +2231,14 @@ static void doTimeChunk(struct cmdlineInfo const cmdline, + png_struct * const png_ptr, png_info * const info_ptr) { if (cmdline.modtimeSpec) { /* tIME chunk */ - info_ptr->valid |= PNG_INFO_tIME; - - png_convert_from_time_t(&info_ptr->mod_time, cmdline.modtime); + png_timep ptime; + png_convert_from_time_t(ptime, cmdline.modtime); + png_set_tIME(png_ptr, info_ptr, ptime); } } @@ -2260,13 +2255,14 @@ static void -doSbitChunk(png_info * const pngInfoP, +doSbitChunk(png_struct * const pngP, + png_info * const pngInfoP, xelval const pngMaxval, xelval const maxval, bool const alpha, xelval const alphaMaxval) { - if (pngInfoP->color_type != PNG_COLOR_TYPE_PALETTE && + if (png_get_color_type(pngP, pngInfoP) != PNG_COLOR_TYPE_PALETTE && (pngMaxval > maxval || (alpha && pngMaxval > alphaMaxval))) { /* We're writing in a bit depth that doesn't match the maxval @@ -2275,26 +2271,28 @@ sBIT chunk. */ - pngInfoP->valid |= PNG_INFO_sBIT; - { int const sbitval = pm_maxvaltobits(MIN(maxval, pngMaxval)); + png_color_8 sbit; - if (pngInfoP->color_type & PNG_COLOR_MASK_COLOR) { - pngInfoP->sig_bit.red = sbitval; - pngInfoP->sig_bit.green = sbitval; - pngInfoP->sig_bit.blue = sbitval; + (void)memset(&sbit, 0, sizeof(sbit)); + if (png_get_color_type(pngP, pngInfoP) & PNG_COLOR_MASK_COLOR) { + sbit.red = sbitval; + sbit.green = sbitval; + sbit.blue = sbitval; } else - pngInfoP->sig_bit.gray = sbitval; + sbit.gray = sbitval; if (verbose) pm_message("Writing sBIT chunk with bits = %d", sbitval); - } - if (pngInfoP->color_type & PNG_COLOR_MASK_ALPHA) { - pngInfoP->sig_bit.alpha = - pm_maxvaltobits(MIN(alphaMaxval, pngMaxval)); - if (verbose) - pm_message(" alpha bits = %d", pngInfoP->sig_bit.alpha); + + if (png_get_color_type(pngP, pngInfoP) & PNG_COLOR_MASK_ALPHA) { + sbit.alpha = + pm_maxvaltobits(MIN(alphaMaxval, pngMaxval)); + if (verbose) + pm_message(" alpha bits = %d", sbit.alpha); + } + png_set_sBIT(pngP, pngInfoP, &sbit); } } } @@ -2391,6 +2382,8 @@ xelval maxmaxval; gray ** alpha_mask; + int color_type; + /* We initialize these guys to quiet compiler warnings: */ depth = 0; @@ -2576,43 +2569,42 @@ pm_error ("setjmp returns error condition (2)"); } - png_init_io (png_ptr, stdout); - info_ptr->width = cols; - info_ptr->height = rows; - info_ptr->bit_depth = depth; - if (colorMapped) - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; - else if (pnm_type == PPM_TYPE) - info_ptr->color_type = PNG_COLOR_TYPE_RGB; - else - info_ptr->color_type = PNG_COLOR_TYPE_GRAY; + color_type = PNG_COLOR_TYPE_PALETTE; + else if (pnm_type == PPM_TYPE) { + if (alpha) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + } else { + if (alpha) + color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + else + color_type = PNG_COLOR_TYPE_GRAY; + } - if (alpha && info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + png_set_IHDR(png_ptr, info_ptr, cols, rows, depth, color_type, 0, 0, 0); + png_init_io (png_ptr, stdout); - info_ptr->interlace_type = cmdline.interlace; + if (cmdline.interlace) + png_set_interlace_handling(png_ptr); - doGamaChunk(cmdline, info_ptr); + doGamaChunk(cmdline, png_ptr, info_ptr); - doChrmChunk(cmdline, info_ptr); + doChrmChunk(cmdline, png_ptr, info_ptr); - doPhysChunk(cmdline, info_ptr); + doPhysChunk(cmdline, png_ptr, info_ptr); - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { /* creating PNG palette (PLTE and tRNS chunks) */ createPngPalette(palette_pnm, palette_size, maxval, trans_pnm, trans_size, alpha_maxval, palette, trans); - info_ptr->valid |= PNG_INFO_PLTE; - info_ptr->palette = palette; - info_ptr->num_palette = palette_size; + png_set_PLTE(png_ptr, info_ptr, palette, palette_size); if (trans_size > 0) { - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->trans = trans; - info_ptr->num_trans = trans_size; /* omit opaque values */ + png_set_tRNS(png_ptr, info_ptr, trans, trans_size, NULL); } /* creating hIST chunk */ if (cmdline.hist) { @@ -2638,18 +2630,17 @@ ppm_freecolorhash(cht); - info_ptr->valid |= PNG_INFO_hIST; - info_ptr->hist = histogram; + png_set_hIST(png_ptr, info_ptr, histogram); if (verbose) pm_message("histogram created"); } } else { /* color_type != PNG_COLOR_TYPE_PALETTE */ - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_RGB) { + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB) { if (transparent > 0) { - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->trans_values = - xelToPngColor_16(transcolor, maxval, png_maxval); + png_color_16 trans_color = xelToPngColor_16(transcolor, maxval, png_maxval); + png_set_tRNS(png_ptr, info_ptr, NULL, 0, &trans_color); + } } else { /* This is PNG_COLOR_MASK_ALPHA. Transparency will be handled @@ -2657,43 +2648,49 @@ */ } if (verbose) { - if (info_ptr->valid && PNG_INFO_tRNS) + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_color_16p trans_color; + + png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_color); pm_message("Transparent color {gray, red, green, blue} = " "{%d, %d, %d, %d}", - info_ptr->trans_values.gray, - info_ptr->trans_values.red, - info_ptr->trans_values.green, - info_ptr->trans_values.blue); - else + trans_color->gray, + trans_color->red, + trans_color->green, + trans_color->blue); + } else pm_message("No transparent color"); } } /* bKGD chunk */ if (cmdline.background) { - info_ptr->valid |= PNG_INFO_bKGD; - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - info_ptr->background.index = background_index; + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { + png_color_16 background; + + (void)memset(&background, 0, sizeof(background)); + background.index = background_index; + png_set_bKGD(png_ptr, info_ptr, &background); } else { - info_ptr->background = - xelToPngColor_16(backcolor, maxval, png_maxval); + png_color_16 background = xelToPngColor_16(backcolor, maxval, png_maxval); + png_set_bKGD(png_ptr, info_ptr, &background); if (verbose) pm_message("Writing bKGD chunk with background color " " {gray, red, green, blue} = {%d, %d, %d, %d}", - info_ptr->background.gray, - info_ptr->background.red, - info_ptr->background.green, - info_ptr->background.blue ); + background.gray, + background.red, + background.green, + background.blue ); } } - doSbitChunk(info_ptr, png_maxval, maxval, alpha, alpha_maxval); + doSbitChunk(png_ptr, info_ptr, png_maxval, maxval, alpha, alpha_maxval); /* tEXT and zTXT chunks */ if (cmdline.text || cmdline.ztxt) - pnmpng_read_text(info_ptr, tfp, !!cmdline.ztxt, cmdline.verbose); + pnmpng_read_text(png_ptr, info_ptr, tfp, !!cmdline.ztxt, cmdline.verbose); - doTimeChunk(cmdline, info_ptr); + doTimeChunk(cmdline, png_ptr, info_ptr); if (cmdline.filterSet != 0) png_set_filter(png_ptr, 0, cmdline.filterSet); @@ -2703,6 +2700,7 @@ /* write the png-info struct */ png_write_info(png_ptr, info_ptr); +#if 0 if (cmdline.text || cmdline.ztxt) /* prevent from being written twice with png_write_end */ info_ptr->num_text = 0; @@ -2710,6 +2708,7 @@ if (cmdline.modtime) /* prevent from being written twice with png_write_end */ info_ptr->valid &= ~PNG_INFO_tIME; +#endif /* let libpng take care of, e.g., bit-depth conversions */ png_set_packing (png_ptr); --y0ulUmNC+osPPQO6--