home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
309.lha
/
PBM_PLUS
/
ppm
/
rasttoppm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1980-12-04
|
5KB
|
229 lines
/* rasttoppm.c - read a Sun raster file and produce a portable pixmap
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
#include <stdio.h>
#include "ppm.h"
/* This program compiles only on Suns. */
#include <pixrect/pixrect_hs.h>
main( argc, argv )
int argc;
char *argv[];
{
FILE *ifd;
struct rasterfile header;
colormap_t pr_colormap;
struct pixrect *pr, *pr_load_image( );
register pixel *pixelrow, *pP;
int argn, rows, cols, depth, row, col, mask, bytenum;
pixval maxval, r, g, b;
pixel zero, one;
int linesize;
short *data, *sp;
unsigned char byte;
pm_progname = argv[0];
argn = 1;
if ( argn != argc )
{
ifd = pm_openr( argv[argn] );
argn++;
}
else
ifd = stdin;
if ( argn != argc )
pm_usage( "[rastfile]" );
/* Read in the raster file. First the header. */
if ( pr_load_header( ifd, &header ) != 0 )
pm_error( "unable to read in raster file header", 0,0,0,0,0 );
cols = header.ras_width;
rows = header.ras_height;
depth = header.ras_depth;
if ( cols <= 0 )
pm_error( "invalid cols: %d", cols, 0,0,0,0 );
if ( rows <= 0 )
pm_error( "invalid rows: %d", rows, 0,0,0,0);
/* If there is a color map, read it. */
if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
{
if ( pr_load_colormap( ifd, &header, &pr_colormap ) != 0 )
pm_error( "unable to skip colormap data", 0,0,0,0,0 );
}
/* Check the depth and color map. */
switch ( depth )
{
case 1:
if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 )
{
maxval = 255;
PPM_ASSIGN( zero, maxval, maxval, maxval );
PPM_ASSIGN( one, 0, 0, 0 );
}
else if ( header.ras_maptype == RMT_EQUAL_RGB &&
header.ras_maplength == 6 )
{
maxval = 255;
PPM_ASSIGN(
zero, pr_colormap.map[0][0], pr_colormap.map[1][0],
pr_colormap.map[2][0] );
PPM_ASSIGN(
one, pr_colormap.map[0][1], pr_colormap.map[1][1],
pr_colormap.map[2][1] );
}
else
pm_error(
"this depth-1 rasterfile has a non-standard colormap - type %d length %d",
header.ras_maptype, header.ras_maplength, 0,0,0 );
break;
case 8:
if ( header.ras_maptype != RMT_EQUAL_RGB )
pm_error(
"this depth-8 rasterfile has a non-standard colormap - type %d length %d",
header.ras_maptype, header.ras_maplength, 0,0,0 );
maxval = 255;
break;
case 24:
if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
pm_error(
"this depth-24 rasterfile has a colormap - can't handle it",
0,0,0,0,0 );
maxval = 255;
break;
default:
pm_error(
"invalid depth: %d. PPM can only handle depth 1, 8, or 24.",
depth, 0,0,0,0 );
}
/* Now load the data. The pixrect returned is a memory pixrect. */
if ( ( pr = pr_load_image( ifd, &header, NULL ) ) == NULL )
pm_error(
"unable to read in the image from the raster file", 0,0,0,0,0 );
#ifdef sun386
/* Force a flip to 680x0 format. */
pr_flip( pr );
( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
pr_flip( pr );
#endif
linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
data = ( (struct mpr_data *) pr->pr_data )->md_image;
pm_close( ifd );
/* Now write out the PPM. */
ppm_writeppminit( stdout, cols, rows, maxval );
pixelrow = ppm_allocrow( cols );
for ( row = 0; row < rows; row++ )
{
sp = data;
switch ( depth )
{
case 1:
mask = 0x8000;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( mask == 0 )
{
sp++;
mask = 0x8000;
}
if ( *sp & mask )
*pP = one;
else
*pP = zero;
mask = mask >> 1;
}
break;
case 8:
bytenum = 0;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
}
if ( bytenum == 0 )
byte = ( *sp & 0xff00 ) >> 8;
else
byte = *sp & 0xff;
PPM_ASSIGN(
*pP, pr_colormap.map[0][byte], pr_colormap.map[1][byte],
pr_colormap.map[2][byte] );
bytenum++;
}
break;
case 24:
bytenum = 0;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
}
if ( bytenum == 0 )
r = ( *sp & 0xff00 ) >> 8;
else
r = *sp & 0xff;
bytenum++;
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
}
if ( bytenum == 0 )
g = ( *sp & 0xff00 ) >> 8;
else
g = *sp & 0xff;
bytenum++;
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
}
if ( bytenum == 0 )
b = ( *sp & 0xff00 ) >> 8;
else
b = *sp & 0xff;
bytenum++;
PPM_ASSIGN( *pP, r, g, b );
}
break;
default:
pm_error( "can't happen", 0,0,0,0,0 );
}
data += linesize / sizeof(short);
ppm_writeppmrow( stdout, pixelrow, cols, maxval );
}
exit( 0 );
}