about summary refs log tree commit diff
path: root/editor/pamditherbw.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/pamditherbw.c')
-rw-r--r--editor/pamditherbw.c210
1 files changed, 113 insertions, 97 deletions
diff --git a/editor/pamditherbw.c b/editor/pamditherbw.c
index 36eb7d9e..4b192e6e 100644
--- a/editor/pamditherbw.c
+++ b/editor/pamditherbw.c
@@ -29,6 +29,10 @@ enum halftone {QT_FS,
 
 enum ditherType {DT_REGULAR, DT_CLUSTER};
 
+static sample blackSample = (sample) PAM_BLACK;
+static sample whiteSample = (sample) PAM_BW_WHITE;
+static tuple  const blackTuple = &blackSample;
+static tuple  const whiteTuple = &whiteSample;
 
 struct cmdlineInfo {
     /* All the information the user supplied in the command line,
@@ -95,6 +99,8 @@ parseCommandLine(int argc, char ** argv,
     pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
+    free(option_def);
+
     if (floydOpt + atkinsonOpt + thresholdOpt + hilbertOpt + dither8Opt + 
         cluster3Opt + cluster4Opt + cluster8Opt == 0)
         cmdlineP->halftone = QT_FS;
@@ -186,134 +192,143 @@ makeOutputPam(unsigned int const width,
 
 #define MAXORD 18
 
-static int hil_order,hil_ord;
-static int hil_turn;
-static int hil_dx,hil_dy;
-static int hil_x,hil_y;
-static int hil_stage[MAXORD];
-static int hil_width,hil_height;
+struct Hil {
+    int order;
+    int ord;
+    int turn;
+    int dx;
+    int dy;
+    int x;
+    int y;
+    int stage[MAXORD];
+    int width;
+    int height;
+};
 
 static void 
-initHilbert(int const w, 
-            int const h) {
+initHilbert(int          const w, 
+            int          const h,
+            struct Hil * const hilP) {
 /*----------------------------------------------------------------------------
   Initialize the Hilbert curve tracer 
 -----------------------------------------------------------------------------*/
-    int big,ber;
-    hil_width = w;
-    hil_height = h;
+    int big, ber;
+    hilP->width = w;
+    hilP->height = h;
     big = w > h ? w : h;
-    for (ber = 2, hil_order = 1; ber < big; ber <<= 1, hil_order++);
-    if (hil_order > MAXORD)
+    for (ber = 2, hilP->order = 1; ber < big; ber <<= 1, hilP->order++);
+    if (hilP->order > MAXORD)
         pm_error("Sorry, hilbert order is too large");
-    hil_ord = hil_order;
-    hil_order--;
+    hilP->ord = hilP->order;
+    hilP->order--;
 }
 
 
 
-static int 
-hilbert(int * const px, int * const py) {
+static bool
+hilbert(int *        const px,
+        int *        const py,
+        struct Hil * const hilP) {
 /*----------------------------------------------------------------------------
   Return non-zero if got another point
 -----------------------------------------------------------------------------*/
     int temp;
-    if (hil_ord > hil_order) {
+    if (hilP->ord > hilP->order) {
         /* have to do first point */
 
-        hil_ord--;
-        hil_stage[hil_ord] = 0;
-        hil_turn = -1;
-        hil_dy = 1;
-        hil_dx = hil_x = hil_y = 0;
+        hilP->ord--;
+        hilP->stage[hilP->ord] = 0;
+        hilP->turn = -1;
+        hilP->dy = 1;
+        hilP->dx = hilP->x = hilP->y = 0;
         *px = *py = 0;
-        return 1;
+        return true;
     }
 
     /* Operate the state machine */
     for(;;)  {
-        switch (hil_stage[hil_ord]) {
+        switch (hilP->stage[hilP->ord]) {
         case 0:
-            hil_turn = -hil_turn;
-            temp = hil_dy;
-            hil_dy = -hil_turn * hil_dx;
-            hil_dx = hil_turn * temp;
-            if (hil_ord > 0) {
-                hil_stage[hil_ord] = 1;
-                hil_ord--;
-                hil_stage[hil_ord]=0;
+            hilP->turn = -hilP->turn;
+            temp = hilP->dy;
+            hilP->dy = -hilP->turn * hilP->dx;
+            hilP->dx = hilP->turn * temp;
+            if (hilP->ord > 0) {
+                hilP->stage[hilP->ord] = 1;
+                hilP->ord--;
+                hilP->stage[hilP->ord]=0;
                 continue;
             }
         case 1:
-            hil_x += hil_dx;
-            hil_y += hil_dy;
-            if (hil_x < hil_width && hil_y < hil_height) {
-                hil_stage[hil_ord] = 2;
-                *px = hil_x;
-                *py = hil_y;
-                return 1;
+            hilP->x += hilP->dx;
+            hilP->y += hilP->dy;
+            if (hilP->x < hilP->width && hilP->y < hilP->height) {
+                hilP->stage[hilP->ord] = 2;
+                *px = hilP->x;
+                *py = hilP->y;
+                return true;
             }
         case 2:
-            hil_turn = -hil_turn;
-            temp = hil_dy;
-            hil_dy = -hil_turn * hil_dx;
-            hil_dx = hil_turn * temp;
-            if (hil_ord > 0) { 
+            hilP->turn = -hilP->turn;
+            temp = hilP->dy;
+            hilP->dy = -hilP->turn * hilP->dx;
+            hilP->dx = hilP->turn * temp;
+            if (hilP->ord > 0) { 
                 /* recurse */
 
-                hil_stage[hil_ord] = 3;
-                hil_ord--;
-                hil_stage[hil_ord]=0;
+                hilP->stage[hilP->ord] = 3;
+                hilP->ord--;
+                hilP->stage[hilP->ord]=0;
                 continue;
             }
         case 3:
-            hil_x += hil_dx;
-            hil_y += hil_dy;
-            if (hil_x < hil_width && hil_y < hil_height) {
-                hil_stage[hil_ord] = 4;
-                *px = hil_x;
-                *py = hil_y;
-                return 1;
+            hilP->x += hilP->dx;
+            hilP->y += hilP->dy;
+            if (hilP->x < hilP->width && hilP->y < hilP->height) {
+                hilP->stage[hilP->ord] = 4;
+                *px = hilP->x;
+                *py = hilP->y;
+                return true;
             }
         case 4:
-            if (hil_ord > 0) {
+            if (hilP->ord > 0) {
                 /* recurse */
-                hil_stage[hil_ord] = 5;
-                hil_ord--;
-                hil_stage[hil_ord]=0;
+                hilP->stage[hilP->ord] = 5;
+                hilP->ord--;
+                hilP->stage[hilP->ord]=0;
                 continue;
             }
         case 5:
-            temp = hil_dy;
-            hil_dy = -hil_turn * hil_dx;
-            hil_dx = hil_turn * temp;
-            hil_turn = -hil_turn;
-            hil_x += hil_dx;
-            hil_y += hil_dy;
-            if (hil_x < hil_width && hil_y < hil_height) {
-                hil_stage[hil_ord] = 6;
-                *px = hil_x;
-                *py = hil_y;
-                return 1;
+            temp = hilP->dy;
+            hilP->dy = -hilP->turn * hilP->dx;
+            hilP->dx = hilP->turn * temp;
+            hilP->turn = -hilP->turn;
+            hilP->x += hilP->dx;
+            hilP->y += hilP->dy;
+            if (hilP->x < hilP->width && hilP->y < hilP->height) {
+                hilP->stage[hilP->ord] = 6;
+                *px = hilP->x;
+                *py = hilP->y;
+                return true;
             }
         case 6:
-            if (hil_ord > 0) {
+            if (hilP->ord > 0) {
                 /* recurse */
-                hil_stage[hil_ord] = 7;
-                hil_ord--;
-                hil_stage[hil_ord]=0;
+                hilP->stage[hilP->ord] = 7;
+                hilP->ord--;
+                hilP->stage[hilP->ord]=0;
                 continue;
             }
         case 7:
-            temp = hil_dy;
-            hil_dy = -hil_turn * hil_dx;
-            hil_dx = hil_turn * temp;
-            hil_turn = -hil_turn;
+            temp = hilP->dy;
+            hilP->dy = -hilP->turn * hilP->dx;
+            hilP->dx = hilP->turn * temp;
+            hilP->turn = -hilP->turn;
             /* Return from a recursion */
-            if (hil_ord < hil_order)
-                hil_ord++;
+            if (hilP->ord < hilP->order)
+                hilP->ord++;
             else
-                return 0;
+                return false;
         }
     }
 }
@@ -341,6 +356,8 @@ doHilbert(FILE *       const ifP,
     tuple ** grays;
     tuple ** bits;
 
+    struct Hil hil;
+
     int end;
     int *x,*y;
     int sum;
@@ -355,7 +372,7 @@ doHilbert(FILE *       const ifP,
     MALLOCARRAY(y, clumpSize);
     if (x == NULL  || y == NULL)
         pm_error("out of memory");
-    initHilbert(graypam.width, graypam.height);
+    initHilbert(graypam.width, graypam.height, &hil);
 
     sum = 0;
     end = clumpSize;
@@ -364,7 +381,9 @@ doHilbert(FILE *       const ifP,
         unsigned int i;
         /* compute the next cluster co-ordinates along hilbert path */
         for (i = 0; i < end; i++) {
-            if (hilbert(&x[i],&y[i])==0)
+            bool gotPoint;
+            gotPoint = hilbert(&x[i], &y[i], &hil);
+            if (!gotPoint)
                 end = i;    /* we reached the end */
         }
         /* sum levels */
@@ -381,6 +400,7 @@ doHilbert(FILE *       const ifP,
                 bits[row][col][0] = 0;
         }
     }
+    free(x);    free(y); 
     pnm_writepam(&bitpam, bits);
 
     pnm_freepamarray(bits, &bitpam);
@@ -458,11 +478,11 @@ fsConvertRow(struct converter * const converterP,
             /* We've accumulated enough light (power) to justify a
                white output pixel.
             */
-            bitrow[col][0] = PAM_BW_WHITE;
+            bitrow[col] = whiteTuple;
             /* Remove from sum the power of this white output pixel */
             accum -= stateP->white;
         } else
-            bitrow[col][0] = PAM_BLACK;
+            bitrow[col] = blackTuple;
 
         /* Forward to future output pixels the power from current
            input pixel and the power forwarded from previous input
@@ -589,10 +609,6 @@ atkinsonConvertRow(struct converter * const converterP,
                    tuplen                   grayrow[],
                    tuple                    bitrow[]) {
 
-    /* See http://www.tinrocket.com/projects/programming/graphics/00158/
-       for a description of the Atkinson algorithm
-    */
-
     struct atkinsonState * const stateP = converterP->stateP;
 
     samplen ** const error = stateP->error;
@@ -607,11 +623,11 @@ atkinsonConvertRow(struct converter * const converterP,
             /* We've accumulated enough light (power) to justify a
                white output pixel.
             */
-            bitrow[col][0] = PAM_BW_WHITE;
+            bitrow[col] = whiteTuple;
             /* Remove from accum the power of this white output pixel */
             accum -= stateP->white;
         } else
-            bitrow[col][0] = PAM_BLACK;
+            bitrow[col] = blackTuple;
         
         /* Forward to future output pixels 3/4 of the power from current
            input pixel and the power forwarded from previous input
@@ -699,8 +715,8 @@ threshConvertRow(struct converter * const converterP,
 
     unsigned int col;
     for (col = 0; col < converterP->cols; ++col)
-        bitrow[col][0] =
-            grayrow[col][0] >= stateP->threshval ? PAM_BW_WHITE : PAM_BLACK;
+        bitrow[col] =
+            grayrow[col][0] >= stateP->threshval ? whiteTuple : blackTuple;
 }
 
 
@@ -754,8 +770,8 @@ clusterConvertRow(struct converter * const converterP,
     for (col = 0; col < converterP->cols; ++col) {
         float const threshold = 
             stateP->clusterMatrix[row % diameter][col % diameter];
-        bitrow[col][0] = 
-            grayrow[col][0] > threshold ? PAM_BW_WHITE : PAM_BLACK;
+        bitrow[col] =
+            grayrow[col][0] > threshold ? whiteTuple : blackTuple;
     }
 }
 
@@ -903,7 +919,7 @@ main(int argc, char *argv[]) {
         }
 
         grayrow = pnm_allocpamrown(&graypam);
-        bitrow  = pnm_allocpamrow(&bitpam);
+        MALLOCARRAY_NOFAIL(bitrow, bitpam.width);
 
         for (row = 0; row < graypam.height; ++row) {
             pnm_readpamrown(&graypam, grayrow);
@@ -912,7 +928,7 @@ main(int argc, char *argv[]) {
             
             pnm_writepamrow(&bitpam, bitrow);
         }
-        pnm_freepamrow(bitrow);
+        free(bitrow);
         pnm_freepamrow(grayrow);
 
         if (converter.destroy)