cnv/rletorast.c
/*
* 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.
*/
/*
* rletorast.c - Convert RLE to sun rasterfile.
*
* Author: Rod Bogart, John W. Peterson & Ed Falk (SMI)
* Computer Science Dept.
* University of Utah
* Date: Tue Nov 4 1986
* Copyright (c) 1986 Rod Bogart
* History:
* 6 September 1990: Clark: fix colormap output when hrle_dflt_dr.ncolors == 1 and
* hrle_dflt_dr.ncmap != 0 (i.e. pseudo_color image).
* 10 September 1990: Clark: fix bug in pointer calculation (optr = image + ...).
*
* Based on "tobw.c" by Spencer Thomas, and
* "rps" by Marc Majka (UBC Vision lab)
*
* If an input file isn't specified, it reads from stdin. An output file
* can be specified with -o (otherwise it writes to stdout).
*/
#include <stdio.h>
#include <math.h>
#include <rasterfile.h>
#include "rle.h"
typedef enum { GREY, GREY_ALPHA, COLOR, COLOR_ALPHA } Input_Type ;
void
main( argc, argv )
int argc;
char **argv;
{
char *infname = NULL,
*outfname = NULL;
FILE *outfile = stdout;
rle_hdr hdr;
int oflag = 0;
int y, ncol, nscan, nchan, nochan, i;
unsigned char **scan;
unsigned char *buffer;
struct rasterfile header ;
unsigned char *image ;
Input_Type input_type ;
int linebytes ;
if ( scanargs( argc, argv,
"% o%-outfile!s infile%s",
&oflag, &outfname, &infname ) == 0 )
exit( 1 );
/* Open RLE file and get header information */
/* Initialize header. */
hdr = *rle_hdr_init( (rle_hdr *)NULL );
rle_names( &hdr, cmd_name( argv ), infname, 0 );
hdr.rle_file = rle_open_f( hdr.cmd, infname, "r" );
rle_get_setup_ok( &hdr, NULL, NULL );
if ( ( hdr.ncolors != 3 ) && ( hdr.ncolors != 1))
{
fprintf( stderr, "%s is not RGB or b&w image",
infname ? infname : "stdin" );
exit( 0 );
}
outfile = rle_open_f( "rletorast", outfname, "w" );
/*
* Spencer trick: save space by sliding the input image over to the
* left margin.
*/
hdr.xmax -= hdr.xmin ;
hdr.xmin = 0 ;
ncol = hdr.xmax + 1;
nscan = hdr.ymax - hdr.ymin + 1;
nchan = hdr.ncolors + (hdr.alpha ? 1 : 0) ;
if( hdr.alpha )
{
if( hdr.ncolors == 1 )
input_type = GREY_ALPHA ;
else
input_type = COLOR_ALPHA ;
}
else
{
if( hdr.ncolors == 1 )
input_type = GREY ;
else
input_type = COLOR ;
}
/* Allocate scanline memory */
/*
* buffer = space for one scanline of one color
* scan = space for pointers to ncolors+alpha buffers
* scan[i] = pointer to space for one scanline of one color
*/
buffer = (unsigned char *)malloc( ncol );
rle_row_alloc( &hdr, &scan );
header.ras_magic = RAS_MAGIC ;
header.ras_width = ncol ;
header.ras_height = nscan ;
switch(input_type)
{
case GREY: nochan = 1 ; break ;
case COLOR: nochan = 3 ; break ;
case GREY_ALPHA: case COLOR_ALPHA: nochan = 4 ; break ;
default: nochan = 4; break;
}
header.ras_depth = 8 * nochan ;
linebytes = header.ras_width * nochan ;
linebytes += linebytes % 2 ;
header.ras_length = linebytes * header.ras_height ;
header.ras_type = RT_STANDARD ;
if( hdr.ncmap != 0 )
{
header.ras_maptype = RMT_EQUAL_RGB ;
header.ras_maplength = (1 << hdr.cmaplen) * 3 ;
}
else
{
header.ras_maptype = RMT_NONE ;
header.ras_maplength = 0 ;
}
fwrite( &header, sizeof(header), 1, outfile );
if( header.ras_maptype == RMT_EQUAL_RGB )
{
register rle_map *iptr ;
unsigned char out ;
register int chan;
int nch, nco ;
if( hdr.ncolors == 1 )
{
nch = 3 ;
nco = (1 << hdr.cmaplen) ;
}
else
{
nch = 1 ;
nco = header.ras_maplength ;
}
for(chan=0; chan<nch; ++chan)
{
iptr = hdr.cmap + (chan<<8) ;
for(i=0; i<nco; ++i)
{
out = (*iptr++ + 0x80) >> 8 ;
fwrite(&out, 1,1, outfile) ;
}
}
}
if( hdr.comments != NULL )
{
register CONST_DECL char **comment = hdr.comments ;
while(*comment != NULL)
{
fprintf(stderr,"%s\n", *comment) ;
++comment ;
}
}
image = (unsigned char *) malloc(linebytes * header.ras_height) ;
if( hdr.background != 0 )
{
register int row,col,chan ;
register unsigned char *ptr ;
register int *bptr ;
for(row=0; row<nscan; ++row)
{
ptr = image + row*linebytes ;
for(col=ncol; --col >= 0; )
{
if( hdr.alpha )
*ptr++ = 0 ;
bptr = hdr.bg_color ;
for(chan=hdr.ncolors; --chan >= 0; )
*ptr++ = *bptr++ ;
}
}
}
while ( (y = rle_getrow( &hdr, scan )) <=
hdr.ymax )
{
register unsigned char *optr, *a,*r,*g,*b ;
register int col ;
optr = image + (nscan-y-1+hdr.ymin)*linebytes ;
switch( input_type )
{
case GREY:
r = scan[RLE_RED] ;
for(col=ncol; --col >= 0; )
*optr++ = *r++ ;
break ;
case GREY_ALPHA:
a = scan[RLE_ALPHA] ;
r = scan[RLE_RED] ;
for(col=ncol; --col >= 0; )
{
*optr++ = *a++ ;
*optr++ = *optr++ = *optr++ = *r++ ;
}
break ;
case COLOR:
r = scan[RLE_RED] ;
g = scan[RLE_GREEN] ;
b = scan[RLE_BLUE] ;
for(col=ncol; --col >= 0; )
{
*optr++ = *r++ ;
*optr++ = *g++ ;
*optr++ = *b++ ;
}
break ;
case COLOR_ALPHA:
a = scan[RLE_ALPHA] ;
r = scan[RLE_RED] ;
g = scan[RLE_GREEN] ;
b = scan[RLE_BLUE] ;
for(col=ncol; --col >= 0; )
{
*optr++ = *a++ ;
*optr++ = *r++ ;
*optr++ = *g++ ;
*optr++ = *b++ ;
}
break ;
}
}
fwrite(image, linebytes * header.ras_height, 1, outfile) ;
exit( 0 );
}