about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-10-23 18:01:23 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-10-23 18:01:23 +0000
commitc7a034c43022ebed0ae039d0686429c9673ff1f5 (patch)
tree441b58b0e19aedb1436869e4f419111628e7f3e4
parentecf32731038af480c51eb69523bb2ec0664afe2d (diff)
downloadnetpbm-mirror-c7a034c43022ebed0ae039d0686429c9673ff1f5.tar.gz
netpbm-mirror-c7a034c43022ebed0ae039d0686429c9673ff1f5.tar.xz
netpbm-mirror-c7a034c43022ebed0ae039d0686429c9673ff1f5.zip
Add -equal
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3977 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--doc/HISTORY6
-rw-r--r--other/pamarith.c79
2 files changed, 67 insertions, 18 deletions
diff --git a/doc/HISTORY b/doc/HISTORY
index 4d2c9abf..a8cf16b8 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -6,8 +6,10 @@ CHANGE HISTORY
 
 not yet  BJH  Release 10.93.00
 
-              Fix bug: fails with more than two operands for -mulitply,
-              -minimum, -maximum, -nand, and -nor.
+              pamarith: Add -equal.
+
+              pamarith: Fix bug: fails with more than two operands for
+              -mulitply, -minimum, -maximum, -nand, and -nor.
 
 20.09.26 BJH  Release 10.92.00
 
diff --git a/other/pamarith.c b/other/pamarith.c
index 180dbe23..9eaaf90e 100644
--- a/other/pamarith.c
+++ b/other/pamarith.c
@@ -9,7 +9,7 @@
 #include "pam.h"
 
 enum function {FN_ADD, FN_SUBTRACT, FN_MULTIPLY, FN_DIVIDE, FN_DIFFERENCE,
-               FN_MINIMUM, FN_MAXIMUM, FN_MEAN, FN_COMPARE,
+               FN_MINIMUM, FN_MAXIMUM, FN_MEAN, FN_EQUAL, FN_COMPARE,
                FN_AND, FN_OR, FN_NAND, FN_NOR, FN_XOR,
                FN_SHIFTLEFT, FN_SHIFTRIGHT
               };
@@ -27,6 +27,7 @@ isDyadic(enum function const function) {
     case FN_MINIMUM:
     case FN_MAXIMUM:
     case FN_MEAN:
+    case FN_EQUAL:
     case FN_AND:
     case FN_NAND:
     case FN_OR:
@@ -75,7 +76,7 @@ parseCommandLine(int argc, const char ** const argv,
 
     unsigned int addSpec, subtractSpec, multiplySpec, divideSpec,
         differenceSpec,
-        minimumSpec, maximumSpec, meanSpec, compareSpec,
+        minimumSpec, maximumSpec, meanSpec, equalSpec, compareSpec,
         andSpec, orSpec, nandSpec, norSpec, xorSpec,
         shiftleftSpec, shiftrightSpec;
 
@@ -90,6 +91,7 @@ parseCommandLine(int argc, const char ** const argv,
     OPTENT3(0, "minimum",     OPT_FLAG,   NULL, &minimumSpec,    0);
     OPTENT3(0, "maximum",     OPT_FLAG,   NULL, &maximumSpec,    0);
     OPTENT3(0, "mean",        OPT_FLAG,   NULL, &meanSpec,       0);
+    OPTENT3(0, "equal",       OPT_FLAG,   NULL, &equalSpec,      0);
     OPTENT3(0, "compare",     OPT_FLAG,   NULL, &compareSpec,    0);
     OPTENT3(0, "and",         OPT_FLAG,   NULL, &andSpec,        0);
     OPTENT3(0, "or",          OPT_FLAG,   NULL, &orSpec,         0);
@@ -107,7 +109,7 @@ parseCommandLine(int argc, const char ** const argv,
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (addSpec + subtractSpec + multiplySpec + divideSpec + differenceSpec +
-        minimumSpec + maximumSpec + meanSpec + compareSpec +
+        minimumSpec + maximumSpec + meanSpec + equalSpec + compareSpec +
         andSpec + orSpec + nandSpec + norSpec + xorSpec +
         shiftleftSpec + shiftrightSpec > 1)
         pm_error("You may specify only one function");
@@ -128,6 +130,8 @@ parseCommandLine(int argc, const char ** const argv,
         cmdlineP->function = FN_MAXIMUM;
     else if (meanSpec)
         cmdlineP->function = FN_MEAN;
+    else if (equalSpec)
+        cmdlineP->function = FN_EQUAL;
     else if (compareSpec)
         cmdlineP->function = FN_COMPARE;
     else if (andSpec)
@@ -192,6 +196,7 @@ functionCategory(enum function const function) {
     case FN_MINIMUM:
     case FN_MAXIMUM:
     case FN_MEAN:
+    case FN_EQUAL:
     case FN_COMPARE:
     case FN_MULTIPLY:
     case FN_DIVIDE:
@@ -262,6 +267,8 @@ computeOutputType(struct pam *  const outpamP,
     case CATEGORY_FRACTIONAL_ARITH:
         if (function == FN_COMPARE)
             outpamP->maxval = 2;
+        else if (function == FN_EQUAL)
+            outpamP->maxval = 1;
         else
             outpamP->maxval = MAX(inpam1.maxval, inpam2.maxval);
         break;
@@ -317,6 +324,21 @@ samplenSum(samplen      const operands[],
 
 
 static samplen
+samplenProduct(samplen      const operands[],
+               unsigned int const operandCt) {
+
+    unsigned int i;
+    double product;
+
+    for (i = 1, product = operands[0]; i < operandCt; ++i)
+        product *= operands[i];
+
+    return product;
+}
+
+
+
+static samplen
 samplenMin(samplen      const operands[],
            unsigned int const operandCt) {
 
@@ -364,16 +386,18 @@ samplenMean(samplen      const operands[],
 
 
 static samplen
-samplenProduct(samplen      const operands[],
-               unsigned int const operandCt) {
+samplenEqual(samplen      const operands[],
+             unsigned int const operandCt) {
 
     unsigned int i;
-    double product;
+    bool allEqual;
 
-    for (i = 1, product = operands[0]; i < operandCt; ++i)
-        product *= operands[i];
+    for (i = 1, allEqual = true; i < operandCt; ++i) {
+        if (operands[i] != operands[0])
+            allEqual = false;
+    }
 
-    return product;
+    return allEqual ? 1.0 : 0.0;
 }
 
 
@@ -412,6 +436,9 @@ applyNormalizedFunction(enum function const function,
     case FN_MEAN:
         result = samplenMean(operands, operandCt);
         break;
+    case FN_EQUAL:
+        result = samplenEqual(operands, operandCt);
+        break;
     case FN_COMPARE:
         result =
             operands[0] > operands[1] ?
@@ -518,6 +545,22 @@ sampleSum(sample       const operands[],
 
 
 static sample
+sampleProduct(sample       const operands[],
+              unsigned int const operandCt,
+              sample       const maxval) {
+
+    unsigned int i;
+    double product;
+
+    for (i = 0, product = 1.0; i < operandCt; ++i) {
+        product *= ((double)operands[i]/maxval);
+    }
+    return (sample)(product * maxval + 0.5);
+}
+
+
+
+static sample
 sampleMin(sample       const operands[],
           unsigned int const operandCt) {
 
@@ -567,17 +610,18 @@ sampleMean(sample       const operands[],
 
 
 static sample
-sampleProduct(sample       const operands[],
-              unsigned int const operandCt,
-              sample       const maxval) {
+sampleEqual(sample       const operands[],
+            unsigned int const operandCt,
+            sample       const maxval) {
 
     unsigned int i;
-    double product;
+    bool allEqual;
 
-    for (i = 0, product = 1.0; i < operandCt; ++i) {
-        product *= ((double)operands[i]/maxval);
+    for (i = 1, allEqual = true; i < operandCt; ++i) {
+        if (operands[i] != operands[0])
+            allEqual = false;
     }
-    return (sample)(product * maxval + 0.5);
+    return allEqual ? maxval : 0;
 }
 
 
@@ -700,6 +744,9 @@ applyUnNormalizedFunction(enum function const function,
     case FN_MEAN:
         result = sampleMean(operands, operandCt);
         break;
+    case FN_EQUAL:
+        result = sampleEqual(operands, operandCt, maxval);
+        break;
     case FN_COMPARE:
         result = operands[0] > operands[1] ?
             2 : operands[0] < operands[1] ? 0 : 1;