/* 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 #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; unsigned int rows; unsigned int rowsX; unsigned int cols; bool colsIsSet; int r = 0, c = 0, p = 0, i; unsigned char **image = NULL; int *imlen; FILE *fp = stdin; int mode; bool modeIsSet = false; 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 *%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 *%c%d%c", cmd, val, c); break; } break; case 'r': switch (c) { case 'S': /* width */ if (val < 0) pm_error("invalid width value"); else { cols = val; colsIsSet = true; } break; case 'T': /* height */ if (val < 0) pm_error ("invalid height value"); else rowsX = 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 *%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; modeIsSet = true; 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 *%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 *%c%d%c", cmd, val, c); break; } default: pm_message("uninmplemented *%c%d%c", cmd, val, c); break; } } } pm_close(fp); if (!modeIsSet) pm_error("Input does not contain a 'bM' transmission mode order"); 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); }