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