about summary refs log tree commit diff
path: root/editor/pnmsmooth.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-12-19 21:10:56 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-12-19 21:10:56 +0000
commit35e1414cfbbf3567c69221432e6a71a07452431a (patch)
treee87693b9cef505276055503732f737d1d2e86222 /editor/pnmsmooth.c
parente0d2b9230213d0535c92502d3df97a91314e99b6 (diff)
downloadnetpbm-mirror-35e1414cfbbf3567c69221432e6a71a07452431a.tar.gz
netpbm-mirror-35e1414cfbbf3567c69221432e6a71a07452431a.tar.xz
netpbm-mirror-35e1414cfbbf3567c69221432e6a71a07452431a.zip
Use new Pnmconvol -matrix option instead of temporary PGM file for convolution kernel
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1067 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor/pnmsmooth.c')
-rw-r--r--editor/pnmsmooth.c113
1 files changed, 62 insertions, 51 deletions
diff --git a/editor/pnmsmooth.c b/editor/pnmsmooth.c
index 33a38982..14116ddf 100644
--- a/editor/pnmsmooth.c
+++ b/editor/pnmsmooth.c
@@ -21,6 +21,7 @@
 
 
 #include <unistd.h>
+#include <assert.h>
 #include <string.h>
 #include <errno.h>
 
@@ -39,7 +40,7 @@ struct cmdlineInfo {
     const char * inputFilespec;  /* Filespec of input file */
     unsigned int width;
     unsigned int height;
-    const char * dump;
+    unsigned int dump;
 };
 
 
@@ -64,13 +65,13 @@ parseCommandLine (int argc, const char ** argv,
 
     unsigned int option_def_index;
 
-    unsigned int widthSpec, heightSpec, dumpSpec, sizeSpec;
+    unsigned int widthSpec, heightSpec, sizeSpec;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
     
     option_def_index = 0;   /* incremented by OPTENT3 */
-    OPTENT3(0,   "dump",          OPT_STRING,   
-            &cmdlineP->dump,            &dumpSpec, 0);
+    OPTENT3(0,   "dump",          OPT_FLAG,   
+            NULL,                       &cmdlineP->dump, 0);
     OPTENT3(0,   "width",         OPT_UINT,
             &cmdlineP->width,           &widthSpec, 0);
     OPTENT3(0,   "height",        OPT_UINT,
@@ -91,9 +92,6 @@ parseCommandLine (int argc, const char ** argv,
     if (!heightSpec)
         cmdlineP->height = 3;
 
-    if (!dumpSpec)
-        cmdlineP->dump = NULL;
-
     if (sizeSpec) {
         /* -size is strictly for backward compatibility.  This program
            used to use a different command line processor and had
@@ -143,36 +141,54 @@ parseCommandLine (int argc, const char ** argv,
 
 
 
-static void
-writeConvolutionImage(FILE *       const cofp,
-                      unsigned int const cols,
-                      unsigned int const rows,
-                      int          const format) {
-
-    xelval const convmaxval = rows * cols * 2;
-        /* normalizing factor for our convolution matrix */
-    xelval const g = rows * cols + 1;
-        /* weight of all pixels in our convolution matrix */
-
-    int row;
-    xel * outputrow;
-
-    if (convmaxval > PNM_OVERALLMAXVAL)
-        pm_error("The convolution matrix is too large.  "
-                 "Width x Height x 2 "
-                 "must not exceed %u and it is %u.",
-                 PNM_OVERALLMAXVAL, convmaxval);
-
-    pnm_writepnminit(cofp, cols, rows, convmaxval, format, 0);
-    outputrow = pnm_allocrow(cols);
-
-    for (row = 0; row < rows; ++row) {
-        unsigned int col;
-        for (col = 0; col < cols; ++col)
-            PNM_ASSIGN1(outputrow[col], g);
-        pnm_writepnmrow(cofp, outputrow, cols, convmaxval, format, 0);
+static const char *
+makeConvolutionKernel(unsigned int const cols,
+                      unsigned int const rows) {
+/*----------------------------------------------------------------------------
+   Return a convolution kernel with dimensions 'cols' by 'rows' that is
+   uniform.  Make it in the form of the value of a Pnmconvol '-matrix'
+   option.
+-----------------------------------------------------------------------------*/
+    double const weight = 1.0/(rows * cols);
+
+    char * matrix;
+
+    unsigned int const maxOptSize = (cols * 10 + 1) * rows + 1;
+
+    MALLOCARRAY(matrix, maxOptSize);
+
+    if (matrix == NULL)
+        pm_error("Could not get memory for a %u x %u convolution matrix",
+                 rows, cols);
+    else {
+        unsigned int row;
+        char * cursor;
+        
+        cursor = &matrix[0];  /* Start at beginning of string */
+
+        for (row = 0; row < rows; ++row) {
+            unsigned int col;
+
+            if (row > 0)
+                *cursor++ = ';';
+
+            for (col = 0; col < cols; ++col) {
+                char weightStr[20];
+                unsigned int i;
+
+                assert(cursor - matrix + 10 < maxOptSize);
+
+                if (col > 0)
+                    *cursor++ = ',';
+
+                snprintf(weightStr, sizeof(weightStr), "%f", weight);
+
+                for (i = 0; weightStr[i]; ++i)
+                    *cursor++ = weightStr[i];
+            }
+        }
     }
-    pnm_freerow(outputrow);
+    return matrix;
 }
 
 
@@ -181,31 +197,26 @@ int
 main(int argc, const char ** argv) {
 
     struct cmdlineInfo cmdline;
-    FILE * convFileP;
-    const char * tempfileName;
+    const char * matrixOptValue;
 
     pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    if (cmdline.dump)
-        convFileP = pm_openw(cmdline.dump);
-    else
-        pm_make_tmpfile(&convFileP, &tempfileName);
-        
-    writeConvolutionImage(convFileP, cmdline.width, cmdline.height,
-                          PGM_FORMAT);
-
-    pm_close(convFileP);
+    matrixOptValue = makeConvolutionKernel(cmdline.width, cmdline.height);
 
     if (cmdline.dump) {
-        /* We're done.  Convolution image is in user's file */
+        fprintf(stdout, "%s\n", matrixOptValue);
     } else {
+        const char * matrixOpt;
+        asprintfN(&matrixOpt, "-matrix=%s", matrixOptValue);
+
         pm_system_lp("pnmconvol", NULL, NULL, NULL, NULL,
-                     "pnmconvol", tempfileName, cmdline.inputFilespec, NULL);
+                     "pnmconvol", matrixOpt, cmdline.inputFilespec, NULL);
 
-        unlink(tempfileName);
-        strfree(tempfileName);
+        strfree(matrixOpt);
     }
+    strfree(matrixOptValue);
+
     return 0;
 }