From 1fd361a1ea06e44286c213ca1f814f49306fdc43 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 19 Aug 2006 03:12:28 +0000 Subject: Create Subversion repository git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/other/pnmtorast.c | 310 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 converter/other/pnmtorast.c (limited to 'converter/other/pnmtorast.c') diff --git a/converter/other/pnmtorast.c b/converter/other/pnmtorast.c new file mode 100644 index 00000000..7d1ae05a --- /dev/null +++ b/converter/other/pnmtorast.c @@ -0,0 +1,310 @@ +/* pnmtorast.c - read a portable anymap and produce a Sun rasterfile +** +** Copyright (C) 1989, 1991 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "pnm.h" +#include "rast.h" +#include "mallocvar.h" + +#define MAXCOLORS 256 +static colormap_t* make_pr_colormap ARGS(( colorhist_vector chv, int colors )); +static colormap_t* make_gray_pr_colormap ARGS(( void )); +static colormap_t* alloc_pr_colormap ARGS(( void )); + +int +main( argc, argv ) + int argc; + char* argv[]; +{ + FILE* ifp; + xel** xels; + xel* xelrow; + 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; + xelval maxval; + struct pixrect* pr; + unsigned char* data; + register unsigned char* byteP; + const char* const usage = "[-standard|-rle] [pnmfile]"; + + pnm_init( &argc, argv ); + + argn = 1; + pr_type = RT_BYTE_ENCODED; + + while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) + { + if ( pm_keymatch( argv[argn], "-standard", 2 ) ) + pr_type = RT_STANDARD; + else if ( pm_keymatch( argv[argn], "-rle", 2 ) ) + pr_type = RT_BYTE_ENCODED; + else + pm_usage( usage ); + ++argn; + } + + if ( argn != argc ) + { + ifp = pm_openr( argv[argn] ); + ++argn; + } + else + ifp = stdin; + + if ( argn != argc ) + pm_usage( usage ); + + xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format ); + + pm_close( ifp ); + + /* Figure out the proper depth and colormap. */ + 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( + "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 ); + 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 ); + + /* 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. */ + depth = 1; + pr_colormapP = (colormap_t*) 0; + } + else + { + /* Turn the ppm colormap into the appropriate Sun colormap. */ + depth = 8; + pr_colormapP = make_pr_colormap( chv, colors ); + } + cht = ppm_colorhisttocolorhash( chv, colors ); + ppm_freecolorhist( chv ); + } + + break; + + case PGM_TYPE: + depth = 8; + pr_colormapP = make_gray_pr_colormap( ); + break; + + default: + depth = 1; + pr_colormapP = (colormap_t*) 0; + break; + } + + if ( maxval > 255 && depth != 1 ) + pm_message( + "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; + + 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; + + default: + pm_error( "can't happen" ); + } + data += linesize; + } + 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" ); + + exit( 0 ); +} + +static colormap_t* +make_pr_colormap( chv, colors ) + colorhist_vector chv; + int colors; +{ + colormap_t* pr_colormapP; + int i; + + pr_colormapP = alloc_pr_colormap( ); + + 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 < MAXCOLORS; ++i ) + pr_colormapP->map[0][i] = pr_colormapP->map[1][i] = + pr_colormapP->map[2][i] = 0; + + return pr_colormapP; +} + +static colormap_t* +make_gray_pr_colormap( ) +{ + colormap_t* pr_colormapP; + int i; + + pr_colormapP = alloc_pr_colormap( ); + + for ( i = 0; i < MAXCOLORS; ++i ) + { + pr_colormapP->map[0][i] = i; + pr_colormapP->map[1][i] = i; + pr_colormapP->map[2][i] = i; + } + + return pr_colormapP; +} + +static colormap_t* +alloc_pr_colormap( ) +{ + 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; +} -- cgit 1.4.1