diff options
Diffstat (limited to 'converter/other/rasttopnm.c')
-rw-r--r-- | converter/other/rasttopnm.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/converter/other/rasttopnm.c b/converter/other/rasttopnm.c new file mode 100644 index 00000000..aa55850b --- /dev/null +++ b/converter/other/rasttopnm.c @@ -0,0 +1,263 @@ +/* rasttopnm.c - read a Sun rasterfile and produce a portable anymap +** +** 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" + +int +main( argc, argv ) + int argc; + char* argv[]; + { + FILE* ifp; + struct rasterfile header; + colormap_t pr_colormap; + int grayscale; + struct pixrect* pr; + xel* xelrow; + register xel* xP; + int argn, rows, cols, format, depth, i, row, mask; + register int col; + xelval maxval; + xel zero, one; + int linesize; + unsigned char* data; + unsigned char* byteP; + + pnm_init( &argc, argv ); + + argn = 1; + + if ( argn != argc ) + { + ifp = pm_openr( argv[argn] ); + ++argn; + } + else + ifp = stdin; + + if ( argn != argc ) + pm_usage( "[rastfile]" ); + + /* Read in the rasterfile. First the header. */ + if ( pr_load_header( ifp, &header ) != 0 ) + pm_error( "unable to read in rasterfile header" ); + + cols = header.ras_width; + rows = header.ras_height; + depth = header.ras_depth; + + if ( cols <= 0 ) + pm_error( "invalid cols: %d", cols ); + if ( rows <= 0 ) + pm_error( "invalid rows: %d", rows ); + + /* If there is a color map, read it. */ + grayscale = 1; + if ( header.ras_maplength != 0 ) + { + if ( pr_load_colormap( ifp, &header, &pr_colormap ) != 0 ) + pm_error( "unable to skip colormap data" ); + for ( i = 0; i < header.ras_maplength / 3; ++i ) + if ( pr_colormap.map[0][i] != pr_colormap.map[1][i] || + pr_colormap.map[1][i] != pr_colormap.map[2][i] ) + { + grayscale = 0; + break; + } + } + + /* Check the depth and color map. */ + switch ( depth ) + { + case 1: + if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 ) + { + maxval = 1; + format = PBM_TYPE; + PNM_ASSIGN1( zero, maxval ); + PNM_ASSIGN1( one, 0 ); + } + else if ( header.ras_maptype == RMT_EQUAL_RGB && + header.ras_maplength == 6 ) + { + if ( grayscale ) + { + maxval = 255; + format = PGM_TYPE; + PNM_ASSIGN1( zero, pr_colormap.map[0][0] ); + PNM_ASSIGN1( one, pr_colormap.map[0][1] ); + } + else + { + maxval = 255; + format = PPM_TYPE; + PPM_ASSIGN( + zero, pr_colormap.map[0][0], pr_colormap.map[1][0], + pr_colormap.map[2][0] ); + PPM_ASSIGN( + one, pr_colormap.map[0][1], pr_colormap.map[1][1], + pr_colormap.map[2][1] ); + } + } + else + pm_error( + "this depth-1 rasterfile has a non-standard colormap - " + "type %ld length %ld", + header.ras_maptype, header.ras_maplength ); + break; + + case 8: + if ( grayscale ) + { + maxval = 255; + format = PGM_TYPE; + } + else if ( header.ras_maptype == RMT_EQUAL_RGB ) + { + maxval = 255; + format = PPM_TYPE; + } + else + pm_error( + "this depth-8 rasterfile has a non-standard colormap - " + "type %ld length %ld", + header.ras_maptype, header.ras_maplength ); + break; + + case 24: + case 32: + if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 ) + ; + else if ( header.ras_maptype == RMT_RAW || header.ras_maplength == 768 ) + ; + else + pm_error( + "this depth-%d rasterfile has a non-standard colormap - " + "type %ld length %ld", + depth, header.ras_maptype, header.ras_maplength ); + maxval = 255; + format = PPM_TYPE; + break; + + default: + pm_error( + "invalid depth: %d. Can only handle depth 1, 8, 24, or 32.", + depth ); + } + + /* Now load the data. The pixrect returned is a memory pixrect. */ + if ( ( pr = pr_load_image( ifp, &header, NULL ) ) == NULL ) + pm_error( + "unable to read in the image from the rasterfile" ); + + linesize = ( (struct mpr_data*) pr->pr_data )->md_linebytes; + data = ( (struct mpr_data*) pr->pr_data )->md_image; + + pm_close( ifp ); + + /* Now write out the anymap. */ + pnm_writepnminit( stdout, cols, rows, maxval, format, 0 ); + xelrow = pnm_allocrow( cols ); + switch ( PNM_FORMAT_TYPE(format) ) + { + case PBM_TYPE: + pm_message( "writing PBM file" ); + break; + + case PGM_TYPE: + pm_message( "writing PGM file" ); + break; + + case PPM_TYPE: + pm_message( "writing PPM file" ); + break; + + default: + pm_error( "shouldn't happen" ); + } + + for ( row = 0; row < rows; ++row ) + { + byteP = data; + switch ( depth ) + { + case 1: + mask = 0x80; + for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) + { + if ( mask == 0 ) + { + ++byteP; + mask = 0x80; + } + *xP = ( *byteP & mask ) ? one : zero; + mask = mask >> 1; + } + break; + + case 8: + for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) + { + if ( header.ras_maplength == 0 ) + PNM_ASSIGN1( *xP, *byteP ); + else if ( grayscale ) + PNM_ASSIGN1( *xP, pr_colormap.map[0][*byteP] ); + else + PPM_ASSIGN( + *xP, pr_colormap.map[0][*byteP], + pr_colormap.map[1][*byteP], + pr_colormap.map[2][*byteP] ); + ++byteP; + } + break; + + case 24: + case 32: + for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) + { + register xelval r, g, b; + + if ( depth == 32 ) + ++byteP; + if ( header.ras_type == RT_FORMAT_RGB ) + { + r = *byteP++; + g = *byteP++; + b = *byteP++; + } + else + { + b = *byteP++; + g = *byteP++; + r = *byteP++; + } + if ( header.ras_maplength == 0 ) + PPM_ASSIGN( *xP, r, g, b ); + else + PPM_ASSIGN( + *xP, pr_colormap.map[0][r], pr_colormap.map[1][g], + pr_colormap.map[2][b] ); + } + break; + + default: + pm_error( "can't happen" ); + } + data += linesize; + pnm_writepnmrow( stdout, xelrow, cols, maxval, format, 0 ); + } + + pm_close( stdout ); + + exit( 0 ); + } |