diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-03-28 01:55:27 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-03-28 01:55:27 +0000 |
commit | 200553b6135e1ba6a4b6585e3d07d934ba6b8ceb (patch) | |
tree | 0d7a730843db22ff539ed39feddd3b7d3e4541f1 /converter/other/pnmtorast.c | |
parent | 5240773e57f21c778d227fd14a3720006f70c83e (diff) | |
download | netpbm-mirror-200553b6135e1ba6a4b6585e3d07d934ba6b8ceb.tar.gz netpbm-mirror-200553b6135e1ba6a4b6585e3d07d934ba6b8ceb.tar.xz netpbm-mirror-200553b6135e1ba6a4b6585e3d07d934ba6b8ceb.zip |
Update advanced series to 10.62
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@1869 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pnmtorast.c')
-rw-r--r-- | converter/other/pnmtorast.c | 501 |
1 files changed, 294 insertions, 207 deletions
diff --git a/converter/other/pnmtorast.c b/converter/other/pnmtorast.c index 605e815c..e11d3cb7 100644 --- a/converter/other/pnmtorast.c +++ b/converter/other/pnmtorast.c @@ -19,103 +19,285 @@ static colormap_t * -alloc_pr_colormap(void) { - - colormap_t* pr_colormapP; - - MALLOCVAR(pr_colormapP); - if ( pr_colormapP == NULL ) - pm_error( "out of memory" ); - pr_colormapP->type = RMT_EQUAL_RGB; - pr_colormapP->length = MAXCOLORS; - MALLOCARRAY(pr_colormapP->map[0], MAXCOLORS); - MALLOCARRAY(pr_colormapP->map[1], MAXCOLORS); - MALLOCARRAY(pr_colormapP->map[2], MAXCOLORS); - if ( pr_colormapP->map[0] == NULL || - pr_colormapP->map[1] == NULL || - pr_colormapP->map[2] == NULL ) - pm_error( "out of memory" ); - - return pr_colormapP; +allocPrColormap(void) { + + colormap_t * prColormapP; + + MALLOCVAR(prColormapP); + if (prColormapP == NULL) + pm_error("out of memory"); + prColormapP->type = RMT_EQUAL_RGB; + prColormapP->length = MAXCOLORS; + MALLOCARRAY(prColormapP->map[0], MAXCOLORS); + MALLOCARRAY(prColormapP->map[1], MAXCOLORS); + MALLOCARRAY(prColormapP->map[2], MAXCOLORS); + if (prColormapP->map[0] == NULL || + prColormapP->map[1] == NULL || + prColormapP->map[2] == NULL) + pm_error("out of memory"); + + return prColormapP; } -static colormap_t* -make_pr_colormap(colorhist_vector const chv, - int const colors) { +static colormap_t * +makePrColormap(colorhist_vector const chv, + unsigned int const colors) { - colormap_t* pr_colormapP; - int i; + colormap_t * prColormapP; + unsigned int i; - pr_colormapP = alloc_pr_colormap( ); + prColormapP = allocPrColormap(); - for ( i = 0; i < colors; ++i ) - { - pr_colormapP->map[0][i] = PPM_GETR( chv[i].color ); - pr_colormapP->map[1][i] = PPM_GETG( chv[i].color ); - pr_colormapP->map[2][i] = PPM_GETB( chv[i].color ); + for (i = 0; i < colors; ++i) { + prColormapP->map[0][i] = PPM_GETR(chv[i].color); + prColormapP->map[1][i] = PPM_GETG(chv[i].color); + prColormapP->map[2][i] = PPM_GETB(chv[i].color); } - for ( ; i < MAXCOLORS; ++i ) - pr_colormapP->map[0][i] = pr_colormapP->map[1][i] = - pr_colormapP->map[2][i] = 0; - - return pr_colormapP; + for ( ; i < MAXCOLORS; ++i) { + prColormapP->map[0][i] = 0; + prColormapP->map[1][i] = 0; + prColormapP->map[2][i] = 0; + } + return prColormapP; } static colormap_t * -make_gray_pr_colormap(void) { +makeGrayPrColormap(void) { - colormap_t* pr_colormapP; - int i; + colormap_t * prColormapP; + unsigned int i; - pr_colormapP = alloc_pr_colormap( ); + prColormapP = allocPrColormap(); - for ( i = 0; i < MAXCOLORS; ++i ) - { - pr_colormapP->map[0][i] = i; - pr_colormapP->map[1][i] = i; - pr_colormapP->map[2][i] = i; + for (i = 0; i < MAXCOLORS; ++i) { + prColormapP->map[0][i] = i; + prColormapP->map[1][i] = i; + prColormapP->map[2][i] = i; + } + + return prColormapP; +} + + + +static void +doRowDepth1(const xel * const xelrow, + unsigned char * const rastRow, + unsigned int const cols, + int const format, + xelval const maxval, + colorhash_table const cht, + unsigned int * const lenP) { + + unsigned int col; + int bitcount; + unsigned int cursor; + + cursor = 0; + + rastRow[cursor] = 0; + bitcount = 7; + + for (col = 0; col < cols; ++col) { + switch (PNM_FORMAT_TYPE(format)) { + case PPM_TYPE: { + xel adjustedXel; + int color; + if (maxval != 255) + PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255 ); + color = ppm_lookupcolor(cht, &adjustedXel); + if (color == -1) + pm_error("color not found?!? " + "col=%u r=%u g=%u b=%u", + col, + PPM_GETR(adjustedXel), + PPM_GETG(adjustedXel), + PPM_GETB(adjustedXel)); + if (color) + rastRow[cursor] |= 1 << bitcount; + } break; + + default: { + int const color = PNM_GET1(xelrow[col]); + if (!color) + rastRow[cursor] |= 1 << bitcount; + break; + } + } + --bitcount; + if (bitcount < 0) { + ++cursor; + rastRow[cursor] = 0; + bitcount = 7; + } + } + *lenP = cursor; +} + + + +static void +doRowDepth8(const xel * const xelrow, + unsigned char * const rastRow, + unsigned int const cols, + int const format, + xelval const maxval, + colorhash_table const cht, + unsigned int * const lenP) { + + unsigned int col; + unsigned int cursor; + + for (col = 0, cursor = 0; col < cols; ++col) { + int color; /* color index of pixel or -1 if not in 'cht' */ + + switch (PNM_FORMAT_TYPE(format)) { + case PPM_TYPE: { + xel adjustedXel; + + if (maxval == 255) + adjustedXel = xelrow[col]; + else + PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255); + + color = ppm_lookupcolor(cht, &adjustedXel); + if (color == -1) + pm_error("color not found?!? " + "col=%u r=%u g=%u b=%u", + col, + PPM_GETR(adjustedXel), + PPM_GETG(adjustedXel), + PPM_GETB(adjustedXel)); + } break; + + case PGM_TYPE: { + int const rawColor = PNM_GET1(xelrow[col]); + + color = maxval == 255 ? rawColor : rawColor * 255 / maxval; + + } break; + + default: + color = PNM_GET1(xelrow[col]); + } + rastRow[cursor++] = color; } + *lenP = cursor; +} + - return pr_colormapP; + + +static void +doRowDepth24(const xel * const xelrow, + unsigned char * const rastRow, + unsigned int const cols, + int const format, + xelval const maxval, + unsigned int * const lenP) { + + /* Since depth is 24, we do NOT have a valid cht. */ + + unsigned int col; + unsigned int cursor; + + for (col = 0, cursor = 0; col < cols; ++col) { + xel adjustedXel; + + if (maxval == 255) + adjustedXel = xelrow[col]; + else + PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255); + + rastRow[cursor++] = PPM_GETB(adjustedXel); + rastRow[cursor++] = PPM_GETG(adjustedXel); + rastRow[cursor++] = PPM_GETR(adjustedXel); + } + *lenP = cursor; +} + + + +static void +computeRaster(unsigned char * const rastRaster, + unsigned int const lineSize, + unsigned int const depth, + unsigned int const cols, + unsigned int const rows, + int const format, + xelval const maxval, + xel ** const xels, + colorhash_table const cht) { + + unsigned int row; + unsigned char * rastRow; + + for (row = 0, rastRow = &rastRaster[0]; row < rows; ++row) { + xel * const xelrow = xels[row]; + + unsigned int len; /* Number of bytes of rast data added to rastRow[] */ + + switch (depth) { + case 1: + doRowDepth1(xelrow, rastRow, cols, format, maxval, cht, &len); + break; + case 8: + doRowDepth8(xelrow, rastRow, cols, format, maxval, cht, &len); + break; + case 24: + doRowDepth24(xelrow, rastRow, cols, format, maxval, &len); + break; + default: + pm_error("INTERNAL ERROR: impossible depth %u", depth); + } + { + /* Pad out the line (which has a rounded size) with zeroes so + the resulting file is repeatable. + */ + unsigned int i; + for (i = len; i < lineSize; ++i) + rastRow[i] = 0; + } + rastRow += lineSize; + } } int -main(int argc, char ** argv) { +main(int argc, const char ** argv) { - FILE* ifp; - xel** xels; - xel* xelrow; + FILE * ifP; + xel ** xels; xel p; - register xel* xP; colorhist_vector chv; colorhash_table cht; - colormap_t* pr_colormapP; - int argn, pr_type, rows, cols, format, i; - int depth, colors, linesize, row; - register int col, bitcount; + colormap_t * prColormapP; + int argn; + int prType; + int rows, cols; + int format; + unsigned int depth; + int colorCt; xelval maxval; - struct pixrect* pr; - unsigned char* data; - register unsigned char* byteP; - const char* const usage = "[-standard|-rle] [pnmfile]"; + struct pixrect * prP; + const char * const usage = "[-standard|-rle] [pnmfile]"; - pnm_init( &argc, argv ); + pm_proginit(&argc, argv); argn = 1; - pr_type = RT_BYTE_ENCODED; + prType = RT_BYTE_ENCODED; while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) { if ( pm_keymatch( argv[argn], "-standard", 2 ) ) - pr_type = RT_STANDARD; + prType = RT_STANDARD; else if ( pm_keymatch( argv[argn], "-rle", 2 ) ) - pr_type = RT_BYTE_ENCODED; + prType = RT_BYTE_ENCODED; else pm_usage( usage ); ++argn; @@ -123,191 +305,96 @@ main(int argc, char ** argv) { if ( argn != argc ) { - ifp = pm_openr( argv[argn] ); + ifP = pm_openr( argv[argn] ); ++argn; } else - ifp = stdin; + ifP = stdin; if ( argn != argc ) pm_usage( usage ); - xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format ); + xels = pnm_readpnm(ifP, &cols, &rows, &maxval, &format); - pm_close( ifp ); + pm_close(ifP); /* Figure out the proper depth and colormap. */ - switch ( PNM_FORMAT_TYPE(format) ) - { + switch (PNM_FORMAT_TYPE(format)) { case PPM_TYPE: - pm_message( "computing colormap..." ); - chv = ppm_computecolorhist( xels, cols, rows, MAXCOLORS, &colors ); - if ( chv == (colorhist_vector) 0 ) - { + pm_message("computing colormap..."); + chv = ppm_computecolorhist(xels, cols, rows, MAXCOLORS, &colorCt); + if (!chv) { pm_message( - "Too many colors - proceeding to write a 24-bit non-mapped" ); + "Too many colors - proceeding to write a 24-bit non-mapped"); pm_message( "rasterfile. If you want 8 bits, try doing a 'pnmquant %d'.", - MAXCOLORS ); + MAXCOLORS); depth = 24; - pr_type = RT_STANDARD; - pr_colormapP = (colormap_t*) 0; - } - else - { - pm_message( "%d colors found", colors ); - - if ( maxval != 255 ) - for ( i = 0; i < colors; ++i ) - PPM_DEPTH( chv[i].color, chv[i].color, maxval, 255 ); - + prType = RT_STANDARD; + prColormapP = NULL; + } else { + pm_message("%u colors found", colorCt); + + if (maxval != 255) { + unsigned int i; + for (i = 0; i < colorCt; ++i) + PPM_DEPTH(chv[i].color, chv[i].color, maxval, 255); + } /* Force white to slot 0 and black to slot 1, if possible. */ - PPM_ASSIGN( p, 255, 255, 255 ); - ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 0 ); - PPM_ASSIGN( p, 0, 0, 0 ); - ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 1 ); - - if ( colors == 2 ) - { - /* Monochrome. */ + PPM_ASSIGN(p, 255, 255, 255); + ppm_addtocolorhist(chv, &colorCt, MAXCOLORS, &p, 0, 0); + PPM_ASSIGN(p, 0, 0, 0); + ppm_addtocolorhist(chv, &colorCt, MAXCOLORS, &p, 0, 1); + + if (colorCt == 2) { + /* Monochrome */ depth = 1; - pr_colormapP = (colormap_t*) 0; - } - else - { + prColormapP = NULL; + } else { /* Turn the ppm colormap into the appropriate Sun colormap. */ depth = 8; - pr_colormapP = make_pr_colormap( chv, colors ); + prColormapP = makePrColormap(chv, colorCt); } - cht = ppm_colorhisttocolorhash( chv, colors ); - ppm_freecolorhist( chv ); + cht = ppm_colorhisttocolorhash(chv, colorCt); + ppm_freecolorhist(chv); } break; case PGM_TYPE: depth = 8; - pr_colormapP = make_gray_pr_colormap( ); + prColormapP = makeGrayPrColormap(); break; default: depth = 1; - pr_colormapP = (colormap_t*) 0; + prColormapP = NULL; break; } - if ( maxval > 255 && depth != 1 ) + if (maxval > 255 && depth != 1) pm_message( - "maxval is not 255 - automatically rescaling colors" ); + "maxval is not 255 - automatically rescaling colors"); /* Allocate space for the Sun-format image. */ - if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect*) 0 ) - pm_error( "unable to create new pixrect" ); - data = ( (struct mpr_data*) pr->pr_data )->md_image; - linesize = ( (struct mpr_data*) pr->pr_data )->md_linebytes; - - /* And compute the Sun image. The variables at this point are: - ** cht is null or not - ** depth is 1, 8, or 24 - */ - for ( row = 0; row < rows; ++row ) - { - xelrow = xels[row]; - byteP = data; - switch ( depth ) - { - case 1: - *byteP = 0; - bitcount = 7; - for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) - { - register int color; - - switch ( PNM_FORMAT_TYPE(format) ) - { - case PPM_TYPE: - if ( maxval != 255 ) - PPM_DEPTH( *xP, *xP, maxval, 255 ); - color = ppm_lookupcolor( cht, xP ); - if ( color == -1 ) - pm_error( - "color not found?!? row=%d col=%d r=%d g=%d b=%d", - row, col, PPM_GETR(*xP), PPM_GETG(*xP), - PPM_GETB(*xP) ); - if ( color ) - *byteP |= 1 << bitcount; - break; - - default: - color = PNM_GET1( *xP ); - if ( ! color ) - *byteP |= 1 << bitcount; - break; - } - --bitcount; - if ( bitcount < 0 ) - { - ++byteP; - *byteP = 0; - bitcount = 7; - } - } - break; - - case 8: - for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) - { - register int color; - - switch ( PNM_FORMAT_TYPE(format) ) - { - case PPM_TYPE: - if ( maxval != 255 ) - PPM_DEPTH( *xP, *xP, maxval, 255 ); - color = ppm_lookupcolor( cht, xP ); - if ( color == -1 ) - pm_error( - "color not found?!? row=%d col=%d r=%d g=%d b=%d", - row, col, PPM_GETR(*xP), PPM_GETG(*xP), - PPM_GETB(*xP) ); - break; - - case PGM_TYPE: - color = PNM_GET1( *xP ); - if ( maxval != 255 ) - color = color * 255 / maxval; - break; - - default: - color = PNM_GET1( *xP ); - } - *byteP++ = color; - } - break; + prP = mem_create(cols, rows, depth); + if (!prP) + pm_error("unable to create new pixrect"); - case 24: - /* If depth is 24, we do NOT have a valid cht. */ - for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) - { - if ( maxval != 255 ) - PPM_DEPTH( *xP, *xP, maxval, 255 ); - *byteP++ = PPM_GETB( *xP ); - *byteP++ = PPM_GETG( *xP ); - *byteP++ = PPM_GETR( *xP ); - } - break; + computeRaster(prP->pr_data->md_image, + prP->pr_data->md_linebytes, + depth, + cols, rows, format, maxval, xels, cht); - default: - pm_error( "can't happen" ); - } - data += linesize; - } - pnm_freearray( xels, rows ); + pnm_freearray(xels, rows); - /* Finally, write the sucker out. */ - if ( pr_dump( pr, stdout, pr_colormapP, pr_type, 0 ) == PIX_ERR ) - pm_error( "error writing rasterfile" ); + { + int rc; - exit( 0 ); + rc = pr_dump(prP, stdout, prColormapP, prType, 0); + if (rc == PIX_ERR ) + pm_error("error writing rasterfile"); + } + return 0; } |