about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--analyzer/pnmpsnr.c135
-rw-r--r--doc/HISTORY2
-rw-r--r--test/jpeg-roundtrip.ok6
-rwxr-xr-xtest/jpeg-roundtrip.test23
-rw-r--r--test/pnmpsnr.ok3
-rwxr-xr-xtest/pnmpsnr.test3
-rw-r--r--test/tiffcmyk-roundtrip.ok10
-rwxr-xr-xtest/tiffcmyk-roundtrip.test33
8 files changed, 152 insertions, 63 deletions
diff --git a/analyzer/pnmpsnr.c b/analyzer/pnmpsnr.c
index 1ddefac2..2363e8c3 100644
--- a/analyzer/pnmpsnr.c
+++ b/analyzer/pnmpsnr.c
@@ -21,6 +21,33 @@
 
 
 
+struct TargetSet {
+    unsigned int targetSpec;
+    float        target;
+    unsigned int target1Spec;
+    float        target1;
+    unsigned int target2Spec;
+    float        target2;
+    unsigned int target3Spec;
+    float        target3;
+};
+
+
+
+static bool
+targetSet_compTargetSpec(struct TargetSet const targetSet) {
+/*----------------------------------------------------------------------------
+   The target set specifies individual color component targets
+   (some may be "don't care", though).
+-----------------------------------------------------------------------------*/
+    return
+        targetSet.target1Spec ||
+        targetSet.target2Spec ||
+        targetSet.target3Spec;
+}
+
+
+
 struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
@@ -31,11 +58,36 @@ struct CmdlineInfo {
     unsigned int machine;
     unsigned int maxSpec;
     float        max;
+    bool         targetMode;
+    struct TargetSet target;
 };
 
 
 
 static void
+interpretTargetSet(struct TargetSet const targetSet,
+                   bool *           const targetModeP) {
+
+    if (targetSet.targetSpec && targetSet.target <= 0.0)
+        pm_error("Nonpositive -target does not make sense");
+
+    if (targetSet.target1Spec && targetSet.target1 <= 0.0)
+        pm_error("Nonpositive -target1 does not make sense");
+
+    if (targetSet.target2Spec && targetSet.target2 <= 0.0)
+        pm_error("Nonpositive -target2 does not make sense");
+
+    if (targetSet.target3Spec && targetSet.target3 <= 0.0)
+        pm_error("Nonpositive -target3 does not make sense");
+
+    *targetModeP =
+        targetSet.targetSpec || targetSet.target1Spec ||
+        targetSet.target2Spec || targetSet.target3Spec;
+}
+
+
+
+static void
 parseCommandLine(int argc, const char ** argv,
                  struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
@@ -50,23 +102,31 @@ parseCommandLine(int argc, const char ** argv,
     unsigned int option_def_index;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
-    
+
     option_def_index = 0;   /* incremented by OPTENT3 */
     OPTENT3(0,   "rgb",      OPT_FLAG,  NULL,
             &cmdlineP->rgb,       0);
     OPTENT3(0,   "machine",  OPT_FLAG,  NULL,
             &cmdlineP->machine,   0);
-    OPTENT3(0,   "max",      OPT_FLOAT, &cmdlineP->max,  
+    OPTENT3(0,   "max",      OPT_FLOAT, &cmdlineP->max,
             &cmdlineP->maxSpec,   0);
+    OPTENT3(0,   "target",   OPT_FLOAT, &cmdlineP->target.target,
+            &cmdlineP->target.targetSpec,   0);
+    OPTENT3(0,   "target1",  OPT_FLOAT, &cmdlineP->target.target1,
+            &cmdlineP->target.target1Spec,   0);
+    OPTENT3(0,   "target2",  OPT_FLOAT, &cmdlineP->target.target2,
+            &cmdlineP->target.target2Spec,   0);
+    OPTENT3(0,   "target3",  OPT_FLOAT, &cmdlineP->target.target3,
+            &cmdlineP->target.target3Spec,   0);
 
     opt.opt_table     = option_def;
     opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */
     opt.allowNegNum   = FALSE; /* We have no parms that are negative numbers */
-    
+
     pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
 
-    if (argc-1 < 2) 
+    if (argc-1 < 2)
         pm_error("Takes two arguments:  names of the two files to compare");
     else {
         cmdlineP->inputFile1Name = argv[1];
@@ -78,6 +138,11 @@ parseCommandLine(int argc, const char ** argv,
     }
 
     free(option_def);
+
+    interpretTargetSet(cmdlineP->target, &cmdlineP->targetMode);
+
+    if (cmdlineP->targetMode && cmdlineP->maxSpec)
+        pm_error("-max is meaningless with -targetX");
 }
 
 
@@ -221,10 +286,10 @@ sqDiffYCbCr(tuple    const tuple1,
     struct SqDiff retval;
 
     double y1, y2, cb1, cb2, cr1, cr2;
-    
+
     pnm_YCbCrtuple(tuple1, &y1, &cb1, &cr1);
     pnm_YCbCrtuple(tuple2, &y2, &cb2, &cr2);
-    
+
     retval.sqDiff[Y_INDEX]  = square(y1  - y2);
     retval.sqDiff[CB_INDEX] = square(cb1 - cb2);
     retval.sqDiff[CR_INDEX] = square(cr1 - cr2);
@@ -316,12 +381,12 @@ sumSqDiffFromRaster(struct pam * const pam1P,
 
     tuplerow1 = pnm_allocpamrow(pam1P);
     tuplerow2 = pnm_allocpamrow(pam2P);
-    
+
     sumSqDiff = zeroSqDiff();
 
     for (row = 0; row < pam1P->height; ++row) {
         unsigned int col;
-        
+
         pnm_readpamrow(pam1P, tuplerow1);
         pnm_readpamrow(pam2P, tuplerow2);
 
@@ -385,7 +450,7 @@ psnrFromSumSqDiff(struct SqDiff const sumSqDiff,
        to the actual mean square difference, which is also the ratio of
        the maximum possible sum square difference to the actual sum square
        difference.
-   
+
        Note that in the important special case that the images are
        identical, the sum square differences are identically 0.0.
        No precision error; no rounding error.
@@ -418,6 +483,49 @@ psnrIsFinite(double const psnr) {
 
 
 static void
+reportTarget(struct Psnr      const psnr,
+             ColorSpace       const colorSpace,
+             struct TargetSet const target) {
+
+    bool hitsTarget;
+
+    if (colorSpace.componentCt == 1) {
+        if (!target.targetSpec)
+            pm_error("Image is monochrome and you specified "
+                     "-target1, -target2, or -target3 but not -target");
+
+        hitsTarget = psnr.psnr[0] >= target.target;
+    } else {
+        float compTarget[3];
+
+        unsigned int i;
+
+        assert(colorSpace.componentCt == 3);
+
+        if (targetSet_compTargetSpec(target)) {
+            compTarget[0] = target.target1Spec ? target.target1 : -1;
+            compTarget[1] = target.target2Spec ? target.target2 : -1;
+            compTarget[2] = target.target3Spec ? target.target3 : -1;
+        } else {
+            assert(target.targetSpec);
+            compTarget[0] = target.target;
+            compTarget[1] = target.target;
+            compTarget[2] = target.target;
+        }
+        for (i = 0, hitsTarget = true;
+             i < colorSpace.componentCt && hitsTarget;
+             ++i) {
+
+            if (psnr.psnr[i] < compTarget[i])
+                hitsTarget = false;
+        }
+    }
+    fprintf(stdout, "%s\n", hitsTarget ? "match" : "nomatch");
+}
+
+
+
+static void
 reportPsnrHuman(struct Psnr   const psnr,
                 ColorSpace    const colorSpace,
                 const char *  const fileName1,
@@ -470,7 +578,7 @@ main (int argc, const char **argv) {
     FILE * if2P;
     struct pam pam1, pam2;
     ColorSpace colorSpace;
-    
+
     struct CmdlineInfo cmdline;
 
     pm_proginit(&argc, argv);
@@ -508,12 +616,16 @@ main (int argc, const char **argv) {
             psnrFromSumSqDiff(
                 sumSqDiff, maxSumSqDiff, colorSpace.componentCt);
 
-        if (cmdline.machine)
+        if (cmdline.targetMode)
+            reportTarget(psnr, colorSpace, cmdline.target);
+        else if (cmdline.machine)
             reportPsnrMachine(psnr, colorSpace.componentCt,
                               cmdline.maxSpec, cmdline.max);
         else
             reportPsnrHuman(psnr, colorSpace,
                             cmdline.inputFile1Name, cmdline.inputFile2Name);
+
+
     }
     pm_close(if2P);
     pm_close(if1P);
@@ -522,3 +634,4 @@ main (int argc, const char **argv) {
 }
 
 
+
diff --git a/doc/HISTORY b/doc/HISTORY
index 16ae1d21..a6961e8f 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -6,6 +6,8 @@ CHANGE HISTORY
 
 not yet  BJH  Release 10.82.00
 
+              pnmpsnr: Add -targetX options.
+
               ppmpat: Fix bug - crash or junk output with -camo or -anticamo
               and no -color.  Introduced in Netpbm 10.78 (March 2017).
 
diff --git a/test/jpeg-roundtrip.ok b/test/jpeg-roundtrip.ok
index 9a93f216..5551f78e 100644
--- a/test/jpeg-roundtrip.ok
+++ b/test/jpeg-roundtrip.ok
@@ -1,3 +1,3 @@
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
+match
+match
+match
diff --git a/test/jpeg-roundtrip.test b/test/jpeg-roundtrip.test
index 23df6341..7cc0fc20 100755
--- a/test/jpeg-roundtrip.test
+++ b/test/jpeg-roundtrip.test
@@ -4,29 +4,16 @@
 
 # TODO: threshold has been determined without much thought.
 # Observed pnmpsnr output: 56.20 58.26 49.38
+# On another system:       54.73 49.41 44.52
 # A small margin has been added to the above numbers.
 
-# Should print 3 1 1 1 three times
+# Should print "match" three times
 
 pnmtojpeg testimg.ppm | jpegtopnm | \
-  pnmpsnr -machine - testimg.ppm |\
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>55.0 ? 1000.00 : $1,
-                $2>57.0 ? 1000.00 : $2,
-                $3>48.0 ? 1000.00 : $3) }'
-
+  pnmpsnr -target1=54 -target2=49 -target3=44 - testimg.ppm
 
 pnmtojpeg testimg.ppm -opt | jpegtopnm | \
-  pnmpsnr -machine - testimg.ppm |\
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>55.0 ? 1000.00 : $1,
-                $2>57.0 ? 1000.00 : $2,
-                $3>48.0 ? 1000.00 : $3) }'
-
+  pnmpsnr -target1=54 -target2=49 -target3=44 - testimg.ppm
 
 pnmtojpeg testimg.ppm -progressive | jpegtopnm | \
-  pnmpsnr -machine - testimg.ppm |\
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>55.0 ? 1000.00 : $1,
-                $2>57.0 ? 1000.00 : $2,
-                $3>48.0 ? 1000.00 : $3) }'
+  pnmpsnr -target1=54 -target2=49 -target3=44 - testimg.ppm
diff --git a/test/pnmpsnr.ok b/test/pnmpsnr.ok
index 4c7eccde..3469f836 100644
--- a/test/pnmpsnr.ok
+++ b/test/pnmpsnr.ok
@@ -1,4 +1,7 @@
 0.00
 inf
 1000.00
+match
 300.00 300.00 300.00
+match
+match
diff --git a/test/pnmpsnr.test b/test/pnmpsnr.test
index c7591983..f24c08aa 100755
--- a/test/pnmpsnr.test
+++ b/test/pnmpsnr.test
@@ -15,6 +15,9 @@ pbmmake -b 10 10 > ${b_pbm}
 pnmpsnr  ${w_pbm}  ${b_pbm} -machine
 pnmpsnr  ${w_pbm}  ${w_pbm} -machine
 pnmpsnr  ${w_pbm}  ${w_pbm} -machine -max=1000
+pnmpsnr  ${w_pbm}  ${w_pbm} -target=1000
 pnmpsnr  testimg.ppm  testimg.ppm -machine -max=300
+pnmpsnr  testimg.ppm  testimg.ppm -target=1000
+pnmpsnr  testimg.ppm  testimg.ppm -target1=1000 -target2=1000 -target3=1000
 
 rm ${b_pbm} ${w_pbm}
diff --git a/test/tiffcmyk-roundtrip.ok b/test/tiffcmyk-roundtrip.ok
index 5f4963cd..05c0b188 100644
--- a/test/tiffcmyk-roundtrip.ok
+++ b/test/tiffcmyk-roundtrip.ok
@@ -1,5 +1,5 @@
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
-  3 1000.00 1000.00 1000.00
+match
+match
+match
+match
+match
diff --git a/test/tiffcmyk-roundtrip.test b/test/tiffcmyk-roundtrip.test
index 99e02c48..133c81b7 100755
--- a/test/tiffcmyk-roundtrip.test
+++ b/test/tiffcmyk-roundtrip.test
@@ -15,47 +15,28 @@ output_tiff=${tmpdir}/output.tiff
 
 pnmtotiffcmyk testimg.ppm > ${output_tiff} && \
   tifftopnm -headerdump -byrow ${output_tiff} | \
-  pnmpsnr -machine - testimg.ppm | \
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>45.0 ? 1000.00 : $1,
-                $2>59.5 ? 1000.00 : $2,
-                $3>56.5 ? 1000.00 : $3) }'
+  pnmpsnr -target1=45.0 -target2=59.5 -target3=56.5 - testimg.ppm
 
 
 # Note that "-rowsperstrip=1" does not work
 pnmtotiffcmyk -rowsperstrip 1 -lsb2msb testimg.ppm > ${output_tiff} && \
   tifftopnm -respectfillorder -byrow  ${output_tiff} | \
-  pnmpsnr -machine - testimg.ppm | \
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>45.0 ? 1000.00 : $1,
-                $2>59.5 ? 1000.00 : $2,
-                $3>56.5 ? 1000.00 : $3) }'
+  pnmpsnr -target1=45.0 -target2=59.5 -target3=56.5 - testimg.ppm
 
 
 pnmtotiffcmyk -packbits testimg.ppm > ${output_tiff} && \
   tifftopnm -byrow ${output_tiff} | \
-  pnmpsnr -machine - testimg.ppm | \
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>45.0 ? 1000.00 : $1,
-                $2>59.5 ? 1000.00 : $2,
-                $3>56.5 ? 1000.00 : $3) }'
+  pnmpsnr -target1=45.0 -target2=59.5 -target3=56.5 - testimg.ppm
 
 
 pnmtotiffcmyk -lzw testimg.ppm > ${output_tiff} && \
   tifftopnm -byrow ${output_tiff} | \
-    pnmpsnr -machine - testimg.ppm | \
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>45.0 ? 1000.00 : $1,
-                $2>59.5 ? 1000.00 : $2,
-                $3>56.5 ? 1000.00 : $3) }'
+  pnmpsnr -target1=45.0 -target2=59.5 -target3=56.5 - testimg.ppm
 
 
 pnmtotiffcmyk -lzw -predictor 2 testimg.ppm > ${output_tiff} && \
   tifftopnm -respectfillorder -byrow ${output_tiff} | \
-  pnmpsnr -machine - testimg.ppm | \
-  awk '{printf("%3d %.2f %.2f %.2f\n", NF,
-                $1>45.0 ? 1000.00 : $1,
-                $2>59.5 ? 1000.00 : $2,
-                $3>56.5 ? 1000.00 : $3) }'
+  pnmpsnr -target1=45.0 -target2=59.5 -target=56.5 - testimg.ppm
 
-rm ${output_tiff}
\ No newline at end of file
+
+rm ${output_tiff}