(oe) diffed from the changes in the netpbm-10.35.48.tar.bz2 tarball taken from netpbm-10.35.48-1.fc8.src.rpm diff -Naurp netpbm-10.35.46/converter/other/pngtopnm.c netpbm-10.35.46.oden/converter/other/pngtopnm.c --- netpbm-10.35.46/converter/other/pngtopnm.c 2009-10-09 06:03:50.000000000 -0400 +++ netpbm-10.35.46.oden/converter/other/pngtopnm.c 2009-10-09 06:03:22.000000000 -0400 @@ -35,6 +35,7 @@ #endif /* 2 for warnings (1 == error) */ #include <math.h> +#include <float.h> #include <png.h> /* includes zlib.h and setjmp.h */ #define VERSION "2.37.4 (5 December 1999) +netpbm" @@ -200,6 +201,14 @@ _get_png_val (png_byte ** const pp, +static bool +isGrayscale(pngcolor const color) { + + return color.r == color.g && color.r == color.b; +} + + + static void setXel(xel * const xelP, pngcolor const foreground, @@ -515,30 +524,32 @@ setupGammaCorrection(png_struct * const if (displaygamma == -1.0) *totalgammaP = -1.0; else { - if (info_ptr->valid & PNG_INFO_gAMA) { - if (displaygamma != info_ptr->gamma) { - png_set_gamma(png_ptr, displaygamma, info_ptr->gamma); - *totalgammaP = - (double) info_ptr->gamma * (double) displaygamma; - /* in case of gamma-corrections, sBIT's as in the - PNG-file are not valid anymore - */ - info_ptr->valid &= ~PNG_INFO_sBIT; - if (verbose) - pm_message("image gamma is %4.2f, " - "converted for display gamma of %4.2f", - info_ptr->gamma, displaygamma); - } + float imageGamma; + if (info_ptr->valid & PNG_INFO_gAMA) + imageGamma = info_ptr->gamma; + else { + if (verbose) + pm_message("PNG doesn't specify image gamma. Assuming 1.0"); + imageGamma = 1.0; + } + + if (fabs(displaygamma * imageGamma - 1.0) < .01) { + *totalgammaP = -1.0; + if (verbose) + pm_message("image gamma %4.2f matches " + "display gamma %4.2f. No conversion.", + imageGamma, displaygamma); } else { - if (displaygamma != info_ptr->gamma) { - png_set_gamma (png_ptr, displaygamma, 1.0); - *totalgammaP = (double) displaygamma; - info_ptr->valid &= ~PNG_INFO_sBIT; - if (verbose) - pm_message("image gamma assumed 1.0, " - "converted for display gamma of %4.2f", - displaygamma); - } + png_set_gamma(png_ptr, displaygamma, imageGamma); + *totalgammaP = imageGamma * displaygamma; + /* in case of gamma-corrections, sBIT's as in the + PNG-file are not valid anymore + */ + info_ptr->valid &= ~PNG_INFO_sBIT; + if (verbose) + pm_message("image gamma is %4.2f, " + "converted for display gamma of %4.2f", + imageGamma, displaygamma); } } } @@ -745,10 +756,12 @@ imageHasColor(png_info * const info_ptr) static void determineOutputType(png_info * const info_ptr, enum alpha_handling const alphaHandling, + pngcolor const bgColor, xelval const maxval, int * const pnmTypeP) { - if (alphaHandling != ALPHA_ONLY && imageHasColor(info_ptr)) + if (alphaHandling != ALPHA_ONLY && + (imageHasColor(info_ptr) || !isGrayscale(bgColor))) *pnmTypeP = PPM_TYPE; else { if (maxval > 1) @@ -778,19 +791,11 @@ getBackgroundColor(png_info * con which is a bit arbitrary. */ pixel const backcolor = ppm_parsecolor(requestedColor, maxval); - switch (info_ptr->color_type) { - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: - bgColorP->r = bgColorP->g = bgColorP->b = PNM_GET1(backcolor); - break; - case PNG_COLOR_TYPE_PALETTE: - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - bgColorP->r = PPM_GETR(backcolor); - bgColorP->g = PPM_GETG(backcolor); - bgColorP->b = PPM_GETB(backcolor); - break; - } + + bgColorP->r = PPM_GETR(backcolor); + bgColorP->g = PPM_GETG(backcolor); + bgColorP->b = PPM_GETB(backcolor); + } else if (info_ptr->valid & PNG_INFO_bKGD) { /* didn't manage to get libpng to work (bugs?) concerning background processing, therefore we do our own. @@ -1054,7 +1059,7 @@ convertpng(FILE * const ifp, } } - determineOutputType(info_ptr, cmdline.alpha, maxval, &pnm_type); + determineOutputType(info_ptr, cmdline.alpha, bgColor, maxval, &pnm_type); writePnm(stdout, maxval, pnm_type, info_ptr, png_image, bgColor, cmdline.alpha, totalgamma); diff -Naurp netpbm-10.35.46/editor/pamperspective.c netpbm-10.35.46.oden/editor/pamperspective.c --- netpbm-10.35.46/editor/pamperspective.c 2008-06-24 02:58:59.000000000 -0400 +++ netpbm-10.35.46.oden/editor/pamperspective.c 2009-10-09 06:03:22.000000000 -0400 @@ -1083,46 +1083,82 @@ static int clean_y (int const y, const return MIN(MAX(0, y), outpam->height-1); } -static void init_buffer (buffer *const b, const world_data *const world, - const option *const options, - const struct pam *const inpam, - const struct pam *const outpam) -{ - int yul, yur, yll, ylr, y_min; - int i, num_rows; +static unsigned int +distance(unsigned int const a, + unsigned int const b) { - yul = outpixel_to_iny (0,0,world); - yur = outpixel_to_iny (outpam->width-1,0,world); - yll = outpixel_to_iny (0,outpam->height-1,world); - ylr = outpixel_to_iny (outpam->width-1,outpam->height-1,world); - - y_min = MIN (MIN (yul,yur), MIN (yll,ylr)); - num_rows = MAX (MAX (diff (yul, yur), - diff (yll, ylr)), - MAX (diff (clean_y(yul,outpam), clean_y(y_min,outpam)), - diff (clean_y(yur,outpam), clean_y(y_min,outpam)))) - + 2; - switch (options->enums[3]) { /* --interpolation */ - case interp_nearest: - break; - case interp_linear: - num_rows += 1; - break; - }; - if (num_rows > inpam->height) - num_rows = inpam->height; + return a > b ? a - b : b - a; +} - b->num_rows = num_rows; - MALLOCARRAY_SAFE (b->rows, num_rows); - for (i=0; i<num_rows; i++) { - b->rows[i] = pnm_allocpamrow (inpam); - pnm_readpamrow (inpam, b->rows[i]); - }; - b->last_physical = num_rows-1; - b->last_logical = num_rows-1; - b->inpam = inpam; + + +static int +boundedRow(int const unboundedRow, + const struct pam * const outpamP) { + + return MIN(MAX(0, unboundedRow), outpamP->height-1); +} + + + +static unsigned int +windowHeight(const world_data * const worldP, + const struct pam * const inpamP, + const struct pam * const outpamP, + const option * const optionsP) { + + unsigned int outRow; + unsigned int maxRowWindowHeight; + + maxRowWindowHeight = 1; /* initial value */ + + for (outRow = 0; outRow < outpamP->height; ++outRow) { + unsigned int const leftCol = 0; + unsigned int const rghtCol = outpamP->width - 1; + unsigned int const leftInRow = + boundedRow(outpixel_to_iny(leftCol, outRow, worldP), outpamP); + unsigned int const rghtInRow = + boundedRow(outpixel_to_iny(rghtCol, outRow, worldP), outpamP); + + unsigned int const rowWindowHeight = distance(leftInRow, rghtInRow); + + maxRowWindowHeight = MAX(maxRowWindowHeight, rowWindowHeight); + } + + /* We add 2 for rounding */ + + return maxRowWindowHeight + 2; } + + +static void +init_buffer(buffer * const bufferP, + const world_data * const worldP, + const option * const optionsP, + const struct pam * const inpamP, + const struct pam * const outpamP) { + + unsigned int const num_rows = + windowHeight(worldP, inpamP, outpamP, optionsP); + + MALLOCARRAY_SAFE(bufferP->rows, num_rows); + bufferP->num_rows = num_rows; + { + unsigned int row; + for (row = 0; row < num_rows; ++row) { + bufferP->rows[row] = pnm_allocpamrow(inpamP); + pnm_readpamrow(inpamP, bufferP->rows[row]); + } + } + bufferP->last_logical = num_rows-1; + bufferP->last_physical = num_rows-1; + bufferP->inpam = inpamP; +} + + + + static tuple* read_buffer (buffer *const b, int const logical_y) { int y;