This is rawtorle.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. */ /* * rawtorle.c - Convert the kitchen sink to RLE format. * * Author: Martin R. Friedmann while residing@media-lab * Vision and Modeling Group/Media Lab * Massachusetts Institute of Technology * Date: Fri Feb 16 1990 * Copyright (c) 1990, Martin R. Friedmann * * usage : rawtorle [-{Ns}] [-r] [-w width] [-h height] [-f header-size] * [-t tailer-size] [-n nchannels] [-a [alpha-value]] * [-p scanline-pad] [-l left-scanline-pad] [-o outfile] * [infile] * * -a [value] add a blank alpha channel to the rle file * -s input data is in scanline interleaved order * -N input is in non-interleaved order (eg. cat pic.r pic.g pic.b | rawtorle) * -r reverse the channel order (e.g. read data as ABGR instead of * the default RGBA order) * * Examples: * 512x512 greyscale image: rawtorle -w 512 -h 512 -n 1 * 640x512 raw RGB file : rawtorle -w 640 -h 512 -n 3 * picture.[rgb] : cat picture.* | rawtorle -w 640 -h 512 -n 3 -N -r * JPLs ODL voyager pics : rawtorle -w 800 -h 800 -f 2508 -t 1672 -n 1 -p 36 * 24bit rasterfile : rawtorle -f 32 -w ... -h ... -n 3 * 8 bit rasterfile w/cmap: Uh er Uh.... use rastorle anyway huh? * pic.[000-100].[rgb] : cat pic.* | rawtorle -w ... -h ... -n 3 -s -r */ #include <stdio.h> #include "rle.h" #ifdef USE_STDLIB_H #include <stdlib.h> #else #ifdef VOID_STAR extern void *malloc(); #else extern char *malloc(); #endif extern void free(); #endif /* USE_STDLIB_H */ /* hey.. why spin normally! */ #define duff(counter, block) {\ while (counter >= 4) {\ { block; } \ { block; } \ { block; } \ { block; } \ counter -= 4;\ } \ switch (counter & 3) { \ case 3: { block; } \ case 2: { block; } \ case 1: { block; } \ case 0: counter = 0;\ }\ } void usage() { fprintf(stderr, "-a [value] add a blank alpha channel to the rle file\n"); fprintf(stderr, "-s input data is in scanline interleaved order\n"); fprintf(stderr, "-N input is in non-interleaved order (eg. cat pic.r pic.g pic.b | rawtorle)\n"); fprintf(stderr, "-r reverse the channel order (e.g. read data as ABGR instead of\n"); fprintf(stderr, " the default RGBA order)\n"); exit(-1); } void main(argc,argv) int argc; char *argv[]; { int i; char *header_bytes = NULL, *trailer_bytes = NULL; char *infname = NULL, *outfname = NULL; FILE *infile, *outfile; int oflag = 0, wflag = 0, hflag = 0, nflag = 0; int fflag = 0, tflag = 0, Nflag = 0, rflag = 0; int header = 0, trailer = 0, alpha_value = 255; int pflag= 0, right_pad = 0, lflag = 0, left_pad = 0; int aflag = 0, input_alpha = 0, sflag = 0; int height = 512, width = 512, nochan = 3; int red_pos, alpha_pos, green_pos = 0, blue_pos = 0; int img_size; /* Default color values */ rle_pixel **outrows; unsigned char *inrows; int inrows_size; if ( scanargs( argc, argv, "% N%- s%- r%- w%-width!d h%-height!d f%-header-size!d \n\ t%-trailer-size!d n%-nchannels!d a%-alpha-value%d \n\ p%-scanline-pad!d l%-left-scanline-pad!d o%-outfile!s \n\ infile%s", &Nflag, &sflag, &rflag, &wflag, &width, &hflag, &height, &fflag, &header, &tflag, &trailer, &nflag, &nochan, &aflag, &alpha_value, &pflag, &right_pad, &lflag, &left_pad, &oflag, &outfname, &infname ) == 0) usage(); /* Open Raw file */ infile = rle_open_f( "rawtorle", infname, "r" ); outfile = rle_open_f( "rawtorle", outfname, "w" ); if ( width <= 0 || height <= 0 ) { fprintf(stderr, "rawtorle: Invalid width or height arg (%d,%d)\n", width, height); exit(-2); } if ( 0 > nochan || nochan > 4 ) { fprintf(stderr, "rawtorle: Invalid number of channels %d\n", nochan); exit(-2); } /* For 2 channels we assume one is an alpha channel */ if ( nochan == 2 || nochan == 4 ) input_alpha = 1; /* either way, who cares */ if ( Nflag && nochan == 1 ) Nflag = 0; if ( Nflag && sflag ) { fprintf( stderr, "rawtorle: Only one of -N and -s may be chosen.\n"); exit (-2); } if ( Nflag && (lflag || pflag)) fprintf( stderr, "rawtorle: -N and -l or -p is not supported.\n" ); /* for -Non-interleaved case, we need nochan-1 whole channels of buffer */ inrows_size = Nflag ? width * (height + 1) * (nochan - 1) : width * nochan; if ((inrows = (unsigned char *) malloc ( inrows_size )) == NULL) { fprintf(stderr, "rawtorle: No memory available for inrows malloc\n"); exit(-2); } /* HACK: we allocate more memory; we jack the size for the first fread */ if ( Nflag ) inrows_size = width * height * (nochan - 1) + width; img_size = width * height; rle_dflt_hdr.rle_file = outfile; rle_dflt_hdr.xmin = rle_dflt_hdr.ymin = 0; rle_dflt_hdr.xmax = width - 1; rle_dflt_hdr.ymax = height - 1; rle_dflt_hdr.alpha = aflag || input_alpha; switch ( nochan ) { case 4: case 3: rle_dflt_hdr.ncolors = 3; break; case 2: case 1: rle_dflt_hdr.ncolors = 1; break; } if ( aflag || input_alpha ) RLE_SET_BIT( rle_dflt_hdr, RLE_ALPHA ); else RLE_CLR_BIT( rle_dflt_hdr, RLE_ALPHA ); rle_addhist( argv, (rle_hdr *)NULL, &rle_dflt_hdr ); /* maybe faster to malloc and fread than to do lots of GETCs, Idunno */ if (fflag) header_bytes = (char *) malloc ( header ); if (tflag) trailer_bytes = (char *) malloc ( trailer ); if (rle_row_alloc( &rle_dflt_hdr, &outrows )) { fprintf(stderr, "rawtorle: No memory available for rle_row_alloc\n"); exit(-2); } /* insert alpha channel */ if ( aflag && !input_alpha ) for (i = 0; i < width; i++) outrows[RLE_ALPHA][i] = alpha_value; /* setup byte positions for reversed colors or otherwise */ if ( rflag ) { alpha_pos = 0; /* alpha comes first if it's there */ if (nochan > 2) { red_pos = 2 + input_alpha; green_pos = 1 + input_alpha; blue_pos = 0 + input_alpha; } else red_pos = 0 + input_alpha; } else { alpha_pos = nochan - input_alpha; red_pos = 0; if (nochan > 2) { green_pos = 1; blue_pos = 2; } } if ( Nflag ) { red_pos *= img_size; green_pos *= img_size; blue_pos *= img_size; alpha_pos *= img_size; } if ( sflag ) { red_pos *= width; green_pos *= width; blue_pos *= width; alpha_pos *= width; } while ( !feof( infile )) { int y = height; int ni_y = 0; /* only used in -N cases */ int first_line = 1; int fread_len = inrows_size; unsigned char *fread_pos = inrows; /* skip the header */ if (fflag) fread( header_bytes, 1, header, infile ); while (--y >= 0) { register rle_pixel *p, *o; register int stride = nochan, count; /* LEFT_PAD */ for (count = 0; count < left_pad; count++) getc(infile); /* READ_SCANLINE */ if (fread( fread_pos, 1, fread_len, infile ) != fread_len) { if (!first_line) perror( "read error" ); exit (!first_line); } /* RIGHT_PAD */ for (count = 0; count < right_pad; count++) getc(infile); /* non-interleaved data is easier to compute than interleaved */ if ( Nflag ) { /* * This is a wierd case... We had to read in all of the * scanlines for all but one of the channels... Then we can * handle things scanline by scanline... We have to jack * the fread parameters for all of the remaining scanlines */ if ( first_line ) { fread_len = width; fread_pos = inrows + (img_size * (nochan - 1)); } if ( input_alpha ) outrows[RLE_ALPHA] = (rflag ? inrows + ni_y : fread_pos); if ( rflag ) outrows[RLE_RED] = fread_pos; else outrows[RLE_RED] = inrows + red_pos + ni_y; if (nochan > 2) { outrows[RLE_GREEN] = inrows + green_pos + ni_y; if ( rflag || input_alpha ) outrows[RLE_BLUE] = inrows + blue_pos + ni_y; else outrows[RLE_BLUE] = fread_pos; } ni_y += width; } else if ( sflag ) { /* scanline interleaved! Like the rle_putrow format.. cake */ /* we only need to jack the pointers on the first scanline */ if (first_line) { if ( input_alpha ) outrows[RLE_ALPHA] = inrows + alpha_pos; outrows[RLE_RED] = inrows + red_pos; if (nochan > 2) { outrows[RLE_GREEN] = inrows + green_pos; outrows[RLE_BLUE] = inrows + blue_pos; } } } else { /* ahhh... the default. interleaved data */ if ( input_alpha ) { o = outrows[RLE_ALPHA]; p = inrows + alpha_pos; count = width; duff(count, *o++ = *p; p += stride); } o = outrows[RLE_RED]; p = inrows + red_pos; count = width; duff( count, *o++ = *p; p += stride); if (nochan > 2) { o = outrows[RLE_GREEN]; p = inrows + green_pos; count = width; duff( count, *o++ = *p; p += stride); o = outrows[RLE_BLUE]; p = inrows + blue_pos; count = width; duff( count, *o++ = *p; p += stride); } } /* start the file */ if (first_line) { rle_put_setup( &rle_dflt_hdr ); first_line = 0; } rle_putrow( outrows, width, &rle_dflt_hdr ); } rle_puteof( &rle_dflt_hdr ); /* skip the trailer */ if (tflag) fread( trailer_bytes, 1, trailer, infile ); } exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.