about summary refs log tree commit diff
path: root/editor/ppmcolormask.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/ppmcolormask.c')
-rw-r--r--editor/ppmcolormask.c188
1 files changed, 120 insertions, 68 deletions
diff --git a/editor/ppmcolormask.c b/editor/ppmcolormask.c
index 5ef8d1c1..3812ac86 100644
--- a/editor/ppmcolormask.c
+++ b/editor/ppmcolormask.c
@@ -9,6 +9,7 @@
   Contributed to the public domain by its author.
 =========================================================================*/
 
+#define _DEFAULT_SOURCE /* New name for SVID & BSD source defines */
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 #define _BSD_SOURCE  /* Make sure strdup() is in <string.h> */
 #include <assert.h>
@@ -19,23 +20,23 @@
 #include "mallocvar.h"
 #include "nstring.h"
 #include "ppm.h"
-#include "pbm.h"
+#include "pam.h"
 
-enum matchType {
+typedef enum {
     MATCH_EXACT,
     MATCH_BK
-};
+} MatchType;
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
     const char * inputFilename;
-    unsigned int colorCount;
+    unsigned int colorCt;
     struct {
-        enum matchType matchType;
+        MatchType matchType;
         union {
-            pixel    color;   /* matchType == MATCH_EXACT */
+            tuplen   color;   /* matchType == MATCH_EXACT */
             bk_color bkColor; /* matchType == MATCH_BK */
         } u;
     } maskColor[16];
@@ -45,46 +46,59 @@ struct cmdlineInfo {
 
 
 static void
+freeCmdline(struct CmdlineInfo * const cmdlineP) {
+
+    unsigned int i;
+
+    for (i = 0; i < cmdlineP->colorCt; ++ i) {
+        if (cmdlineP->maskColor[i].matchType == MATCH_EXACT)
+            free(cmdlineP->maskColor[i].u.color);
+    }
+}
+
+
+
+static void
 parseColorOpt(const char *         const colorOpt,
-              struct cmdlineInfo * const cmdlineP) {
+              struct CmdlineInfo * const cmdlineP) {
 
-    unsigned int colorCount;
+    unsigned int colorCt;
     char * colorOptWork;
     char * cursor;
     bool eol;
-    
+
     colorOptWork = strdup(colorOpt);
     cursor = &colorOptWork[0];
-    
+
     eol = FALSE;    /* initial value */
-    colorCount = 0; /* initial value */
-    while (!eol && colorCount < ARRAY_SIZE(cmdlineP->maskColor)) {
+    colorCt = 0;    /* initial value */
+    while (!eol && colorCt < ARRAY_SIZE(cmdlineP->maskColor)) {
         const char * token;
         token = pm_strsep(&cursor, ",");
         if (token) {
             if (strneq(token, "bk:", 3)) {
-                cmdlineP->maskColor[colorCount].matchType = MATCH_BK;
-                cmdlineP->maskColor[colorCount].u.bkColor =
+                cmdlineP->maskColor[colorCt].matchType = MATCH_BK;
+                cmdlineP->maskColor[colorCt].u.bkColor =
                     ppm_bk_color_from_name(&token[3]);
             } else {
-                cmdlineP->maskColor[colorCount].matchType = MATCH_EXACT;
-                cmdlineP->maskColor[colorCount].u.color =
-                    ppm_parsecolor(token, PPM_MAXMAXVAL);
+                cmdlineP->maskColor[colorCt].matchType = MATCH_EXACT;
+                cmdlineP->maskColor[colorCt].u.color =
+                    pnm_parsecolorn(token);
             }
-            ++colorCount;
+            ++colorCt;
         } else
             eol = TRUE;
     }
     free(colorOptWork);
 
-    cmdlineP->colorCount = colorCount;
+    cmdlineP->colorCt = colorCt;
 }
 
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo *cmdlineP) {
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo *cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that many of the strings that this function returns in the
    *cmdlineP structure are actually in the supplied argv array.  And
@@ -109,7 +123,7 @@ parseCommandLine(int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0);
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and all of *cmdlineP. */
 
     if (colorSpec)
@@ -128,16 +142,15 @@ parseCommandLine(int argc, char ** argv,
         if (argc-1 < 1)
             pm_error("You must specify the -color option.");
         else {
-            cmdlineP->colorCount = 1;
+            cmdlineP->colorCt = 1;
             cmdlineP->maskColor[0].matchType = MATCH_EXACT;
-            cmdlineP->maskColor[0].u.color =
-                ppm_parsecolor(argv[1], PPM_MAXMAXVAL);
+            cmdlineP->maskColor[0].u.color = pnm_parsecolorn(argv[1]);
 
             if (argc - 1 < 2)
                 cmdlineP->inputFilename = "-";  /* he wants stdin */
             else if (argc-1 == 2)
                 cmdlineP->inputFilename = argv[2];
-            else 
+            else
                 pm_error("Too many arguments.  The only arguments accepted "
                          "are the mask color and optional input file name");
         }
@@ -146,16 +159,47 @@ parseCommandLine(int argc, char ** argv,
 
 
 
+static void
+setupOutput(FILE *       const fileP,
+            unsigned int const width,
+            unsigned int const height,
+            struct pam * const outPamP) {
+
+    outPamP->size             = sizeof(*outPamP);
+    outPamP->len              = PAM_STRUCT_SIZE(tuple_type);
+    outPamP->file             = fileP;
+    outPamP->format           = RPBM_FORMAT;
+    outPamP->plainformat      = 0;
+    outPamP->height           = height;
+    outPamP->width            = width;
+    outPamP->depth            = 1;
+    outPamP->maxval           = 1;
+    outPamP->bytes_per_sample = 1;
+    strcpy(outPamP->tuple_type, PAM_PBM_TUPLETYPE);
+}
+
+
+
 static bool
-isBkColor(pixel    const comparator,
-          pixval   const maxval,
-          bk_color const comparand) {
+isBkColor(tuple        const comparator,
+          struct pam * const pamP,
+          bk_color     const comparand) {
+
+    pixel comparatorPixel;
+    bk_color comparatorBk;
 
     /* TODO: keep a cache of the bk color for each color in
        a colorhash_table.
     */
-    
-    bk_color const comparatorBk = ppm_bk_color_from_color(comparator, maxval);
+
+    assert(pamP->depth >= 3);
+
+    PPM_ASSIGN(comparatorPixel,
+               comparator[PAM_RED_PLANE],
+               comparator[PAM_GRN_PLANE],
+               comparator[PAM_BLU_PLANE]);
+
+    comparatorBk = ppm_bk_color_from_color(comparatorPixel, pamP->maxval);
 
     return comparatorBk == comparand;
 }
@@ -163,86 +207,94 @@ isBkColor(pixel    const comparator,
 
 
 static bool
-colorIsInSet(pixel              const color,
-             pixval             const maxval,
-             struct cmdlineInfo const cmdline) {
+colorIsInSet(tuple              const color,
+             struct pam *       const pamP,
+             struct CmdlineInfo const cmdline) {
 
     bool isInSet;
     unsigned int i;
+    tuple maskColorUnnorm;
+
+    maskColorUnnorm = pnm_allocpamtuple(pamP);
 
-    for (i = 0, isInSet = FALSE;
-         i < cmdline.colorCount && !isInSet; ++i) {
+    for (i = 0, isInSet = FALSE; i < cmdline.colorCt && !isInSet; ++i) {
 
         assert(i < ARRAY_SIZE(cmdline.maskColor));
 
         switch(cmdline.maskColor[i].matchType) {
         case MATCH_EXACT:
-            if (PPM_EQUAL(color, cmdline.maskColor[i].u.color))
+            pnm_unnormalizetuple(pamP,
+                                 cmdline.maskColor[i].u.color,
+                                 maskColorUnnorm);
+            if (pnm_tupleequal(pamP, color, maskColorUnnorm))
                 isInSet = TRUE;
             break;
         case MATCH_BK:
-            if (isBkColor(color, maxval, cmdline.maskColor[i].u.bkColor))
+            if (isBkColor(color, pamP, cmdline.maskColor[i].u.bkColor))
                 isInSet = TRUE;
             break;
         }
     }
+
+    free(maskColorUnnorm);
+
     return isInSet;
 }
 
 
 
 int
-main(int argc, char *argv[]) {
+main(int argc, const char *argv[]) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
 
     FILE * ifP;
+    struct pam inPam;
+    struct pam outPam;
 
-    /* Parameters of input image: */
-    int rows, cols;
-    pixval maxval;
-    int format;
-
-    ppm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
     ifP = pm_openr(cmdline.inputFilename);
 
-    ppm_readppminit(ifP, &cols, &rows, &maxval, &format);
-    pbm_writepbminit(stdout, cols, rows, 0);
+    pnm_readpaminit(ifP, &inPam, PAM_STRUCT_SIZE(allocation_depth));
+
+    pnm_setminallocationdepth(&inPam, 3);
+
+    setupOutput(stdout, inPam.width, inPam.height, &outPam);
+
+    pnm_writepaminit(&outPam);
     {
-        pixel * const inputRow = ppm_allocrow(cols);
-        bit *   const maskRow  = pbm_allocrow(cols);
+        tuple * const inputRow = pnm_allocpamrow(&inPam);
+        tuple * const maskRow  = pnm_allocpamrow(&outPam);
 
         unsigned int numPixelsMasked;
 
         unsigned int row;
-        for (row = 0, numPixelsMasked = 0; row < rows; ++row) {
-            int col;
-            ppm_readppmrow(ifP, inputRow, cols, maxval, format);
-            for (col = 0; col < cols; ++col) {
-                pixel thisColor;
-                    /* Color of this pixel with same maxval as used in
-                       'cmdline'
-                    */
-                PPM_DEPTH(thisColor, inputRow[col], maxval, PPM_MAXMAXVAL);
-                if (colorIsInSet(thisColor, PPM_MAXMAXVAL, cmdline)) {
-                    maskRow[col] = PBM_BLACK;
+
+        for (row = 0, numPixelsMasked = 0; row < inPam.height; ++row) {
+            unsigned int col;
+            pnm_readpamrow(&inPam, inputRow);
+            pnm_makerowrgb(&inPam, inputRow);
+            for (col = 0; col < inPam.width; ++col) {
+                if (colorIsInSet(inputRow[col], &inPam, cmdline)) {
+                    maskRow[col][0] = PAM_BLACK;
                     ++numPixelsMasked;
-                } else 
-                    maskRow[col] = PBM_WHITE;
+                } else
+                    maskRow[col][0] = PAM_BW_WHITE;
             }
-            pbm_writepbmrow(stdout, maskRow, cols, 0);
+            pnm_writepamrow(&outPam, maskRow);
         }
 
         if (cmdline.verbose)
             pm_message("%u pixels found matching %u requested colors",
-                       numPixelsMasked, cmdline.colorCount);
+                       numPixelsMasked, cmdline.colorCt);
 
-        pbm_freerow(maskRow);
-        ppm_freerow(inputRow);
+        pnm_freepamrow(maskRow);
+        pnm_freepamrow(inputRow);
     }
+    freeCmdline(&cmdline);
     pm_close(ifP);
 
     return 0;