This is rletoraw.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. */ /* * rletoraw.c - Convert the RLE format to the kitchen sink. * * Author: Martin R. Friedmann * Vision and Modeling Group/Media Lab * Massachusetts Institute of Technology * Date: Thu Sep 13 1990 * Copyright (c) 1990, Martin R. Friedmann * * usage : rletoraw [-{Ns}] [-r] [-w width] [-h height] [-f header-size] * [-t tailer-size] [-n nchannels] [-a] * [-p scanline-pad] [-l left-scanline-pad] [-o outfile] * [infile] * * -a dont strip the alpha channel from the rle file * -s output data in scanline interleaved order * -N output data in non-interleaved order (eg. | split -Wid*Height -) * -r reverse the channel order (e.g. write data as ABGR instead of * the default RGBA order) * */ #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 don't strip the alpha channel from the rle file\n"); fprintf(stderr, "-s output data in scanline interleaved order\n"); fprintf(stderr, "-N output data in non-interleaved order (eg. | split -Wid*Height -)\n"); fprintf(stderr, "-r reverse the channel order (e.g. write data as ABGR instead of\n"); fprintf(stderr, "the default RGBA order)\n"); exit(-1); } #define WRITE_DATA() \ if (fwrite( outrows, 1, fwrite_len, outfile ) != fwrite_len) {\ perror( "write error" );\ exit(-2);\ }\ void main(argc,argv) int argc; char *argv[]; { int i, rle_err; char *nullbytes = NULL; char *infname = NULL, *outfname = NULL, *progname; FILE *infile, *outfile; int oflag = 0; int fflag = 0, tflag = 0, Nflag = 0, rflag = 0; int header = 0, trailer = 0; int pflag= 0, right_pad = 0, lflag = 0, left_pad = 0; int aflag = 0, output_alpha = 0, sflag = 0; int height, width, nochan; int red_pos, alpha_pos, green_pos = 0, blue_pos = 0; int img_size; /* Default color values */ unsigned char *outrows; rle_pixel **inrows; int outrows_size; int y; int line_pos; int fwrite_len; unsigned char *fwrite_pos; progname = argv[0]; if ( scanargs( argc, argv, "% {Ns}%- r%- a%- f%-header-size!d t%-trailer-size!d \n\ p%-scanline-pad!d l%-left-scanline-pad!d o%-outfile!s \n\ infile%s", &Nflag, &rflag, &aflag, &fflag, &header, &tflag, &trailer, &pflag, &right_pad, &lflag, &left_pad, &oflag, &outfname, &infname ) == 0) usage(); if (Nflag) { if (Nflag & 2) { Nflag = 0; sflag = 1; } else { Nflag = 1; sflag = 0; } } /* Open Raw file */ infile = rle_open_f( progname, infname, "r" ); outfile = rle_open_f( progname, outfname, "w" ); rle_dflt_hdr.rle_file = infile; if ( (rle_err = rle_get_setup(&rle_dflt_hdr)) < 0) { rle_get_error( rle_err, progname, infname ); exit ( rle_err ); } rle_dflt_hdr.xmax -= rle_dflt_hdr.xmin; rle_dflt_hdr.xmin = 0; rle_dflt_hdr.ymax -= rle_dflt_hdr.ymin; rle_dflt_hdr.ymin = 0; width = rle_dflt_hdr.xmax + 1; height = rle_dflt_hdr.ymax + 1; nochan = rle_dflt_hdr.ncolors; fprintf(stderr, "width %d, height %d, channnels %d\n", width, height, nochan); if (! aflag) RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA); output_alpha = (aflag && RLE_BIT(rle_dflt_hdr, RLE_ALPHA)) ? 1 : 0; /* for -Non-interleaved case, we need nochan-1 whole channels of buffer */ /* HACK: we allocate more memory; we jack the size for the first fread */ outrows_size = width * (nochan + output_alpha); if ( Nflag ) outrows_size *= height; if ((outrows = (unsigned char *) malloc ( outrows_size )) == NULL ) { fprintf(stderr, "%s: No memory available for rows malloc\n", progname); exit(-2); } img_size = width * height; /* Were only interested in R, G, & B */ for (i = 3; i < rle_dflt_hdr.ncolors; i++) RLE_CLR_BIT(rle_dflt_hdr, i); if (rle_row_alloc( &rle_dflt_hdr, &inrows )) { fprintf(stderr, "%s: No memory available for rle_row_alloc\n", progname); exit(-2); } /* maybe faster to malloc and fwrite than to do lots of GETCs, Idunno */ if (fflag || tflag) { nullbytes = (char *) malloc ( (header > trailer) ? header : trailer ); if (! nullbytes) fprintf(stderr, "%s: No memory for nullbytes\n", progname); else for( i = (header > trailer) ? header : trailer; i > 0; ) nullbytes[--i] = 0; } /* 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 + output_alpha; green_pos = 1 + output_alpha; blue_pos = 0 + output_alpha; } else red_pos = 0 + output_alpha; } else { alpha_pos = nochan; 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; } else if ( sflag ) { red_pos *= width; green_pos *= width; blue_pos *= width; alpha_pos *= width; } y = height; line_pos = 0; fwrite_len = outrows_size; fwrite_pos = outrows; /* write the header */ if (fflag) fwrite( nullbytes, 1, header, outfile ); while (--y >= 0) { register rle_pixel *p, *o; register int stride = nochan + output_alpha, count; rle_getrow(&rle_dflt_hdr, inrows); /* 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 ( output_alpha ) bcopy(inrows[RLE_ALPHA], outrows + alpha_pos + line_pos,width); bcopy(inrows[RLE_RED], outrows + red_pos + line_pos, width); if (nochan > 2) { bcopy(inrows[RLE_GREEN], outrows + green_pos + line_pos,width); bcopy(inrows[RLE_BLUE], outrows + blue_pos + line_pos,width); } line_pos += width; } else if (sflag) { /* scanline interleaved: we only need to copy the data */ if ( output_alpha ) bcopy (inrows[RLE_ALPHA], outrows + alpha_pos, width); bcopy (inrows[RLE_RED], outrows + red_pos, width); if (nochan > 2) { bcopy(inrows[RLE_GREEN], outrows + green_pos, width); bcopy(inrows[RLE_BLUE], outrows + blue_pos, width); } } else { #define COPY_LINE() duff(count, *o = *p++; o += stride); /* ahhh... the default. interleaved data */ if ( output_alpha ) { o = outrows + alpha_pos; p = inrows[RLE_ALPHA]; count = width; COPY_LINE(); } o = outrows + red_pos; p = inrows[RLE_RED]; count = width; COPY_LINE(); if (nochan > 2) { o = outrows + green_pos; p = inrows[RLE_GREEN]; count = width; COPY_LINE(); o = outrows + blue_pos; p = inrows[RLE_BLUE]; count = width; COPY_LINE(); } } /* LEFT_PAD */ for (count = 0; count < left_pad; count++) putc('\0', outfile); /* WRITE_SCANLINE */ if (! Nflag) WRITE_DATA(); /* RIGHT_PAD */ for (count = 0; count < right_pad; count++) putc('\0', outfile); } if ( Nflag ) WRITE_DATA(); /* write the trailer */ if (tflag) fwrite( nullbytes, 1, trailer, outfile ); exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.