home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
309.lha
/
PBM_PLUS
/
ppm
/
ppmtorast.c
< prev
next >
Wrap
C/C++ Source or Header
|
1980-12-04
|
8KB
|
332 lines
/* ppmtorast.c - read a portable pixmap and produce a Sun rasterfile
**
** 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"
#include "ppmcmap.h"
/* This program compiles only on Suns. */
#include <pixrect/pixrect_hs.h>
#define MAXCOLORS 256
main( argc, argv )
int argc;
char *argv[];
{
FILE *ifd;
pixel **pixels, *pixelrow, onepixel, p;
register pixel *pP;
colorhist_vector chv;
colorhash_table cht;
int argn, pr_type, xflag, rows, cols, i;
int depth, colors, linesize, row;
register int col;
pixval maxval;
struct pixrect *pr;
colormap_t *pr_colormapP;
short *data, s;
register short *sp;
int bitcount, bytenum, color;
colormap_t *make_pr_colormap();
char *usage = "[-s] [-x] [ppmfile]";
pm_progname = argv[0];
argn = 1;
pr_type = RT_BYTE_ENCODED;
xflag = 0;
while ( argn < argc && argv[argn][0] == '-' )
{
if ( ( argv[argn][1] == 's' || argv[argn][1] == 'S' ) &&
argv[argn][2] == '\0' )
{
pr_type = RT_STANDARD;
argn++;
}
else if ( ( argv[argn][1] == 'x' || argv[argn][1] == 'X' ) &&
argv[argn][2] == '\0' )
{
xflag = 1;
argn++;
}
else
pm_usage( usage );
}
if ( argn != argc )
{
ifd = pm_openr( argv[argn] );
argn++;
}
else
ifd = stdin;
if ( argn != argc )
pm_usage( usage );
pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
pm_close( ifd );
/* Figure out the proper depth and colormap. */
fprintf( stderr, "(Computing colormap..." );
fflush( stderr );
chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
if ( chv == (colorhist_vector) 0 )
{
fprintf(
stderr, " Too many colors - proceeding to write a 24-bit\n" );
fprintf(
stderr, "non-mapped rasterfile. If you want 8 bits, try running the\n" );
fprintf( stderr, "pixmap through 'ppmquant 256'.)\n" );
depth = 24;
pr_colormapP = (colormap_t *) 0;
}
else
{
fprintf( stderr, " Done. %d colors found.)\n", colors );
if ( maxval != 255 )
for ( i = 0; i < colors; i++ )
PPM_CSCALE( chv[i].color, chv[i].color, maxval, 255 );
if ( xflag )
{
/* Force black to slot 0 and white to slot 1, if possible. */
PPM_ASSIGN( p, 0, 0, 0 );
ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
PPM_ASSIGN( p, 255, 255, 255 );
ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
}
else
{
/* Force white to slot 0 and black to slot 1, if possible. */
PPM_ASSIGN( p, 255, 255, 255 );
ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
PPM_ASSIGN( p, 0, 0, 0 );
ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
}
/* Now turn the ppm colormap into the appropriate Sun colormap. */
if ( colors == 2 )
{
/* Monochrome - no problem. */
depth = 1;
if ( PPM_GETR( chv[0].color ) == 255 &&
PPM_GETG( chv[0].color ) == 255 &&
PPM_GETB( chv[0].color ) == 255 &&
PPM_GETR( chv[1].color ) == 0 &&
PPM_GETG( chv[1].color ) == 0 &&
PPM_GETB( chv[1].color ) == 0 )
{
/* Default colormap. */
pr_colormapP = (colormap_t *) 0;
}
else
pr_colormapP = make_pr_colormap( chv, colors );
onepixel = chv[1].color;
}
else
{
depth = 8;
pr_colormapP = make_pr_colormap( chv, colors );
cht = ppm_colorhisttocolorhash( chv, colors );
}
ppm_freecolorhist( chv );
}
if ( maxval > 255 )
fprintf(
stderr, "(Maxval is not 255 -- automatically rescaling colors.)\n");
/* Allocate space for the Sun-format image. */
if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect *) 0 )
pm_error( "unable to create new pixrect", 0,0,0,0,0 );
data = ( (struct mpr_data *) pr->pr_data )->md_image;
linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
/* And compute the Sun image. The variables at this point are:
** chv is null or not
** depth is 1, 8, or 24
*/
for ( row = 0; row < rows; row++ )
{
pixelrow = pixels[row];
sp = data;
switch ( depth )
{
case 1:
bitcount = 15;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( maxval != 255 )
PPM_CSCALE( *pP, *pP, maxval, 255 );
if ( PPM_EQUAL( *pP, onepixel ) )
*sp |= 1 << bitcount;
bitcount--;
if ( bitcount < 0 )
{
sp++;
bitcount = 15;
}
}
break;
case 8:
/* If depth is 8, we have a valid cht (yes, t). */
bytenum = 0;
s = 0;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( maxval != 255 )
PPM_CSCALE( *pP, *pP, maxval, 255 );
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
s = 0;
}
color = ppm_lookupcolor( cht, *pP );
if ( color == -1 )
pm_error(
"color not found?!? row=%d col=%d r=%d g=%d b=%d",
row, col, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP) );
if ( bytenum == 0 )
s = color << 8;
else
{
s += color;
*sp = s;
}
bytenum++;
}
break;
case 24:
/* If depth is 24, we are guaranteed NOT to have a valid chv. */
bytenum = 0;
s = 0;
for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
{
if ( maxval != 255 )
PPM_CSCALE( *pP, *pP, maxval, 255 );
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
s = 0;
}
if ( bytenum == 0 )
s = PPM_GETR( *pP ) << 8;
else
{
s += PPM_GETR( *pP );
*sp = s;
}
bytenum++;
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
s = 0;
}
if ( bytenum == 0 )
s = PPM_GETG( *pP ) << 8;
else
{
s += PPM_GETG( *pP );
*sp = s;
}
bytenum++;
if ( bytenum == 2 )
{
sp++;
bytenum = 0;
s = 0;
}
if ( bytenum == 0 )
s = PPM_GETB( *pP ) << 8;
else
{
s += PPM_GETB( *pP );
*sp = s;
}
bytenum++;
}
break;
default:
pm_error( "can't happen", 0,0,0,0,0 );
}
data += linesize / sizeof(short);
}
#ifdef sun386
/* Force a flip to 80386 format. */
( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
pr_flip( pr );
#endif sun386
/* Finally, write the sucker out. */
pr_dump( pr, stdout, pr_colormapP, pr_type, 0 );
exit( 0 );
}
colormap_t *
make_pr_colormap( chv, colors )
colorhist_vector chv;
int colors;
{
colormap_t *pr_colormapP;
int i;
pr_colormapP = (colormap_t *) malloc( sizeof(colormap_t) );
if ( pr_colormapP == 0 )
pm_error( "out of memory", 0,0,0,0,0 );
pr_colormapP->type = RMT_EQUAL_RGB;
pr_colormapP->length = colors;
pr_colormapP->map[0] =
(unsigned char *) malloc( colors * sizeof(unsigned char) );
pr_colormapP->map[1] =
(unsigned char *) malloc( colors * sizeof(unsigned char) );
pr_colormapP->map[2] =
(unsigned char *) malloc( colors * sizeof(unsigned char) );
if ( pr_colormapP->map[0] == 0 || pr_colormapP->map[1] == 0 ||
pr_colormapP->map[2] == 0 )
pm_error( "out of memory", 0,0,0,0,0 );
for ( i = 0; i < colors; i++ )
{
pr_colormapP->map[0][i] = PPM_GETR( chv[i].color );
pr_colormapP->map[1][i] = PPM_GETG( chv[i].color );
pr_colormapP->map[2][i] = PPM_GETB( chv[i].color );
}
return pr_colormapP;
}
#ifdef notdef
dump_map( chv, colors )
colorhist_vector chv;
int colors;
{
int i;
for ( i = 0; i < colors; i++ )
fprintf(
stderr, "%d: %d %d %d (%d)\n", i, PPM_GETR(chv[i].color),
PPM_GETG(chv[i].color), PPM_GETB(chv[i].color), chv[i].count );
}
#endif notdef