about summary refs log tree commit diff
path: root/converter/ppm/pjtoppm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/pjtoppm.c')
-rw-r--r--converter/ppm/pjtoppm.c205
1 files changed, 121 insertions, 84 deletions
diff --git a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c
index e556803f..45746495 100644
--- a/converter/ppm/pjtoppm.c
+++ b/converter/ppm/pjtoppm.c
@@ -1,4 +1,4 @@
-/* pjtoppm.c - convert an HP PainJetXL image to a portable pixmap file
+/* pjtoppm.c - convert an HP PainJetXL image to a PPM
 **
 ** Copyright (C) 1990 by Christos Zoulas (christos@ee.cornell.edu)
 **
@@ -11,13 +11,12 @@
 */
 
 #include <stdbool.h>
+#include <assert.h>
 
 #include "ppm.h"
 #include "pm_c_util.h"
 #include "mallocvar.h"
 
-static char usage[] =  "[paintjetfile]";
-
 
 
 static unsigned int
@@ -46,44 +45,142 @@ egetc(FILE * const ifP) {
 
 
 
+static void
+modifyImageMode1(unsigned int     const rows,
+                 unsigned int     const planes,
+                 const int *      const imlen,
+                 unsigned char ** const image,
+                 unsigned int *   const colsP) {
+
+    unsigned int const newcols = 10240;
+    /* It could not be larger than that! */
+
+    unsigned int cols;
+    unsigned int row;
+
+    for (row = 0, cols = 0; row < rows; ++row) {
+        unsigned int plane;
+        if (image[row * planes]) {
+            for (plane = 0; plane < planes; ++plane) {
+                unsigned int i;
+                unsigned int col;
+                unsigned char * buf;
+
+                MALLOCARRAY(buf, newcols);
+                if (buf == NULL)
+                    pm_error("out of memory");
+                for (i = 0, col = 0;
+                     col < imlen[row * planes + plane];
+                     col += 2) {
+                    int cmd, val;
+                    for (cmd = image[row * planes + plane][col],
+                             val = image[plane + row * planes][col+1];
+                         cmd >= 0 && i < newcols; --cmd, ++i)
+                        buf[i] = val;
+                }
+                cols = MAX(cols, i);
+                free(image[row * planes + plane]);
+
+                /*
+                 * This is less than what we have so it realloc should
+                 * not return null. Even if it does, tough! We will
+                 * lose a line, and probably die on the next line anyway
+                 */
+                image[row * planes + plane] = realloc(buf, i);
+            }
+        }
+    }
+    *colsP = cols * 8;  assert(cols < UINT_MAX/8);
+}
+
+
+
+static void
+writePpm(FILE *           const ofP,
+         unsigned int     const cols,
+         unsigned int     const rows,
+         unsigned int     const planes,
+         unsigned char ** const image,
+         int              const mode,
+         const int *      const imlen) {
+
+    pixel * pixrow;
+    unsigned int row;
+
+    ppm_writeppminit(stdout, cols, rows, 255, 0);
+    pixrow = ppm_allocrow(cols);
+
+    for (row = 0; row < rows; ++row) {
+        if (image[row * planes + 0] == NULL) {
+            unsigned int col;
+            for (col = 0; col < cols; ++col)
+                PPM_ASSIGN(pixrow[col], 0, 0, 0);
+        } else {
+            unsigned int col;
+            unsigned int cmd;
+            for (cmd = 0, col = 0; col < cols; col += 8, ++cmd) {
+                unsigned int i;
+                for (i = 0; i < 8 && col + i < cols; ++i) {
+                    unsigned int plane;
+                    unsigned char bf[3];
+
+                    assert(planes == 3);
+
+                    for (plane = 0; plane < planes; ++plane) {
+                        if (mode == 0 && cmd >= imlen[row * planes + plane])
+                            bf[plane] = 0;
+                        else
+                            bf[plane] = (image[row * planes + plane][cmd] &
+                                     (1 << (7 - i))) ? 255 : 0;
+                    }
+                    PPM_ASSIGN(pixrow[col + i], bf[0], bf[1], bf[2]);
+                }
+            }
+            ppm_writeppmrow(stdout, pixrow, cols, 255, 0);
+        }
+    }
+}
+
+
+
 int
 main(int argc, const char ** argv) {
 
     int cmd, val;
     char buffer[BUFSIZ];
-    int planes = 3;
+    unsigned int planes;
     unsigned int rows;
     unsigned int rowsX;
     unsigned int cols;
     bool colsIsSet;
-    unsigned char **image = NULL;
-    int *imlen;
+    unsigned char ** image;  /* malloc'ed */
+    int * imlen;  /* malloc'ed */
     FILE * ifP;
     int mode;
     bool modeIsSet;
-    int argn;
-    unsigned char bf[3];
-    pixel * pixrow;
     int c;
-    int row;
-    int plane;
+    unsigned int plane;
+    unsigned int row;
 
     pm_proginit(&argc, argv);
 
-    argn = 1;
-    if (argn != argc)
-        ifP = pm_openr(argv[argn++]);
+    if (argc-1 > 0)
+        ifP = pm_openr(argv[1]);
     else
         ifP = stdin;
 
-    if (argn != argc)
-        pm_usage(usage);
+    if (argc-1 > 2)
+        pm_error("Too many arguments (%u).  Only possible argument is "
+                 "input file name", argc-1);
 
     row = 0;  /* initial value */
     plane = 0;  /* initial value */
     modeIsSet = false;  /* initial value */
     colsIsSet = false;  /* initial value */
     rowsX = 0;  /* initial value */
+    image = NULL;  /* initial value */
+    imlen = NULL;  /* initial value */
+    planes = 3;  /* initial value */
 
     while ((c = fgetc(ifP)) != -1) {
         if (c != '\033')
@@ -170,13 +267,8 @@ main(int argc, const char ** argv) {
                     if (row >= rowsX || image == NULL) {
                         if (row >= rowsX)
                             rowsX += 100;
-                        if (image == NULL) {
-                            MALLOCARRAY(image, uintProduct(rowsX, planes));
-                            MALLOCARRAY(imlen, uintProduct(rowsX, planes));
-                        } else {
-                            REALLOCARRAY(image, uintProduct(rowsX, planes));
-                            REALLOCARRAY(imlen, uintProduct(rowsX, planes));
-                        }
+                        REALLOCARRAY(image, uintProduct(rowsX, planes));
+                        REALLOCARRAY(imlen, uintProduct(rowsX, planes));
                     }
                     if (image == NULL || imlen == NULL)
                         pm_error("out of memory");
@@ -196,6 +288,9 @@ main(int argc, const char ** argv) {
                         ++plane;
                     else {
                         plane = 0;
+                        if (row > UINT_MAX/planes-100)
+                            pm_error("Too many rows (more than %u) "
+                                     "for computation", row);
                         ++row;
                     }
                     break;
@@ -241,72 +336,14 @@ main(int argc, const char ** argv) {
         pm_error("Input does not contain a 'bM' transmission mode order");
 
     rows = row;
-    if (mode == 1) {
-        unsigned int const newcols = 10240;
-            /* It could not be larger than that! */
 
-        unsigned char * buf;
-        unsigned int row;
+    if (mode == 1) {
+        modifyImageMode1(rows, planes, imlen, image, &cols);
 
-        for (row = 0, cols = 0; row < rows; ++row) {
-            unsigned int plane;
-            if (image[row * planes] == NULL)
-                continue;
-            for (plane = 0; plane < planes; ++plane) {
-                unsigned int i;
-                unsigned int col;
-                MALLOCARRAY(buf, newcols);
-                if (buf == NULL)
-                    pm_error("out of memory");
-                for (i = 0, col = 0;
-                     col < imlen[plane + row * planes];
-                     col += 2)
-                    for (cmd = image[plane + row * planes][col],
-                             val = image[plane + row * planes][col+1];
-                         cmd >= 0 && i < newcols; cmd--, i++)
-                        buf[i] = val;
-                cols = MAX(cols, i);
-                free(image[plane + row * planes]);
-                /*
-                 * This is less than what we have so it realloc should
-                 * not return null. Even if it does, tough! We will
-                 * lose a line, and probably die on the next line anyway
-                 */
-                image[plane + row * planes] = realloc(buf, i);
-            }
-        }
-        cols *= 8;
     }
 
-    ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
-    pixrow = ppm_allocrow(cols);
+    writePpm(stdout, cols, rows, planes, image, mode, imlen);
 
-    for (row = 0; row < rows; ++row) {
-        if (image[row * planes] == NULL) {
-            unsigned int col;
-            for (col = 0; col < cols; ++col)
-                PPM_ASSIGN(pixrow[col], 0, 0, 0);
-            continue;
-        }
-        {
-            unsigned int col;
-            unsigned int cmd;
-            for (cmd = 0, col = 0; col < cols; col += 8, ++cmd) {
-                unsigned int i;
-                for (i = 0; i < 8 && col + i < cols; ++i) {
-                    unsigned int plane;
-                    for (plane = 0; plane < planes; ++plane)
-                        if (mode == 0 && cmd >= imlen[row * planes + plane])
-                            bf[plane] = 0;
-                        else
-                            bf[plane] = (image[row * planes + plane][cmd] &
-                                     (1 << (7 - i))) ? 255 : 0;
-                    PPM_ASSIGN(pixrow[col + i], bf[0], bf[1], bf[2]);
-                }
-            }
-        }
-        ppm_writeppmrow(stdout, pixrow, cols, 255, 0);
-    }
     pm_close(stdout);
 
     return 0;