about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-04-14 22:24:11 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-04-14 22:24:11 +0000
commit187713b8f0bd8769db95b8f9e1212af1b083f75f (patch)
treec1e295fe9af02e2c4f7e63827031a437a93b5de0
parent157b01d10a4c81206dae4fa05a623539e764717f (diff)
downloadnetpbm-mirror-187713b8f0bd8769db95b8f9e1212af1b083f75f.tar.gz
netpbm-mirror-187713b8f0bd8769db95b8f9e1212af1b083f75f.tar.xz
netpbm-mirror-187713b8f0bd8769db95b8f9e1212af1b083f75f.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1189 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--editor/pampaintspill.c143
1 files changed, 90 insertions, 53 deletions
diff --git a/editor/pampaintspill.c b/editor/pampaintspill.c
index 1ba1aedc..b5f96523 100644
--- a/editor/pampaintspill.c
+++ b/editor/pampaintspill.c
@@ -24,6 +24,19 @@
  * ----------------------------------------------------------------------
  */
 
+/*
+  This program contains code to work with Openmp, so that it can process
+  multiple columns at once, using multiple threads on multiple CPU cores,
+  and thus take less elapsed time to run.
+
+  But that code is dead in a normal Netpbm build, as it does not use the
+  required compiler options or link with the required library in any
+  conventional environment we know of.  One can exploit this code with a
+  modified build, e.g. with CADD and LADD make variables.
+
+  10.04.14
+*/
+
 #define _XOPEN_SOURCE 600  /* Make sure random(), srandom() are in <stdlib.h>*/
 #include <stdlib.h>
 #include <stdio.h>
@@ -218,7 +231,7 @@ locatePaintSources(struct pam *            const pamP,
   represent a non-background color.
   ----------------------------------------------------------------------*/
     struct paintSourceSet paintSources;
-    unsigned int row;
+    int row;  /* signed so it works with Openmp */
 
     paintSources.list  = NULL;
     paintSources.size  = 0;
@@ -346,20 +359,69 @@ reportProgress(unsigned int const rowsComplete,
 
 
 static void
+spillOnePixel(struct pam *          const pamP,
+              struct coords         const target,
+              struct paintSourceSet const paintSources,
+              distFunc_t *          const distFunc,
+              double                const distPower,
+              tuple                 const outTuple,
+              double *              const newColor) {
+
+    unsigned int plane;
+    unsigned int ps;
+    double       totalWeight;
+
+    for (plane = 0; plane < pamP->depth; ++plane)
+        newColor[plane] = 0.0;
+    totalWeight = 0.0;
+    for (ps = 0; ps < paintSources.size; ++ps) {
+        struct coords const source = paintSources.list[ps];
+        double const distSqr =
+            (*distFunc)(&target, &source,
+                        pamP->width, pamP->height);
+
+        if (distSqr > 0.0) {
+            /* We do special cases for some common cases with code
+               that is much faster than pow().
+            */
+            double const weight =
+                distPower == -2.0 ? 1.0 / distSqr :
+                distPower == -1.0 ? 1.0 / sqrt(distSqr):
+                pow(distSqr, distPower/2);
+
+            unsigned int plane;
+
+            for (plane = 0; plane < pamP->depth; ++plane)
+                newColor[plane] += weight * source.color[plane];
+
+            totalWeight += weight;
+        }
+    }
+    for (plane = 0; plane < pamP->depth; ++plane)
+        outTuple[plane] = (sample) (newColor[plane] / totalWeight);
+}
+
+
+
+static void
 produceOutputImage(struct pam *          const pamP,
-                   tuple **              const tuples,
+                   tuple **              const intuples,
                    tuple                 const bgColor,
                    struct paintSourceSet const paintSources,
                    distFunc_t *          const distFunc,
                    double                const distPower,
-                   bool                  const all) {
+                   bool                  const all,
+                   tuple ***             const outtuplesP) {
 /*--------------------------------------------------------------------
   Color each background pixel (or, if allPixels is 1, all pixels)
   using a fraction of each paint source as determined by its distance
   to the background pixel.
 ----------------------------------------------------------------------*/
-    unsigned int row;
+    int row;   /* signed so it works with Openmp */
     unsigned int rowsComplete;
+    tuple ** outtuples;
+
+    outtuples = pnm_allocpamarray(pamP);
 
     rowsComplete = 0;
     #pragma omp parallel for
@@ -371,49 +433,21 @@ produceOutputImage(struct pam *          const pamP,
 
         target.y = row;
         for (target.x = 0; target.x < pamP->width; ++target.x) {
-        tuple targetTuple = tuples[target.y][target.x];
-
-            if (all || tupleEqualColor(pamP, targetTuple, bgColor)) {
-                unsigned int plane;
-                unsigned int ps;
-                double       totalWeight;
-
-                for (plane = 0; plane < pamP->depth; ++plane)
-                    newColor[plane] = 0.0;
-                totalWeight = 0.0;
-                for (ps = 0; ps < paintSources.size; ++ps) {
-                    struct coords const source = paintSources.list[ps];
-                    double const distSqr =
-                        (*distFunc)(&target, &source,
-                                    pamP->width, pamP->height);
-
-                    if (distSqr > 0.0) {
-                        /* We do special cases for some common cases with code
-                           that is much faster than pow().
-                        */
-                        double const weight =
-                            distPower == -2.0 ? 1.0 / distSqr :
-                            distPower == -1.0 ? 1.0 / sqrt(distSqr):
-                            pow(distSqr, distPower/2);
-
-                        unsigned int plane;
-
-                        for (plane = 0; plane < pamP->depth; ++plane)
-                            newColor[plane] += weight * source.color[plane];
-
-                        totalWeight += weight;
-                    }
-                }
-                for (plane = 0; plane < pamP->depth; ++plane)
-                    targetTuple[plane] =
-                        (sample) (newColor[plane] / totalWeight);
-            }
+            tuple const targetTuple = intuples[target.y][target.x];
+            tuple const outputTuple = outtuples[target.y][target.x];
+
+            if (all || tupleEqualColor(pamP, targetTuple, bgColor))
+                spillOnePixel(pamP, target, paintSources, distFunc, distPower,
+                              outputTuple, newColor);
+            else
+                pnm_assigntuple(pamP,  outputTuple, targetTuple);
         }
         #pragma omp critical (rowTally)
         reportProgress(++rowsComplete, pamP->height);
 
         free(newColor);
     }
+    *outtuplesP = outtuples;
 }
 
 
@@ -426,9 +460,10 @@ main(int argc, const char *argv[]) {
     struct paintSourceSet paintSources;
         /* The set of paint-source indexes into 'tuples' */
     distFunc_t *       distFunc;         /* The distance function */
-    struct pam inpam;
+    struct pam inPam;
     struct pam outPam;
-    tuple ** tuples;
+    tuple ** inTuples;
+    tuple ** outTuples;
 
     pm_proginit(&argc, argv);
 
@@ -436,30 +471,32 @@ main(int argc, const char *argv[]) {
 
     ifP = pm_openr(cmdline.inputFilename);
 
-    tuples = pnm_readpam(ifP, &inpam, PAM_STRUCT_SIZE(allocation_depth));
+    inTuples = pnm_readpam(ifP, &inPam, PAM_STRUCT_SIZE(allocation_depth));
 
     pm_close(ifP);
 
     distFunc = cmdline.wrap ? euclideanDistanceTorusSqr : euclideanDistanceSqr;
 
     if (cmdline.bgcolor)
-        bgColor = pnm_parsecolor(cmdline.bgcolor, inpam.maxval) ;
+        bgColor = pnm_parsecolor(cmdline.bgcolor, inPam.maxval) ;
     else
-        bgColor = pnm_backgroundtuple(&inpam, tuples);
+        bgColor = pnm_backgroundtuple(&inPam, inTuples);
 
     pm_message("Treating %s as the background color",
-               pnm_colorname(&inpam, bgColor, PAM_COLORNAME_HEXOK));
+               pnm_colorname(&inPam, bgColor, PAM_COLORNAME_HEXOK));
 
-    locatePaintSources(&inpam, tuples, bgColor, cmdline.downsample,
+    locatePaintSources(&inPam, inTuples, bgColor, cmdline.downsample,
                        &paintSources);
 
-    produceOutputImage(&inpam, tuples, bgColor, paintSources, distFunc,
-                       cmdline.power, cmdline.all);
-
+    produceOutputImage(&inPam, inTuples, bgColor, paintSources, distFunc,
+                       cmdline.power, cmdline.all, &outTuples);
 
-    outPam = inpam;
+    outPam = inPam;
     outPam.file = stdout;
-    pnm_writepam(&outPam, tuples);
+    pnm_writepam(&outPam, outTuples);
+
+    pnm_freepamarray(outTuples, &inPam);
+    pnm_freepamarray(inTuples, &outPam);
 
     return 0;
 }