diff options
Diffstat (limited to 'converter/ppm/pjtoppm.c')
-rw-r--r-- | converter/ppm/pjtoppm.c | 253 |
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); +} |