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.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c
new file mode 100644
index 00000000..7b694fb3
--- /dev/null
+++ b/converter/ppm/pjtoppm.c
@@ -0,0 +1,253 @@
+/* pjtoppm.c - convert an HP PainJetXL image to a portable pixmap file
+**
+** Copyright (C) 1990 by Christos Zoulas (christos@ee.cornell.edu)
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include "ppm.h"
+#include "mallocvar.h"
+
+static char usage[] =  "[paintjetfile]";
+
+static int egetc ARGS((FILE *fp));
+static int
+egetc(fp)
+    FILE *fp;
+{
+    int c;
+    if ((c = fgetc(fp)) == -1)
+        pm_error("unexpected end of file");
+    return(c);
+}
+
+int
+main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int cmd, val;
+    char buffer[BUFSIZ];
+    int planes = 3, rows = -1, cols = -1;
+    int r = 0, c = 0, p = 0, i;
+    unsigned char **image = NULL;
+    int *imlen;
+    FILE *fp = stdin;
+    int mode;
+    int argn;
+    unsigned char bf[3];
+    pixel *pixrow;
+
+
+    ppm_init(&argc, argv);
+    argn = 1;
+    if (argn != argc)
+        fp = pm_openr(argv[argn++]);
+    else
+        fp = stdin;
+
+    if (argn != argc)
+        pm_usage(usage);
+
+    while ((c = fgetc(fp)) != -1) {
+        if (c != '\033')
+            continue;
+        switch (c = egetc(fp)) {
+        case 'E':   /* reset */
+            break;
+        case '*':
+            cmd = egetc(fp);
+            for (i = 0; i < BUFSIZ; i++) {
+                if (!isdigit(c = egetc(fp)) && c != '+' && c != '-')
+                    break;
+                buffer[i] = c;
+            }
+            if (i != 0) {
+                buffer[i] = '\0';
+                if (sscanf(buffer, "%d", &val) != 1) 
+                    pm_error("bad value `%s' at <ESC>*%c%c", buffer, cmd, c);
+            }
+            else
+                val = -1;
+            switch (cmd) {
+            case 't':
+                switch (c) {
+                case 'J':   /* render */
+                    break;
+                case 'K':   /* back scale */
+                    break;
+                case 'I':   /* gamma */
+                    break;
+                case 'R':
+                    break;  /* set resolution */
+                default:
+                    pm_message("uninmplemented <ESC>*%c%d%c", cmd, val, c);
+                    break;
+                }
+                break;
+            case 'r':
+                switch (c) {
+                case 'S':   /* width */
+                    cols = val;
+                    break;
+                case 'T':   /* height */
+                    rows = val;
+                    break;
+                case 'U':   /* planes */
+                    planes = val;
+                    if (planes != 3) 
+                        pm_error("can handle only 3 plane files");
+                    break;
+                case 'A':   /* begin raster */
+                    break;
+                case 'B':
+                case 'C':   /* end raster */
+                    break;
+                case 'V':
+                    break;  /* set deci height */
+                case 'H':
+                    break;  /* set deci width */
+                default:
+                    pm_message("uninmplemented <ESC>*%c%d%c", cmd, val, c);
+                    break;
+                }
+                break;
+            case 'b':
+                switch (c) {
+                case 'M':   /* transmission mode */
+                    if (val != 0 && val != 1)
+                        pm_error("unimplemented trasmission mode %d", val);
+                    mode = val;
+                    break;
+                case 'V':   /* send plane */
+                case 'W':   /* send last plane */
+                    if (rows == -1 || r >= rows || image == NULL) {
+                        if (rows == -1 || r >= rows)
+                            rows += 100;
+                        if (image == NULL) {
+                            MALLOCARRAY(image, rows * planes);
+                            MALLOCARRAY(imlen, rows * planes);
+                        }
+                        else {
+                            image = (unsigned char **) 
+                                realloc(image, 
+                                        rows * planes * 
+                                        sizeof(unsigned char *));
+                            imlen = (int *) 
+                                realloc(imlen, rows * planes * sizeof(int));
+                        }
+                    }
+                    if (image == NULL || imlen == NULL)
+                        pm_error("out of memory");
+                    if (p == planes) 
+                        pm_error("too many planes");
+                    cols = cols > val ? cols : val;
+                    imlen[r * planes + p] = val;
+                    MALLOCARRAY(image[r * planes + p], val);
+                    if (image[r * planes + p] == NULL) 
+                        pm_error("out of memory");
+                    if (fread(image[r * planes + p], 1, val, fp) != val) 
+                        pm_error("short data");
+                    if (c == 'V')
+                        p++;
+                    else {
+                        p = 0;
+                        r++;
+                    }
+                    break;
+                default:
+                    pm_message("uninmplemented <ESC>*%c%d%c", cmd, val, c);
+                    break;
+                }
+                break;
+            case 'p': /* Position */
+                if (p != 0) 
+                    pm_error("changed position in the middle of "
+                             "transferring planes");
+                switch (c) {
+                case 'X':
+                    pm_message("can only position in y");
+                    break;
+                case 'Y':
+                    if (buffer[0] == '+')
+                        val = r + val;
+                    if (buffer[0] == '-')
+                        val = r - val;
+                    for (; val > r; r++) 
+                        for (p = 0; p < 3; p++) {
+                            imlen[r * planes + p] = 0;
+                            image[r * planes + p] = NULL;
+                        }
+                    r = val;
+                    break;
+                default:
+                    pm_message("uninmplemented <ESC>*%c%d%c", cmd, val, c);
+                    break;
+                }
+            default:
+                pm_message("uninmplemented <ESC>*%c%d%c", cmd, val, c);
+                break;
+            }
+        }
+    }
+    pm_close(fp);
+    rows = r;
+    if (mode == 1) {
+        unsigned char *buf;
+        int newcols = 0;
+        newcols = 10240; /* It could not be larger that that! */
+        cols = 0;
+        for (r = 0; r < rows; r++) {
+            if (image[r * planes] == NULL)
+                continue;
+            for (p = 0; p < planes; p++) {
+                MALLOCARRAY(buf, newcols);
+                if (buf == NULL) 
+                    pm_error("out of memory");
+                for (i = 0, c = 0; c < imlen[p + r * planes]; c += 2)
+                    for (cmd = image[p + r * planes][c],
+                             val = image[p + r * planes][c+1]; 
+                         cmd >= 0 && i < newcols; cmd--, i++) 
+                        buf[i] = val;
+                cols = cols > i ? cols : i;
+                free(image[p + r * 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[p + r * planes] = (unsigned char *) realloc(buf, i);
+            }
+        }
+        cols *= 8;
+    }
+            
+       
+    ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
+    pixrow = ppm_allocrow(cols);
+    for (r = 0; r < rows; r++) {
+        if (image[r * planes] == NULL) {
+            for (c = 0; c < cols; c++)
+                PPM_ASSIGN(pixrow[c], 0, 0, 0);
+            continue;
+        }
+        for (cmd = 0, c = 0; c < cols; c += 8, cmd++) 
+            for (i = 0; i < 8 && c + i < cols; i++) {
+                for (p = 0; p < planes; p++) 
+                    if (mode == 0 && cmd >= imlen[r * planes + p])
+                        bf[p] = 0;
+                    else
+                        bf[p] = (image[r * planes + p][cmd] & 
+                                 (1 << (7 - i))) ? 255 : 0;
+                PPM_ASSIGN(pixrow[c + i], bf[0], bf[1], bf[2]);
+            }
+        ppm_writeppmrow(stdout, pixrow, cols, (pixval) 255, 0);
+    }
+    pm_close(stdout);
+    exit(0);
+}