From 6d06b8e0c26536edaedf04ae56849667b85c1325 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 20 Jan 2019 19:22:55 +0000 Subject: Fix handling of floating point imprecision in unnormalizing samples git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3513 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- editor/pambrighten.c | 28 ++++++++++++++-------------- editor/pamcomp.c | 3 ++- editor/pnmhisteq.c | 2 +- editor/pnmnorm.c | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/editor/pambrighten.c b/editor/pambrighten.c index 462c5efe..51bd0d23 100644 --- a/editor/pambrighten.c +++ b/editor/pambrighten.c @@ -96,10 +96,10 @@ parseCommandLine(int argc, static void -changeColorPix(tuple const tupleval, - float const valchange, - float const satchange, - sample const maxval) { +changeColorPix(tuple const tupleval, + float const valchange, + float const satchange, + const struct pam * const pamP) { pixel oldRgb, newRgb; struct hsv oldHsv, newHsv; @@ -107,7 +107,7 @@ changeColorPix(tuple const tupleval, PPM_PUTR(oldRgb, tupleval[PAM_RED_PLANE]); PPM_PUTG(oldRgb, tupleval[PAM_GRN_PLANE]); PPM_PUTB(oldRgb, tupleval[PAM_BLU_PLANE]); - oldHsv = ppm_hsv_from_color(oldRgb, maxval); + oldHsv = ppm_hsv_from_color(oldRgb, pamP->maxval); newHsv.h = oldHsv.h; @@ -115,7 +115,7 @@ changeColorPix(tuple const tupleval, newHsv.v = MIN(1.0, MAX(0.0, oldHsv.v * valchange)); - newRgb = ppm_color_from_hsv(newHsv, maxval); + newRgb = ppm_color_from_hsv(newHsv, pamP->maxval); tupleval[PAM_RED_PLANE] = PPM_GETR(newRgb); tupleval[PAM_GRN_PLANE] = PPM_GETG(newRgb); @@ -125,14 +125,14 @@ changeColorPix(tuple const tupleval, static void -changeGrayPix(tuple const tupleval, - float const valchange, - sample const maxval) { +changeGrayPix(tuple const tupleval, + float const valchange, + struct pam * const pamP) { - double const oldGray = (double) tupleval[0] / maxval; - double const newGray = MIN(1.0, MAX(0.0, oldGray * valchange)); + samplen const oldGray = pnm_normalized_sample(pamP, tupleval[0]); + samplen const newGray = MIN(1.0, MAX(0.0, oldGray * valchange)); - tupleval[0] = ROUNDU(newGray * maxval); + tupleval[0] = pnm_unnormalized_sample(pamP, newGray); } @@ -211,12 +211,12 @@ pambrighten(struct CmdlineInfo const cmdline, case COLORTYPE_COLOR: changeColorPix(tuplerow[col], cmdline.valchange, cmdline.satchange, - inpam.maxval); + &inpam); break; case COLORTYPE_GRAY: changeGrayPix(tuplerow[col], cmdline.valchange, - inpam.maxval); + &inpam); break; case COLORTYPE_BW: /* Nothing to change. */ diff --git a/editor/pamcomp.c b/editor/pamcomp.c index 3e27731f..6e1e7f7d 100644 --- a/editor/pamcomp.c +++ b/editor/pamcomp.c @@ -532,7 +532,8 @@ composeComponents(sample const compA, float const mix = compALinear * distrib + compBLinearAdj * (1.0 - distrib) * composedFactor; - sample const sampleValue = ROUNDU(pm_gamma709(mix) * maxval); + sample const sampleValue = + pnm_unnormalize(pm_gamma709(mix), maxval); retval = MIN(maxval, MAX(0, sampleValue)); } } diff --git a/editor/pnmhisteq.c b/editor/pnmhisteq.c index 76fd6d2a..a339f73f 100644 --- a/editor/pnmhisteq.c +++ b/editor/pnmhisteq.c @@ -426,7 +426,7 @@ remapRgbValue(xel const thisXel, struct hsv const hsv = ppm_hsv_from_color(thisXel, maxval); xelval const oldValue = - MIN(maxval, ROUNDU(hsv.v * maxval)); + MIN(maxval, pnm_unnormalize(hsv.v, maxval)); xelval const newValue = lumamap[oldValue]; diff --git a/editor/pnmnorm.c b/editor/pnmnorm.c index 7762f049..2f9a6b20 100644 --- a/editor/pnmnorm.c +++ b/editor/pnmnorm.c @@ -714,7 +714,7 @@ computeQuadraticTransfer(xelval const bvalue, Set this mapping in newBrightness[]. -----------------------------------------------------------------------------*/ - xelval const middle = ROUNDU(middleNorm * maxval); + xelval const middle = pnm_unnormalize(middleNorm, maxval); /* Computing this function is just the task of finding a parabola that passes through 3 given points: @@ -924,7 +924,7 @@ reportTransferParm(bool const quadratic, if (quadratic) pm_message("remapping %u..%u..%u to %u..%u..%u", bvalue, midvalue, wvalue, - 0, ROUNDU(maxval*middle), maxval); + 0, pnm_unnormalize(middle, maxval), maxval); else pm_message("remapping %u..%u to %u..%u", bvalue, wvalue, 0, maxval); -- cgit 1.4.1