This is rastorle.c in view mode; [Download] [Up]
/* * This software is copyrighted as noted below. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* * rastorle -- * convert Sun Rasterfile to Utah RLE format * reads Sun rasterfile or stdin and writes stdout. * * Author: Berry Kercheval (berry@mordor.s1.gov) * Lawrence Livermore National Laboratory * Livermore, CA. * Date: 9 March 1987 * History: * 27 March 1987: bbk: make it understand depth one (B&W) rasterfiles. * 6 September 1990: Clark: make it understand RT_BYTE_ENCODED rasterfiles, * add flag so alpha channel is done only if desired, * and output a colormap for images of depth 8. * * Usage is: * rastorle [-a] [-o outfile.rle] [ infile.ras ] * (optionally) | rleflip -v > out.rle * * -a Fake an alpha channel. * * (The flip is necessary because Sun numbers the rows differently.) * * This will be difficult to compile on a non-sun, as it uses the pixrect * library include files. */ #include <stdio.h> #include <pixrect/pixrect_hs.h> #include <sysexits.h> #include "rle.h" #define MAXLINE 1280 /* max width of a line */ #define MAXVAL 255 /* max value for pixel */ #define CMAPSIZE 256 /* Max size of color map */ #define ESCAPE 128 /* Escape value for RT_BYTE_ENCODED rasterfiles */ /* #define DEBUG /* debug output turned on */ int getbit(); static rle_map out_map[3*(1<<8)]; unsigned char *outrows[4]; /* array of rows for RLE output */ unsigned char redline[MAXLINE], /* rle red row values */ grnline[MAXLINE], bluline[MAXLINE], alfline[MAXLINE]; /* alpha channel values */ unsigned char red[CMAPSIZE], /* red colormap entries */ green[CMAPSIZE], /* Green ditto */ blue[CMAPSIZE]; /* see a pattern? */ void main(argc, argv) int argc; char *argv[]; { char *outfname = NULL; char *infname = NULL; int flag = 0, aflag = 0, oflag = 0; FILE *rasfile; /* where input comes from */ FILE *outfile; /* where output goes to */ int i; /* useful index */ int p; /* pixel value read from a file -- * used to index rasterfile color map. */ int count; /* Holds current byte count for rasterfiles * of type RT_BYTE_ENCODED */ int h; /* index for looping along a row */ struct rasterfile rashdr; /* standard header of a Sun rasterfile*/ if ( scanargs( argc, argv, "% a%- o%-outfile!s infile%s", &aflag, &oflag, &outfname, &infname ) == 0 ) exit( EX_USAGE ); rasfile = rle_open_f( "rastorle", infname, "r" ); outfile = rle_open_f( "rastorle", outfname, "w" ); rle_addhist( argv, (rle_hdr *)NULL, &rle_dflt_hdr ); /* first read the rasterfile header */ if(fread(&rashdr, sizeof(rashdr), 1, rasfile) != 1) { fprintf(stderr, "Can't read rasterfile header.\n"); exit(EX_DATAERR); } /* it has to start with the magic number... */ if (rashdr.ras_magic != RAS_MAGIC) { fprintf(stderr, "Error: \"%s\" is not a rasterfile.\n", rasfile==stdin?"stdin":argv[1]); exit(EX_DATAERR); } #ifdef DEBUG fprintf (stderr, "rasterfile width = %d\n", rashdr.ras_width); fprintf (stderr, "rasterfile height = %d\n", rashdr.ras_height); fprintf (stderr, "rasterfile depth = %d\n", rashdr.ras_depth); fprintf (stderr, "rasterfile length = %d\n", rashdr.ras_length); fprintf (stderr, "rasterfile type = %d\n", rashdr.ras_type); fprintf (stderr, "rasterfile maplength = %d\n", rashdr.ras_maplength); #endif /* read in color map */ switch(rashdr.ras_maptype) { case RMT_NONE: #ifdef DEBUG fprintf (stderr, "No color map\n"); #endif for (i = 0; i < 256; i++) red[i] = green[i] = blue[i] = i ; break; case RMT_RAW: #ifdef DEBUG fprintf (stderr, "Raw color map\n"); #endif for (i = 0; i < 256; i++) red[i] = green[i] = blue[i] = i ; for (i = 0; i < rashdr.ras_maplength; i++) getc(rasfile); break; case RMT_EQUAL_RGB: #ifdef DEBUG fprintf (stderr, "RGB color map\n"); #endif /* read red */ for (i = 0; i < rashdr.ras_maplength/3; i++) red[i] = getc(rasfile); /* read green */ for (i = 0; i < rashdr.ras_maplength/3; i++) green[i] = getc(rasfile); /* read blue */ for (i = 0; i < rashdr.ras_maplength/3; i++) blue[i] = getc(rasfile); break; default: fprintf (stderr, "Unknown color map type (%d)\n", rashdr.ras_maptype); exit (EX_DATAERR); } /* we need to work on this... */ switch(rashdr.ras_depth) { default: fprintf(stderr, "Sorry, I can't deal with a rasterfile depth %d\n",rashdr.ras_depth); break; case 1: /* black & white */ /* next few lines stolen from painttorle.c */ RLE_SET_BIT(rle_dflt_hdr, RLE_RED); RLE_SET_BIT(rle_dflt_hdr, RLE_GREEN); RLE_SET_BIT(rle_dflt_hdr, RLE_BLUE); if ( aflag ) RLE_SET_BIT(rle_dflt_hdr, RLE_ALPHA ); else RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA ); rle_dflt_hdr.rle_file = outfile; rle_dflt_hdr.xmin = 0 ; rle_dflt_hdr.xmax = rashdr.ras_width-1; rle_dflt_hdr.ymin = 0 ; rle_dflt_hdr.ymax = rashdr.ras_height-1; rle_dflt_hdr.ncmap = 0 ; if ( aflag ) rle_dflt_hdr.alpha = 1; else rle_dflt_hdr.alpha = 0; outrows[0] = alfline; /* all three can have the same value since it's B&W */ outrows[1] = redline; outrows[2] = redline; outrows[3] = redline; rle_put_setup( &rle_dflt_hdr ); for (i=0; i<rashdr.ras_height; i++) { for(h = 0; h < rashdr.ras_width; h++) { p = getbit(rasfile, 0); redline[h] = p?0:MAXVAL; if ( aflag ) alfline[h] = p?0:MAXVAL; } /* write a line to the rle file */ rle_putrow(&outrows[1], rashdr.ras_width, &rle_dflt_hdr); getbit(NULL, 1); } break; /* end case 1: */ case 8: case 24: case 32: /* next few lines stolen from painttorle.c */ RLE_SET_BIT(rle_dflt_hdr, RLE_RED); RLE_SET_BIT(rle_dflt_hdr, RLE_GREEN); RLE_SET_BIT(rle_dflt_hdr, RLE_BLUE); if ( aflag || rashdr.ras_depth == 32 ) RLE_SET_BIT(rle_dflt_hdr, RLE_ALPHA ); else RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA ); rle_dflt_hdr.rle_file = outfile; rle_dflt_hdr.xmin = 0 ; rle_dflt_hdr.xmax = rashdr.ras_width-1; rle_dflt_hdr.ymin = 0 ; rle_dflt_hdr.ymax = rashdr.ras_height-1; if ( aflag || rashdr.ras_depth == 32 ) rle_dflt_hdr.alpha = 1; else rle_dflt_hdr.alpha = 0; if (rashdr.ras_depth == 8) { rle_dflt_hdr.ncolors = 1; rle_dflt_hdr.ncmap = 3; rle_dflt_hdr.cmaplen = 8; rle_dflt_hdr.cmap = out_map; for (i=0;i<(1<<8);i++) { out_map[i+(0<<8)] = red[i] << 8; out_map[i+(1<<8)] = green[i] << 8; out_map[i+(2<<8)] = blue[i] << 8; } } outrows[0] = alfline; outrows[1] = redline; outrows[2] = grnline; outrows[3] = bluline; rle_put_setup( &rle_dflt_hdr ); /* now just loop through the rows */ if (rashdr.ras_type == RT_BYTE_ENCODED) count = 9999; for (i=0; i<rashdr.ras_height; i++) { /* read a line from the rasterfile */ switch(rashdr.ras_depth) { case 8: for (h=0; h < rashdr.ras_width; h++) { if (rashdr.ras_type != RT_BYTE_ENCODED) p = getc(rasfile); else { if (count == 9999) { p = getc(rasfile); if (p == ESCAPE) { count = getc(rasfile); if (count == 0) count = 9999; else p = getc(rasfile); } } else { if (--count == 0) count = 9999; } } redline[h] = p; grnline[h] = p; bluline[h] = p; /* fake up an alpha channel */ if ( aflag || rashdr.ras_depth == 32 ) { if (redline[h] || grnline[h] || bluline[h]) alfline[h] = 255; else alfline[h] = 0; } } /* Since records are an even number of bytes */ if (rashdr.ras_width & 1) p = getc(rasfile); break ; case 24: for (h=0; h < rashdr.ras_width; h++) { register int r,g,b ; r = getc(rasfile); g = getc(rasfile); b = getc(rasfile); redline[h] = red[r]; grnline[h] = green[g]; bluline[h] = blue[b]; /* fake up an alpha channel */ if ( aflag ) { if (redline[h] || grnline[h] || bluline[h]) alfline[h] = 255; else alfline[h] = 0; } } break ; case 32: for (h=0; h < rashdr.ras_width; h++) { register int r,g,b,a ; a = getc(rasfile); r = getc(rasfile); g = getc(rasfile); b = getc(rasfile); redline[h] = red[r]; grnline[h] = green[g]; bluline[h] = blue[b]; alfline[h] = a; } break ; } /* write a line to the rle file */ rle_putrow(&outrows[1], rashdr.ras_width, &rle_dflt_hdr); } break; /* end case 8: */ } /* end switch */ } /* * get a bit from the file fp. Read a byte and return its bits * one at a time. (actually returns zero or non-zero). */ int getbit(fp, force) FILE *fp; int force; /* true if we should read a byte anyway */ { static int c; /* the char we are picking apart */ static unsigned int mask = 0x0; /* mask to get the next bit -- init to huge * so that we get a byte the first time */ int val; /* value to be returned */ if (force) /* read a new byte next time */ { mask = 0x0; return 0; } if(mask == 0) /* time to get the next byte */ { c = getc(fp); mask = 0x80; /* reset the mask */ } val = c & mask; /* true if this bit on */ mask >>= 1; /* shift mask over one bit */ return val; /* the bit we saved goes back to caller */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.