about summary refs log tree commit diff
path: root/analyzer
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-01-06 03:28:54 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-01-06 03:28:54 +0000
commit733798d7f10211ad1ebe60482ce5c0be92f170f4 (patch)
treef0dcc3edf448700a9b1e294cd53ce4fb1585cf1a /analyzer
parent4d797dc32c3142447fb51ce1fed91c36f78b11cf (diff)
downloadnetpbm-mirror-733798d7f10211ad1ebe60482ce5c0be92f170f4.tar.gz
netpbm-mirror-733798d7f10211ad1ebe60482ce5c0be92f170f4.tar.xz
netpbm-mirror-733798d7f10211ad1ebe60482ce5c0be92f170f4.zip
Add -targetX
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3110 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'analyzer')
-rw-r--r--analyzer/pnmpsnr.c135
1 files changed, 124 insertions, 11 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) {
 }
 
 
+