about summary refs log tree commit diff
path: root/converter/other/pnmtosgi.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/pnmtosgi.c')
-rw-r--r--converter/other/pnmtosgi.c512
1 files changed, 274 insertions, 238 deletions
diff --git a/converter/other/pnmtosgi.c b/converter/other/pnmtosgi.c
index 169125b3..a8df5328 100644
--- a/converter/other/pnmtosgi.c
+++ b/converter/other/pnmtosgi.c
@@ -31,17 +31,6 @@ typedef struct {
     long        length;
 } ScanLine;
 
-/* prototypes */
-static void put_big_short ARGS((short s));
-static void put_big_long ARGS((long l));
-#define put_byte(b)     (void)(putc((unsigned char)(b), stdout))
-static void put_short_as_byte ARGS((short s));
-static void write_table  ARGS((long *table, int tabsize));
-static void write_channels ARGS((int cols, int rows, int channels, void (*put) ARGS((short)) ));
-static long * build_channels ARGS((FILE *ifp, int cols, int rows, xelval maxval, int format, int bpc, int channels));
-static ScanElem *compress ARGS((ScanElem *temp, int row, int rows, int cols, int chan_no, long *table, int bpc));
-static int rle_compress ARGS((ScanElem *inbuf, int cols));
-
 #define WORSTCOMPR(x)   (2*(x) + 2)
 
 
@@ -55,301 +44,348 @@ static ScanElem * rletemp;
 static xel * pnmrow;
 
 
-static void
-write_header(int const cols, 
-             int const rows, 
-             xelval const maxval, 
-             int const bpc, 
-             int const dimensions, 
-             int const channels, 
-             const char * const imagename)
-{
-    int i;
-
-#ifdef DEBUG
-    pm_message("writing header");
-#endif
-
-    put_big_short(SGI_MAGIC);
-    put_byte(storage);
-    put_byte((char)bpc);
-    put_big_short(dimensions);
-    put_big_short(cols);
-    put_big_short(rows);
-    put_big_short(channels);
-    put_big_long(0);                /* PIXMIN */
-    put_big_long(maxval);           /* PIXMAX */
-    for( i = 0; i < 4; i++ )
-        put_byte(0);
-    for( i = 0; i < 79 && imagename[i] != '\0'; i++ )
-        put_byte(imagename[i]);
-    for(; i < 80; i++ )
-        put_byte(0);
-    put_big_long(CMAP_NORMAL);
-    for( i = 0; i < 404; i++ )
-        put_byte(0);
-}
 
+#define putByte(b) (void)(putc((unsigned char)(b), stdout))
 
 
-int
-main(int argc,char * argv[])
-{
-    FILE *ifp;
-    int argn;
-    const char * const usage = "[-verbatim|-rle] [-imagename <name>] [pnmfile]";
-    int cols, rows, format;
-    xelval maxval, newmaxval;
-    const char *imagename = "no name";
-    int bpc, dimensions, channels;
-    long *table = NULL;
+static void
+putBigShort(short const s) {
 
-    pnm_init(&argc, argv);
+    if (pm_writebigshort(stdout, s ) == -1)
+        pm_error( "write error" );
+}
 
-    argn = 1;
-    while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
-        if( pm_keymatch(argv[argn], "-verbatim", 2) )
-            storage = STORAGE_VERBATIM;
-        else
-        if( pm_keymatch(argv[argn], "-rle", 2) )
-            storage = STORAGE_RLE;
-        else
-        if( pm_keymatch(argv[argn], "-imagename", 2) ) {
-            if( ++argn >= argc )
-                pm_usage(usage);
-            imagename = argv[argn];
-        }
-        else
-            pm_usage(usage);
-        ++argn;
-    }
 
-    if( argn < argc ) {
-        ifp = pm_openr( argv[argn] );
-        argn++;
-    }
-    else
-        ifp = stdin;
 
-    if( argn != argc )
-        pm_usage(usage);
+static void
+putBigLong(long const l) {
 
-    pnm_readpnminit(ifp, &cols, &rows, &maxval, &format);
-    if( rows>INT16MAX || cols>INT16MAX )
-      pm_error ("Input image is too large.");
+    if (pm_writebiglong( stdout, l ) == -1)
+        pm_error( "write error" );
+}
 
-    pnmrow = pnm_allocrow(cols);
 
-    switch( PNM_FORMAT_TYPE(format) ) {
-        case PBM_TYPE:
-            newmaxval = PGM_MAXMAXVAL;
-            pm_message("promoting PBM to PGM");
-        case PGM_TYPE:
-            newmaxval = maxval;
-            dimensions = 2; channels = 1;
-            break;
-        case PPM_TYPE:
-            newmaxval = maxval;
-            dimensions = 3; channels = 3;
-            break;
-        default:
-            pm_error("can\'t happen");
-    }
-    if( newmaxval <= MAXVAL_BYTE )
-        bpc = 1;
-    else if( newmaxval <= MAXVAL_WORD )
-        bpc = 2;
-    else
-        pm_error("maxval too large - try using \"pnmdepth %d\"", MAXVAL_WORD);
 
-    table = build_channels(ifp, cols, rows, newmaxval, format, bpc, channels);
-    pnm_freerow(pnmrow);
-    pm_close(ifp);
-
-    write_header(cols, rows, newmaxval, bpc, dimensions, channels, imagename);
-    if( table )
-        write_table(table, rows * channels);
-    if( bpc == 1 )
-        write_channels(cols, rows, channels, put_short_as_byte);
-    else
-        write_channels(cols, rows, channels, put_big_short);
+static void
+putShortAsByte(short const s) {
 
-    exit(0);
+    putByte((unsigned char)s);
 }
 
 
+
 static void
-write_table(long * table, int const tabsize)
-{
-    int i;
-    long offset;
+writeTable(long *       const table,
+           unsigned int const tabsize) {
 
-#ifdef DEBUG
-    pm_message("writing table");
-#endif
+    unsigned int i;
+    unsigned long offset;
 
     offset = HeaderSize + tabsize * 8;
-    for( i = 0; i < tabsize; i++ ) {
-        put_big_long(offset);
+
+    for (i = 0; i < tabsize; ++i) {
+        putBigLong(offset);
         offset += table[i];
     }
-    for( i = 0; i < tabsize; i++ )
-        put_big_long(table[i]);
+    for (i = 0; i < tabsize; ++i)
+        putBigLong(table[i]);
 }
 
 
+
 static void
-write_channels(int const cols,int const rows, int const channels,
-               void (*put) (short))
-{
-    int i, row, col;
-
-#ifdef DEBUG
-    pm_message("writing image data");
-#endif
-
-    for( i = 0; i < channels; i++ ) {
-        for( row = 0; row < rows; row++ ) {
-            for( col = 0; col < channel[i][row].length; col++ ) {
+writeChannels(unsigned int const cols,
+              unsigned int const rows,
+              unsigned int const channels,
+              void (*put) (short)) {
+
+    unsigned int i;
+
+    for (i = 0; i < channels; ++i) {
+        unsigned int row;
+        for (row = 0; row < rows; ++row) {
+            unsigned int col;
+            for (col = 0; col < channel[i][row].length; ++col) {
                 (*put)(channel[i][row].data[col]);
             }
         }
     }
 }
 
-static void
-put_big_short(short const s)
-{
-    if ( pm_writebigshort( stdout, s ) == -1 )
-        pm_error( "write error" );
-}
 
 
-static void
-put_big_long(long const l)
-{
-    if ( pm_writebiglong( stdout, l ) == -1 )
-        pm_error( "write error" );
+static int
+rleCompress(ScanElem *   const inbuf,
+            unsigned int const size) {
+
+    /* slightly modified RLE algorithm from ppmtoilbm.c written by Robert
+       A. Knop (rknop@mop.caltech.edu)
+    */
+
+    int in, out, hold, count;
+    ScanElem *outbuf = rletemp;
+
+    in = out = 0;
+    while (in < size) {
+        if ((in < size-1) && (inbuf[in] == inbuf[in+1])) {
+            /*Begin replicate run*/
+            for (count = 0, hold = in; in < size &&
+                     inbuf[in] == inbuf[hold] && count < 127;
+                 ++in, ++count)
+                ;
+            outbuf[out++] = (ScanElem)(count);
+            outbuf[out++] = inbuf[hold];
+        } else {
+            /*Do a literal run*/
+            hold = out;
+            ++out;
+            count = 0;
+            while (((in >= size-2) && (in < size))
+                   || ((in < size-2) && ((inbuf[in] != inbuf[in+1])
+                                         || (inbuf[in] != inbuf[in+2])))) {
+                outbuf[out++] = inbuf[in++];
+                if (++count >= 127)
+                    break;
+            }
+            outbuf[hold] = (ScanElem)(count | 0x80);
+        }
+    }
+    outbuf[out++] = (ScanElem)0;     /* terminator */
+
+    return out;
 }
 
 
-static void
-put_short_as_byte(short const s)
-{
-    put_byte((unsigned char)s);
+
+static ScanElem *
+compress(ScanElem *   const tempArg,
+         unsigned int const row,
+         unsigned int const rows,
+         unsigned int const cols,
+         unsigned int const chanNum,
+         long *       const table,
+         unsigned int const bpc) {
+
+    ScanElem * retval;
+
+    switch (storage) {
+    case STORAGE_VERBATIM:
+        channel[chanNum][row].length = cols;
+        channel[chanNum][row].data = tempArg;
+        MALLOCARRAY_NOFAIL(retval, cols);
+        break;
+    case STORAGE_RLE: {
+        unsigned int const tabrow = chanNum * rows + row;
+        unsigned int const len = rleCompress(tempArg, cols);
+            /* writes result into rletemp */
+        unsigned int i;
+        ScanElem * p;
+        
+        channel[chanNum][row].length = len;
+        MALLOCARRAY(p, len);
+        channel[chanNum][row].data = p;
+        for (i = 0; i < len; ++i)
+            p[i] = rletemp[i];
+        table[tabrow] = len * bpc;
+        retval = tempArg;
+    } break;
+    default:
+        pm_error("unknown storage type - can't happen");
+    }
+    return retval;
 }
 
 
+
 static long *
-build_channels(FILE * const ifp, int const cols, int const rows,
-               xelval const maxval, int const format,
-               int const bpc, int const channels)
-{
-    int i, row, col, sgirow;
-    long *table = NULL;
-    ScanElem *temp;
-
-#ifdef DEBUG
-    pm_message("building channels");
-#endif
-
-    if( storage != STORAGE_VERBATIM ) {
+buildChannels(FILE *       const ifP,
+              unsigned int const cols,
+              unsigned int const rows,
+              xelval       const maxval,
+              int          const format,
+              unsigned int const bpc,
+              unsigned int const channels) {
+
+    unsigned int row;
+    unsigned int sgirow;
+    long * table;
+    ScanElem * temp;
+
+    if (storage != STORAGE_VERBATIM) {
         MALLOCARRAY_NOFAIL(table, channels * rows);
         MALLOCARRAY_NOFAIL(rletemp, WORSTCOMPR(cols));
-    }
+    } else
+        table = NULL;
+
     MALLOCARRAY_NOFAIL(temp, cols);
 
-    for( i = 0; i < channels; i++ )
-        MALLOCARRAY_NOFAIL(channel[i], rows);
+    {
+        unsigned int i;
+        for (i = 0; i < channels; ++i)
+            MALLOCARRAY_NOFAIL(channel[i], rows);
+    }
 
-    for( row = 0, sgirow = rows-1; row < rows; row++, sgirow-- ) {
-        pnm_readpnmrow(ifp, pnmrow, cols, maxval, format);
-        if( channels == 1 ) {
-            for( col = 0; col < cols; col++ )
+    for (row = 0, sgirow = rows-1; row < rows; ++row, --sgirow) {
+        pnm_readpnmrow(ifP, pnmrow, cols, maxval, format);
+        if (channels == 1) {
+            unsigned int col;
+            for (col = 0; col < cols; ++col)
                 temp[col] = (ScanElem)PNM_GET1(pnmrow[col]);
             temp = compress(temp, sgirow, rows, cols, 0, table, bpc);
-        }
-        else {
-            for( col = 0; col < cols; col++ )
+        } else {
+            unsigned int col;
+            for (col = 0; col < cols; ++col)
                 temp[col] = (ScanElem)PPM_GETR(pnmrow[col]);
             temp = compress(temp, sgirow, rows, cols, 0, table, bpc);
-            for( col = 0; col < cols; col++ )
+            for (col = 0; col < cols; ++col)
                 temp[col] = (ScanElem)PPM_GETG(pnmrow[col]);
             temp = compress(temp, sgirow, rows, cols, 1, table, bpc);
-            for( col = 0; col < cols; col++ )
+            for (col = 0; col < cols; ++col)
                 temp[col] = (ScanElem)PPM_GETB(pnmrow[col]);
             temp = compress(temp, sgirow, rows, cols, 2, table, bpc);
         }
     }
 
     free(temp);
-    if( table )
+    if (table)
         free(rletemp);
     return table;
 }
 
 
-static ScanElem *
-compress(ScanElem * temp,
-         int const row,  int const rows,
-         int const cols, int const chan_no,
-         long * table, int const bpc)
-{
-    int len, i, tabrow;
-    ScanElem *p;
-
-    switch( storage ) {
-        case STORAGE_VERBATIM:
-            channel[chan_no][row].length = cols;
-            channel[chan_no][row].data = temp;
-            MALLOCARRAY_NOFAIL(temp, cols);
+
+static void
+writeHeader(unsigned int const cols, 
+            unsigned int const rows, 
+            xelval       const maxval, 
+            unsigned int const bpc, 
+            unsigned int const dimensions, 
+            unsigned int const channels, 
+            const char * const imagename) {
+
+    unsigned int i;
+
+    putBigShort(SGI_MAGIC);
+    putByte(storage);
+    putByte((char)bpc);
+    putBigShort(dimensions);
+    putBigShort(cols);
+    putBigShort(rows);
+    putBigShort(channels);
+    putBigLong(0);                /* PIXMIN */
+    putBigLong(maxval);           /* PIXMAX */
+
+    for(i = 0; i < 4; ++i)
+        putByte(0);
+
+    for (i = 0; i < 79 && imagename[i] != '\0'; ++i)
+        putByte(imagename[i]);
+
+    for(; i < 80; ++i)
+        putByte(0);
+
+    putBigLong(CMAP_NORMAL);
+
+    for (i = 0; i < 404; ++i)
+        putByte(0);
+}
+
+
+
+int
+main(int argc,char * argv[]) {
+
+    FILE * ifP;
+    int argn;
+    const char * const usage = "[-verbatim|-rle] [-imagename <name>] [pnmfile]";
+    int cols, rows;
+    int format;
+    xelval maxval, newmaxval;
+    const char * imagename;
+    unsigned int bpc;
+    unsigned int dimensions;
+    unsigned int channels;
+    long * table;
+
+    pnm_init(&argc, argv);
+
+    imagename = "no name";  /* default value */
+    argn = 1;
+    while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
+        if( pm_keymatch(argv[argn], "-verbatim", 2) )
+            storage = STORAGE_VERBATIM;
+        else
+        if( pm_keymatch(argv[argn], "-rle", 2) )
+            storage = STORAGE_RLE;
+        else
+        if( pm_keymatch(argv[argn], "-imagename", 2) ) {
+            if( ++argn >= argc )
+                pm_usage(usage);
+            imagename = argv[argn];
+        }
+        else
+            pm_usage(usage);
+        ++argn;
+    }
+
+    if( argn < argc ) {
+        ifP = pm_openr( argv[argn] );
+        argn++;
+    }
+    else
+        ifP = stdin;
+
+    if( argn != argc )
+        pm_usage(usage);
+
+    pnm_readpnminit(ifP, &cols, &rows, &maxval, &format);
+
+    if (rows > INT16MAX || cols > INT16MAX)
+        pm_error ("Input image is too large.");
+
+    pnmrow = pnm_allocrow(cols);
+    
+    switch (PNM_FORMAT_TYPE(format)) {
+        case PBM_TYPE:
+            pm_message("promoting PBM to PGM");
+            newmaxval = PGM_MAXMAXVAL;
+        case PGM_TYPE:
+            newmaxval = maxval;
+            dimensions = 2;
+            channels = 1;
             break;
-        case STORAGE_RLE:
-            tabrow = chan_no * rows + row;
-            len = rle_compress(temp, cols);    /* writes result into rletemp */
-            channel[chan_no][row].length = len;
-            MALLOCARRAY(p, len);
-            channel[chan_no][row].data = p;
-            for( i = 0; i < len; i++, p++ )
-                *p = rletemp[i];
-            table[tabrow] = len * bpc;
+        case PPM_TYPE:
+            newmaxval = maxval;
+            dimensions = 3;
+            channels = 3;
             break;
         default:
-            pm_error("unknown storage type - can\'t happen");
+            pm_error("can\'t happen");
     }
-    return temp;
-}
+    if (newmaxval <= MAXVAL_BYTE)
+        bpc = 1;
+    else if (newmaxval <= MAXVAL_WORD)
+        bpc = 2;
+    else
+        pm_error("maxval too large - try using \"pnmdepth %u\"", MAXVAL_WORD);
 
+    table = buildChannels(ifP, cols, rows, newmaxval, format, bpc, channels);
 
-/*
-slightly modified RLE algorithm from ppmtoilbm.c
-written by Robert A. Knop (rknop@mop.caltech.edu)
-*/
-static int
-rle_compress(ScanElem * const inbuf, int const size)
-{
-    int in, out, hold, count;
-    ScanElem *outbuf = rletemp;
+    pnm_freerow(pnmrow);
 
-    in=out=0;
-    while( in<size ) {
-        if( (in<size-1) && (inbuf[in]==inbuf[in+1]) ) {     /*Begin replicate run*/
-            for( count=0,hold=in; in<size && inbuf[in]==inbuf[hold] && count<127; in++,count++)
-                ;
-            outbuf[out++]=(ScanElem)(count);
-            outbuf[out++]=inbuf[hold];
-        }
-        else {  /*Do a literal run*/
-            hold=out; out++; count=0;
-            while( ((in>=size-2)&&(in<size)) || ((in<size-2) && ((inbuf[in]!=inbuf[in+1])||(inbuf[in]!=inbuf[in+2]))) ) {
-                outbuf[out++]=inbuf[in++];
-                if( ++count>=127 )
-                    break;
-            }
-            outbuf[hold]=(ScanElem)(count | 0x80);
-        }
-    }
-    outbuf[out++] = (ScanElem)0;     /* terminator */
-    return(out);
+    pm_close(ifP);
+
+    writeHeader(cols, rows, newmaxval, bpc, dimensions, channels, imagename);
+
+    if (table)
+        writeTable(table, rows * channels);
+
+    if (bpc == 1)
+        writeChannels(cols, rows, channels, putShortAsByte);
+    else
+        writeChannels(cols, rows, channels, putBigShort);
+
+    return 0;
 }
 
+