1 /* ppmtopi1.c - read a portable pixmap and write a Degas PI1 file
2 **
3 ** Copyright (C) 1991 by Steve Belczyk and Jef Poskanzer.
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation. This software is provided "as is" without express or
10 ** implied warranty.
11 */
12
13 #include "ppm.h"
14
15 #define COLS 320
16 #define ROWS 200
17 #define MAXVAL 7
18 #define MAXCOLORS 16
19
20 static short screen[ROWS*COLS/4]; /* simulate the ST's video RAM */
21
22 int
main(argc,argv)23 main( argc, argv )
24 int argc;
25 char* argv[];
26 {
27 FILE* ifp;
28 pixel** pixels;
29 register pixel *pP;
30 colorhist_vector chv;
31 colorhash_table cht;
32 int rows, cols, row, colors, i;
33 register int col;
34 pixval maxval;
35
36
37 ppm_init( &argc, argv );
38
39 if ( argc > 2 )
40 pm_usage( "[ppmfile]" );
41
42 if ( argc == 2 )
43 ifp = pm_openr( argv[1] );
44 else
45 ifp = stdin;
46
47 pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
48 pm_close( ifp );
49 if ( (cols > COLS) || (rows > ROWS) )
50 pm_error( "image is larger than %dx%d - sorry", COLS, ROWS );
51
52 pm_message( "computing colormap..." );
53 chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
54 if ( chv == (colorhist_vector) 0 )
55 {
56 pm_message(
57 "too many colors - try doing a 'pnmquant %d'", MAXCOLORS );
58 exit( 1 );
59 }
60 pm_message( "%d colors found", colors );
61
62 /* Write PI1 header - resolution and palette. */
63 (void) pm_writebigshort( stdout, (short) 0 ); /* low resolution */
64 for ( i = 0; i < 16; ++i )
65 {
66 short w;
67
68 if ( i < colors )
69 {
70 pixel p;
71
72 p = chv[i].color;
73 if ( maxval != MAXVAL )
74 PPM_DEPTH( p, p, maxval, MAXVAL );
75 w = ( (int) PPM_GETR( p ) ) << 8;
76 w |= ( (int) PPM_GETG( p ) ) << 4;
77 w |= ( (int) PPM_GETB( p ) );
78 }
79 else
80 w = 0;
81 (void) pm_writebigshort( stdout, w );
82 }
83 if ( maxval > MAXVAL )
84 pm_message(
85 "maxval is not %d - automatically rescaling colors", MAXVAL );
86
87 /* Convert color vector to color hash table, for fast lookup. */
88 cht = ppm_colorhisttocolorhash( chv, colors );
89 ppm_freecolorhist( chv );
90
91 /* Clear the screen buffer. */
92 for ( i = 0; i < ROWS*COLS/4; ++i )
93 screen[i] = 0;
94
95 /* Convert. */
96 for ( row = 0; row < rows; ++row )
97 {
98 for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
99 {
100 register int color, ind, b, plane;
101
102 color = ppm_lookupcolor( cht, pP );
103 if ( color == -1 )
104 pm_error(
105 "color not found?!? row=%d col=%d r=%d g=%d b=%d",
106 row, col, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP) );
107 ind = 80 * row + ( ( col >> 4 ) << 2 );
108 b = 0x8000 >> (col & 0xf);
109 for ( plane = 0; plane < 4; ++plane )
110 if ( color & (1 << plane) )
111 screen[ind+plane] |= b;
112 }
113 }
114
115 /* And write out the screen buffer. */
116 for ( i = 0; i < ROWS*COLS/4; ++i )
117 (void) pm_writebigshort( stdout, screen[i] );
118
119 exit( 0 );
120 }
121