From 6c8b9ea2f03aa6cc250dd80a0d6232c8c4449cb7 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 6 Sep 2023 23:20:19 +0000 Subject: Release 11.03.05 git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@4636 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/other/pamtosvg/fit.c | 42 +++++++++++++++++++++++++++++--------- doc/HISTORY | 13 ++++++++++++ editor/pamaddnoise.c | 41 ++++++++----------------------------- generator/ppmrough.c | 46 +++++++++++++++++++++++++----------------- version.mk | 2 +- 5 files changed, 83 insertions(+), 61 deletions(-) diff --git a/converter/other/pamtosvg/fit.c b/converter/other/pamtosvg/fit.c index 179b3bdf..06e708c2 100644 --- a/converter/other/pamtosvg/fit.c +++ b/converter/other/pamtosvg/fit.c @@ -1379,14 +1379,26 @@ findHalfTangentBeg(curve * const curveP, unsigned int const thisIndex = p + 1; float_coord const thisPoint = CURVE_POINT(curveP, thisIndex); - /* Perhaps we should weight the tangent from `thisPoint' by some - factor dependent on the distance from the tangent point. - */ - sum = Vadd(sum, Pdirection(thisPoint, tangentPoint)); - ++n; + if (epsilon_equal(thisPoint.x, tangentPoint.x) && + epsilon_equal(thisPoint.y, tangentPoint.y) && + epsilon_equal(thisPoint.z, tangentPoint.z)) { + /* It's the same point; can't compute a slope */ + } else { + /* Perhaps we should weight the tangent from `thisPoint' by some + factor dependent on the distance from the tangent point. + */ + sum = Vadd(sum, Pdirection(thisPoint, tangentPoint)); + ++n; + } } - mean = Vmult_scalar(sum, 1.0 / n); + if (n >= 1) + mean = Vmult_scalar(sum, 1.0 / n); + else { + mean.dx = 1.0; + mean.dy = 0.0; + mean.dz = 0.0; + } return mean; } @@ -1418,11 +1430,23 @@ findHalfTangentEnd(curve * const curveP, unsigned int const thisIndex = CURVE_LENGTH(curveP) - 1 - p; float_coord const thisPoint = CURVE_POINT(curveP, thisIndex); - sum = Vadd(sum, Pdirection(tangentPoint, thisPoint)); - ++n; + if (epsilon_equal(thisPoint.x, tangentPoint.x) && + epsilon_equal(thisPoint.y, tangentPoint.y) && + epsilon_equal(thisPoint.z, tangentPoint.z)) { + /* It's the same point; can't compute a slope */ + } else { + sum = Vadd(sum, Pdirection(tangentPoint, thisPoint)); + ++n; + } } - mean = Vmult_scalar(sum, 1.0 / n); + if (n >= 1) + mean = Vmult_scalar(sum, 1.0 / n); + else { + mean.dx = 1.0; + mean.dy = 0.0; + mean.dz = 0.0; + } return mean; } diff --git a/doc/HISTORY b/doc/HISTORY index be97732d..dc7f78c4 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,6 +4,19 @@ Netpbm. CHANGE HISTORY -------------- +23.09.06 BJH Release 11.03.05 + + pamtosvg: fix hang. + + pamaddnoise: fix very incorrect noise added for all types. + Introduced in Netpbm 10.94 (March 2021). + + ppmrough: fix buffer overrun. Always broken (Ppmrough was new + in Netpbm 10.9 (September 2002). + + ppmrough: fix excessive roughness. Introduced in Netpbm 10.94 + (March 2021). + 23.08.20 BJH Release 11.03.04 pgmtexture: Fix buffer overflow with maxval > 255. Always diff --git a/editor/pamaddnoise.c b/editor/pamaddnoise.c index 9ca80394..e585700b 100644 --- a/editor/pamaddnoise.c +++ b/editor/pamaddnoise.c @@ -43,14 +43,6 @@ static double const SALT_RATIO = 0.5; -static double -rand1(struct pm_randSt * const randStP) { - - return (double)pm_rand(randStP)/RAND_MAX; -} - - - enum NoiseType { NOISETYPE_GAUSSIAN, NOISETYPE_IMPULSE, /* aka salt and pepper noise */ @@ -226,19 +218,13 @@ addGaussianNoise(sample const maxval, Based on Kasturi/Algorithms of the ACM -----------------------------------------------------------------------------*/ - double x1, x2, xn, yn; + double grnd1, grnd2; /* Gaussian random numbers. mean=0 sigma=1 */ double rawNewSample; - x1 = rand1(randStP); - - if (x1 == 0.0) - x1 = 1.0; - x2 = rand1(randStP); - xn = sqrt(-2.0 * log(x1)) * cos(2.0 * M_PI * x2); - yn = sqrt(-2.0 * log(x1)) * sin(2.0 * M_PI * x2); + pm_gaussrand2(randStP, &grnd1, &grnd2); rawNewSample = - origSample + (sqrt((double) origSample) * sigma1 * xn) + (sigma2 * yn); + origSample + (sqrt((double) origSample) * sigma1 * grnd1) + (sigma2 * grnd2); *newSampleP = MAX(MIN((int)rawNewSample, maxval), 0); } @@ -259,7 +245,7 @@ addImpulseNoise(sample const maxval, double const pepperRatio = 1.0 - saltRatio; double const loTolerance = tolerance * pepperRatio; double const hiTolerance = 1.0 - tolerance * saltRatio; - double const sap = rand1(randStP); + double const sap = pm_drand(randStP); *newSampleP = sap < loTolerance ? 0 : @@ -281,7 +267,7 @@ addLaplacianNoise(sample const maxval, From Pitas' book. -----------------------------------------------------------------------------*/ - double const u = rand1(randStP); + double const u = pm_drand(randStP); double rawNewSample; @@ -314,21 +300,10 @@ addMultiplicativeGaussianNoise(sample const maxval, From Pitas' book. -----------------------------------------------------------------------------*/ - double rayleigh, gauss; + double rawNewSample; - { - double const uniform = rand1(randStP); - if (uniform <= EPSILON) - rayleigh = infinity; - else - rayleigh = sqrt(-2.0 * log( uniform)); - } - { - double const uniform = rand1(randStP); - gauss = rayleigh * cos(2.0 * M_PI * uniform); - } - rawNewSample = origSample + (origSample * mgsigma * gauss); + rawNewSample = origSample + (origSample * mgsigma * pm_gaussrand(randStP)); *newSampleP = MIN(MAX((int)rawNewSample, 0), maxval); } @@ -384,7 +359,7 @@ addPoissonNoise(struct pam * const pamP, double const lambda = origSampleIntensity * lambdaOfMaxval; - double const u = rand1(randStP); + double const u = pm_drand(randStP); /* We now apply the inverse CDF (cumulative distribution function) of the Poisson distribution to uniform random variable 'u' to get a Poisson diff --git a/generator/ppmrough.c b/generator/ppmrough.c index a4a1f14d..c43b1fa5 100644 --- a/generator/ppmrough.c +++ b/generator/ppmrough.c @@ -96,6 +96,14 @@ parseCommandLine(int argc, const char ** argv, cmdlineP->fg = NULL; if (!varSpec) cmdlineP->var = 10; + if (cmdlineP->topSpec && cmdlineP->top > cmdlineP->height) + pm_error("-top value too large. Max is %u", cmdlineP->height); + if (cmdlineP->bottomSpec && cmdlineP->bottom > cmdlineP->height) + pm_error("-bottom value too large. Max is %u", cmdlineP->height); + if (cmdlineP->leftSpec && cmdlineP->left > cmdlineP->width) + pm_error("-left value too large. Max is %u", cmdlineP->width); + if (cmdlineP->rightSpec && cmdlineP->right > cmdlineP->width) + pm_error("-right value too large. Max is %u", cmdlineP->width); if (argc-1 != 0) pm_error("There are no arguments. You specified %d.", argc-1); @@ -159,6 +167,7 @@ procLeft(pixel ** const pixels, int const r2, int const c1, int const c2, + unsigned int const width, unsigned int const var, pixel const bgcolor, struct pm_randSt * const randStP) { @@ -166,15 +175,15 @@ procLeft(pixel ** const pixels, if (r1 + 1 != r2) { int const rm = (r1 + r2) >> 1; int const cm = ((c1 + c2) >> 1) + - (int)floor(((float)pm_rand(randStP) / RAND_MAX - 0.5) * var + 0.5); + (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5); - int c; + unsigned int c; - for (c = 0; c < cm; c++) + for (c = 0; c < MIN(width, MAX(0, cm)); c++) pixels[rm][c] = bgcolor; - procLeft(pixels, r1, rm, c1, cm, var, bgcolor, randStP); - procLeft(pixels, rm, r2, cm, c2, var, bgcolor, randStP); + procLeft(pixels, r1, rm, c1, cm, width, var, bgcolor, randStP); + procLeft(pixels, rm, r2, cm, c2, width, var, bgcolor, randStP); } } @@ -194,11 +203,11 @@ procRight(pixel ** const pixels, if (r1 + 1 != r2) { int const rm = (r1 + r2) >> 1; int const cm = ((c1 + c2) >> 1) + - (int)floor(((float)pm_rand(randStP) / RAND_MAX - 0.5) * var + 0.5); + (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5); - int c; + unsigned int c; - for (c = cm; c < width; c++) + for (c = MAX(0, cm); c < width; c++) pixels[rm][c] = bgcolor; procRight(pixels, r1, rm, c1, cm, width, var, bgcolor, randStP); @@ -214,6 +223,7 @@ procTop(pixel ** const pixels, int const c2, int const r1, int const r2, + unsigned int const height, unsigned int const var, pixel const bgcolor, struct pm_randSt * const randStP) { @@ -221,15 +231,15 @@ procTop(pixel ** const pixels, if (c1 + 1 != c2) { int const cm = (c1 + c2) >> 1; int const rm = ((r1 + r2) >> 1) + - (int)floor(((float)pm_rand(randStP) / RAND_MAX - 0.5) * var + 0.5); + (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5); - int r; + unsigned int r; - for (r = 0; r < rm; r++) + for (r = 0; r < MIN(height, MAX(0, rm)); r++) pixels[r][cm] = bgcolor; - procTop(pixels, c1, cm, r1, rm, var, bgcolor, randStP); - procTop(pixels, cm, c2, rm, r2, var, bgcolor, randStP); + procTop(pixels, c1, cm, r1, rm, height, var, bgcolor, randStP); + procTop(pixels, cm, c2, rm, r2, height, var, bgcolor, randStP); } } @@ -249,11 +259,11 @@ procBottom(pixel ** const pixels, if (c1 + 1 != c2) { int const cm = (c1 + c2) >> 1; int const rm = ((r1 + r2) >> 1) + - (int)floor(((float)pm_rand(randStP) / RAND_MAX - 0.5) * var + 0.5); + (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5); - int r; + unsigned int r; - for (r = rm; r < height; ++r) + for (r = MAX(0, rm); r < height; ++r) pixels[r][cm] = bgcolor; procBottom(pixels, c1, cm, r1, rm, height, var, bgcolor, randStP); @@ -286,7 +296,7 @@ makeRaggedLeftBorder(pixel ** const pixels, for (col = 0; col < leftC2; ++col) pixels[leftR2][col] = bgcolor; - procLeft(pixels, leftR1, leftR2, leftC1, leftC2, var, + procLeft(pixels, leftR1, leftR2, leftC1, leftC2, cols, var, bgcolor, randStP); } } @@ -347,7 +357,7 @@ makeRaggedTopBorder(pixel ** const pixels, for (row = 0; row < topR2; ++row) pixels[row][topC2] = bgcolor; - procTop(pixels, topC1, topC2, topR1, topR2, var, bgcolor, randStP); + procTop(pixels, topC1, topC2, topR1, topR2, rows, var, bgcolor, randStP); } } diff --git a/version.mk b/version.mk index c1f267cc..0f13782a 100644 --- a/version.mk +++ b/version.mk @@ -1,3 +1,3 @@ NETPBM_MAJOR_RELEASE = 11 NETPBM_MINOR_RELEASE = 3 -NETPBM_POINT_RELEASE = 4 +NETPBM_POINT_RELEASE = 5 -- cgit 1.4.1