diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2014-06-29 19:32:13 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2014-06-29 19:32:13 +0000 |
commit | 51eb5e0d2722f0cf1033ac158d2fdbcd82b6e800 (patch) | |
tree | 3b763ebf105fc1136ebcac13b7d4dafca114be68 /converter/other/pnmtosgi.c | |
parent | 1610a1f6aa54ad1d97926c1d8605720933059df7 (diff) | |
download | netpbm-mirror-51eb5e0d2722f0cf1033ac158d2fdbcd82b6e800.tar.gz netpbm-mirror-51eb5e0d2722f0cf1033ac158d2fdbcd82b6e800.tar.xz netpbm-mirror-51eb5e0d2722f0cf1033ac158d2fdbcd82b6e800.zip |
Reverse messed up commit
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@2222 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pnmtosgi.c')
-rw-r--r-- | converter/other/pnmtosgi.c | 512 |
1 files changed, 238 insertions, 274 deletions
diff --git a/converter/other/pnmtosgi.c b/converter/other/pnmtosgi.c index a8df5328..169125b3 100644 --- a/converter/other/pnmtosgi.c +++ b/converter/other/pnmtosgi.c @@ -31,6 +31,17 @@ 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) @@ -44,348 +55,301 @@ 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)) -static void -putBigShort(short const s) { +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; - if (pm_writebigshort(stdout, s ) == -1) - pm_error( "write error" ); -} + pnm_init(&argc, argv); + 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; -static void -putBigLong(long const l) { + if( argn != argc ) + pm_usage(usage); - if (pm_writebiglong( stdout, l ) == -1) - pm_error( "write error" ); -} + 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: + 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); -static void -putShortAsByte(short const s) { + table = build_channels(ifp, cols, rows, newmaxval, format, bpc, channels); + pnm_freerow(pnmrow); + pm_close(ifp); - putByte((unsigned char)s); -} + 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); + exit(0); +} static void -writeTable(long * const table, - unsigned int const tabsize) { +write_table(long * table, int const tabsize) +{ + int i; + long offset; - unsigned int i; - unsigned long offset; +#ifdef DEBUG + pm_message("writing table"); +#endif offset = HeaderSize + tabsize * 8; - - for (i = 0; i < tabsize; ++i) { - putBigLong(offset); + for( i = 0; i < tabsize; i++ ) { + put_big_long(offset); offset += table[i]; } - for (i = 0; i < tabsize; ++i) - putBigLong(table[i]); + for( i = 0; i < tabsize; i++ ) + put_big_long(table[i]); } - static void -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) { +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++ ) { (*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 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_big_long(long const l) +{ + if ( pm_writebiglong( stdout, l ) == -1 ) + pm_error( "write error" ); } - -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 void +put_short_as_byte(short const s) +{ + put_byte((unsigned char)s); } - static long * -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) { +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 ) { MALLOCARRAY_NOFAIL(table, channels * rows); MALLOCARRAY_NOFAIL(rletemp, WORSTCOMPR(cols)); - } else - table = NULL; - + } MALLOCARRAY_NOFAIL(temp, cols); - { - unsigned int i; - for (i = 0; i < channels; ++i) - MALLOCARRAY_NOFAIL(channel[i], rows); - } + 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) { - unsigned int col; - 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 ) { + for( col = 0; col < cols; col++ ) temp[col] = (ScanElem)PNM_GET1(pnmrow[col]); temp = compress(temp, sgirow, rows, cols, 0, table, bpc); - } else { - unsigned int col; - for (col = 0; col < cols; ++col) + } + else { + 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 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; +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); break; - case PPM_TYPE: - newmaxval = maxval; - dimensions = 3; - channels = 3; + 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; break; default: - pm_error("can\'t happen"); + pm_error("unknown storage type - 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 %u\"", MAXVAL_WORD); - - table = buildChannels(ifP, cols, rows, newmaxval, format, bpc, channels); - - pnm_freerow(pnmrow); - - pm_close(ifP); - - writeHeader(cols, rows, newmaxval, bpc, dimensions, channels, imagename); + return temp; +} - if (table) - writeTable(table, rows * channels); - if (bpc == 1) - writeChannels(cols, rows, channels, putShortAsByte); - else - writeChannels(cols, rows, channels, putBigShort); +/* +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; - return 0; + 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); } - |