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.