From 1a6b1b3b5fe92754ae2b6d66121638bcbddbbe2d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 24 Oct 2020 16:30:49 +0000 Subject: Add -closeness git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3979 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- other/pamarith.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/other/pamarith.c b/other/pamarith.c index 9eaaf90e..858acf3f 100644 --- a/other/pamarith.c +++ b/other/pamarith.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "pm_c_util.h" #include "mallocvar.h" @@ -8,6 +9,8 @@ #include "shhopt.h" #include "pam.h" +static double const EPSILON = 1.0e-5; + enum function {FN_ADD, FN_SUBTRACT, FN_MULTIPLY, FN_DIVIDE, FN_DIFFERENCE, FN_MINIMUM, FN_MAXIMUM, FN_MEAN, FN_EQUAL, FN_COMPARE, FN_AND, FN_OR, FN_NAND, FN_NOR, FN_XOR, @@ -56,6 +59,7 @@ struct CmdlineInfo { enum function function; unsigned int operandCt; const char ** operandFileNames; + double closeness; }; @@ -78,7 +82,9 @@ parseCommandLine(int argc, const char ** const argv, differenceSpec, minimumSpec, maximumSpec, meanSpec, equalSpec, compareSpec, andSpec, orSpec, nandSpec, norSpec, xorSpec, - shiftleftSpec, shiftrightSpec; + shiftleftSpec, shiftrightSpec, closenessSpec; + + unsigned int closeness; MALLOCARRAY_NOFAIL(option_def, 100); @@ -100,6 +106,7 @@ parseCommandLine(int argc, const char ** const argv, OPTENT3(0, "xor", OPT_FLAG, NULL, &xorSpec, 0); OPTENT3(0, "shiftleft", OPT_FLAG, NULL, &shiftleftSpec, 0); OPTENT3(0, "shiftright", OPT_FLAG, NULL, &shiftrightSpec, 0); + OPTENT3(0, "closeness", OPT_UINT, &closeness, &closenessSpec, 0); opt.opt_table = option_def; opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ @@ -151,6 +158,18 @@ parseCommandLine(int argc, const char ** const argv, else pm_error("You must specify a function (e.g. '-add')"); + if (closenessSpec) { + if (cmdlineP->function != FN_EQUAL) + pm_error("-closeness is valid only with -equal"); + else { + if (closeness > 100) + pm_error("-closeness value %u is not a valid percentage", + closeness); + cmdlineP->closeness = (double)closeness/100; + } + } else + cmdlineP->closeness = EPSILON; + if (argc-1 < 2) pm_error("You must specify at least two arguments: the files which " "are the operands of the function. You specified %u", @@ -387,13 +406,14 @@ samplenMean(samplen const operands[], static samplen samplenEqual(samplen const operands[], - unsigned int const operandCt) { + unsigned int const operandCt, + double const closeness) { unsigned int i; bool allEqual; for (i = 1, allEqual = true; i < operandCt; ++i) { - if (operands[i] != operands[0]) + if (fabs(operands[i]- operands[0]) > closeness) allEqual = false; } @@ -405,7 +425,8 @@ samplenEqual(samplen const operands[], static samplen applyNormalizedFunction(enum function const function, samplen const operands[], - unsigned int const operandCt) { + unsigned int const operandCt, + double const closeness) { samplen result; @@ -437,7 +458,7 @@ applyNormalizedFunction(enum function const function, result = samplenMean(operands, operandCt); break; case FN_EQUAL: - result = samplenEqual(operands, operandCt); + result = samplenEqual(operands, operandCt, closeness); break; case FN_COMPARE: result = @@ -459,7 +480,8 @@ static void doNormalizedArith(struct pam * const inpam1P, struct pam * const inpam2P, struct pam * const outpamP, - enum function const function) { + enum function const function, + double const closeness) { /* Some of the logic in this subroutine is designed for future expansion into non-dyadic computations. But for now, all @@ -508,7 +530,8 @@ doNormalizedArith(struct pam * const inpam1P, operands[op] = tuplerown[op][col][plane[op]]; tuplerownOut[col][outplane] = - applyNormalizedFunction(function, operands, operandCt); + applyNormalizedFunction(function, operands, operandCt, + closeness); assert(tuplerownOut[col][outplane] >= 0.); assert(tuplerownOut[col][outplane] <= 1.); } @@ -919,7 +942,8 @@ main(int argc, const char *argv[]) { if (inpam1.maxval == inpam2.maxval && inpam2.maxval == outpam.maxval) doUnNormalizedArith(&inpam1, &inpam2, &outpam, cmdline.function); else - doNormalizedArith(&inpam1, &inpam2, &outpam, cmdline.function); + doNormalizedArith(&inpam1, &inpam2, &outpam, cmdline.function, + cmdline.closeness); break; case CATEGORY_BITSTRING: case CATEGORY_SHIFT: -- cgit 1.4.1