Blame converter/ppm/pjtoppm.c

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
}