w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ppmtopcx.c
Go to the documentation of this file.
1 /* ppmtopcx.c - convert a portable pixmap to PCX
2 **
3 ** Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
4 ** based on ppmtopcx.c by Michael Davidson
5 **
6 ** Permission to use, copy, modify, and distribute this software and its
7 ** documentation for any purpose and without fee is hereby granted, provided
8 ** that the above copyright notice appear in all copies and that both that
9 ** copyright notice and this permission notice appear in supporting
10 ** documentation. This software is provided "as is" without express or
11 ** implied warranty.
12 **
13 ** 11/Dec/94: first version
14 ** 12/Dec/94: added support for "packed" format (16 colors or less)
15 */
16 #include "ppm.h"
17 #include "ppmcmap.h"
18 
19 /*#define DEBUG*/
20 
21 #define MAXCOLORS 256
22 
23 #define PCX_MAGIC 0x0a /* PCX magic number */
24 #define PCX_256_COLORS 0x0c /* magic number for 256 colors */
25 #define PCX_MAXVAL (pixval)255
26 
27 
28 /* prototypes */
29 static void ppm_to_16col_pcx ARGS((pixel **pixels, int cols, int rows,
31 static void ppm_to_256col_pcx ARGS((pixel **pixels, int cols, int rows,
33 static void ppm_to_truecol_pcx ARGS((pixel **pixels, int cols, int rows, int maxval));
34 static void write_header ARGS((FILE *fp, int cols, int rows, int BitsPerPixel, int Planes, pixel *cmap16));
35 static void PCXEncode ARGS(( FILE* fp, unsigned char* buf, int Size ));
36 static void ToPlanes ARGS((unsigned char *rawrow, int width, unsigned char *buf, int planes));
37 static void PackBits ARGS((unsigned char *rawrow, int width, unsigned char *buf, int bits));
38 static void Putword ARGS(( int w, FILE* fp ));
39 static void Putbyte ARGS(( int b, FILE* fp ));
40 
41 static short force24 = 0;
42 static short packbits = 0;
43 
44 
45 int
47  int argc;
48  char* argv[];
49  {
50  FILE* ifp;
51  int argn, rows, cols, colors, i;
52  pixval maxval;
53  pixel black_pixel, *cmap, **pixels;
54  colorhist_vector chv;
56  char* usage = "[-24bit] [-packed] [ppmfile]";
57 
58  ppm_init(&argc, argv);
59 
60  argn = 1;
61  while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
62  if( pm_keymatch(argv[argn], "-24bit", 3) )
63  force24 = 1;
64  else
65  if( pm_keymatch(argv[argn], "-packed", 2) )
66  packbits = 1;
67  else
68  pm_usage(usage);
69  ++argn;
70  }
71  if( argn < argc ) {
72  ifp = pm_openr(argv[argn]);
73  ++argn;
74  }
75  else
76  ifp = stdin;
77  if( argn != argc )
78  pm_usage(usage);
79 
80 
81  pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
82  pm_close( ifp );
83 
84  if( !force24 ) {
85  /* Figure out the colormap. */
86  pm_message( "computing colormap..." );
88  if ( chv == (colorhist_vector) 0 ) {
89  pm_message("too many colors - writing a 24bit PCX file");
90  pm_message("if you want a non-24bit file, do a \'ppmquant %d\'", MAXCOLORS);
91  force24 = 1;
92  }
93  }
94 
95  if( maxval != PCX_MAXVAL )
96  pm_message("maxval is not %d - automatically rescaling colors", PCX_MAXVAL);
97 
98  if( force24 )
100  else {
101  pm_message("%d colors found", colors);
102 
103  /* Force black to slot 0 if possible. */
104  PPM_ASSIGN(black_pixel, 0, 0, 0 );
105  ppm_addtocolorhist(chv, &colors, MAXCOLORS, &black_pixel, 0, 0 );
106 
107 
108  /* build colormap */
110  for( i = 0; i < colors; i++ ) {
111  pixval r, g, b;
112  r = PPM_GETR(chv[i].color); g = PPM_GETG(chv[i].color); b = PPM_GETB(chv[i].color);
113  if( maxval != PCX_MAXVAL ) {
114  r = r * PCX_MAXVAL / maxval; g = g * PCX_MAXVAL / maxval; b = b * PCX_MAXVAL / maxval;
115  }
116  PPM_ASSIGN(cmap[i], r, g, b);
117  }
118  for( ; i < MAXCOLORS; i++ )
119  PPM_ASSIGN(cmap[i], 0,0,0);
120 
121  /* make a hash table for fast color lookup */
123  ppm_freecolorhist( chv );
124 
125  /* convert image */
126  if( colors <= 16 )
128  else
130  }
131  exit(0);
132 }
133 
134 
135 static void
137  pixel **pixels;
138  int cols, rows;
139  pixel *cmap;
140  int colors;
142 {
143  int Planes, BytesPerLine, BitsPerPixel;
144  unsigned char *rawrow, *planesrow;
145  register int col, row;
146 
147 #ifdef DEBUG
148  pm_message("ppm -> %d colors", colors);
149 #endif
150 
151  if( packbits ) {
152  Planes = 1;
153  if( colors > 4 ) BitsPerPixel = 4;
154  else if( colors > 2 ) BitsPerPixel = 2;
155  else BitsPerPixel = 1;
156  }
157  else {
158  BitsPerPixel = 1;
159  if( colors > 8 ) Planes = 4;
160  else if( colors > 4 ) Planes = 3;
161  else if( colors > 2 ) Planes = 2;
162  else Planes = 1;
163  }
164 
165  BytesPerLine = ((cols * BitsPerPixel) + 7) / 8;
166  rawrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
167  planesrow = (unsigned char *)pm_allocrow(BytesPerLine, sizeof(unsigned char));
168 
169 #ifdef DEBUG
170  pm_message("Planes = %d, BitsPerPixel = %d, BytesPerLine = %d",
171  Planes, BitsPerPixel, BytesPerLine);
172 #endif
173 
174  write_header(stdout, cols, rows, BitsPerPixel, Planes, cmap);
175  for( row = 0; row < rows; row++ ) {
176  register pixel *pP = pixels[row];
177  for( col = 0; col < cols; col++, pP++ )
178  rawrow[col] = (unsigned char)ppm_lookupcolor(cht, pP) & 0x0f;
179  if( packbits ) {
180  PackBits(rawrow, cols, planesrow, BitsPerPixel);
181  PCXEncode(stdout, planesrow, BytesPerLine);
182  }
183  else {
184  for( col = 0; col < Planes; col++ ) {
185  ToPlanes(rawrow, cols, planesrow, col);
186  PCXEncode(stdout, planesrow, BytesPerLine);
187  }
188  }
189  }
190 #ifdef DEBUG
191  pm_message("done!");
192 #endif
193  pm_freerow((void*)planesrow);
194  pm_freerow((void*)rawrow);
195 }
196 
197 
198 static void
200  pixel **pixels;
201  int cols, rows;
202  pixel *cmap;
203  int colors;
205 {
206  register int col, row, i;
207  unsigned char *rawrow;
208 
209 #ifdef DEBUG
210  pm_message("ppm -> 256 color, writing index array...");
211 #endif
212 
213  rawrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
214 
215  /* 8 bits per pixel, 1 plane */
216  write_header(stdout, cols, rows, 8, 1, (pixel *)NULL);
217  for( row = 0; row < rows; row++ ) {
218  register pixel *pP = pixels[row];
219  for( col = 0; col < cols; col++, pP++ )
220  rawrow[col] = ppm_lookupcolor(cht, pP);
221  PCXEncode(stdout, rawrow, cols);
222  }
223 #ifdef DEBUG
224  pm_message("ok, writing colormap...");
225 #endif
227  for( i = 0; i < MAXCOLORS; i++ ) {
231  }
232 #ifdef DEBUG
233  pm_message("done!");
234 #endif
235  pm_freerow((void*)rawrow);
236 }
237 
238 
239 static void
241  pixel **pixels;
242  int cols, rows, maxval;
243 {
244  unsigned char *redrow, *greenrow, *bluerow;
245  register int col, row;
246 
247 #ifdef DEBUG
248  pm_message("ppm -> 24bit");
249 #endif
250 
251  redrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
252  greenrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
253  bluerow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
254 
255  /* 8 bits per pixel, 3 planes */
256  write_header(stdout, cols, rows, 8, 3, (pixel *)NULL);
257  for( row = 0; row < rows; row++ ) {
258  register pixel *pP = pixels[row];
259  for( col = 0; col < cols; col++, pP++ ) {
260  if( maxval != PCX_MAXVAL ) {
261  redrow[col] = (long)PPM_GETR(*pP) * PCX_MAXVAL / maxval;
262  greenrow[col] = (long)PPM_GETG(*pP) * PCX_MAXVAL / maxval;
263  bluerow[col] = (long)PPM_GETB(*pP) * PCX_MAXVAL / maxval;
264  }
265  else {
266  redrow[col] = PPM_GETR(*pP);
267  greenrow[col] = PPM_GETG(*pP);
268  bluerow[col] = PPM_GETB(*pP);
269  }
270  }
271  PCXEncode(stdout, redrow, cols);
272  PCXEncode(stdout, greenrow, cols);
273  PCXEncode(stdout, bluerow, cols);
274  }
275 #ifdef DEBUG
276  pm_message("done!");
277 #endif
278  pm_freerow((void*)bluerow);
279  pm_freerow((void*)greenrow);
280  pm_freerow((void*)redrow);
281 }
282 
283 
284 static void
285 write_header(fp, cols, rows, BitsPerPixel, Planes, cmap16)
286  FILE *fp;
287  int cols, rows;
288  int BitsPerPixel, Planes;
289  pixel *cmap16;
290 {
291  int i, BytesPerLine;
292 
293  Putbyte( PCX_MAGIC, fp); /* .PCX magic number */
294  Putbyte( 0x05, fp); /* PC Paintbrush version */
295  Putbyte( 0x01, fp); /* .PCX run length encoding */
296  Putbyte( BitsPerPixel, fp); /* bits per pixel */
297 
298  Putword( 0, fp ); /* x1 - image left */
299  Putword( 0, fp ); /* y1 - image top */
300  Putword( cols-1, fp ); /* x2 - image right */
301  Putword( rows-1, fp ); /* y2 - image bottom */
302 
303  Putword( cols, fp ); /* horizontal resolution */
304  Putword( rows, fp ); /* vertical resolution */
305 
306  /* Write out the Color Map for images with 16 colors or less */
307  if( cmap16 )
308  for (i = 0; i < 16; ++i) {
309  Putbyte( PPM_GETR(cmap16[i]), fp );
310  Putbyte( PPM_GETG(cmap16[i]), fp );
311  Putbyte( PPM_GETB(cmap16[i]), fp );
312  }
313  else
314  for (i = 0; i < 16; ++i) {
315  Putbyte( 0, fp );
316  Putbyte( 0, fp );
317  Putbyte( 0, fp );
318  }
319 
320  Putbyte( 0, fp); /* reserved byte */
321  Putbyte( Planes, fp); /* number of color planes */
322 
323  BytesPerLine = ((cols * BitsPerPixel) + 7) / 8;
324  Putword( BytesPerLine, fp ); /* number of bytes per scanline */
325 
326  Putword( 1, fp); /* pallette info */
327 
328  for (i = 0; i < 58; ++i) /* fill to end of header */
329  Putbyte( 0, fp );
330 }
331 
332 
333 static void
334 PCXEncode(fp, buf, Size)
335 FILE *fp;
336 unsigned char *buf;
337 int Size;
338 {
339  unsigned char *end;
340  int c, previous, count;
341 
342  end = buf + Size;
343  previous = *buf++;
344  count = 1;
345 
346  while (buf < end) {
347  c = *buf++;
348  if (c == previous && count < 63) {
349  ++count;
350  continue;
351  }
352 
353  if (count > 1 || (previous & 0xc0) == 0xc0) {
354  count |= 0xc0;
355  Putbyte ( count , fp );
356  }
357  Putbyte(previous, fp);
358  previous = c;
359  count = 1;
360  }
361 
362  if (count > 1 || (previous & 0xc0) == 0xc0) {
363  count |= 0xc0;
364  Putbyte ( count , fp );
365  }
366  Putbyte(previous, fp);
367 }
368 
369 
370 static void
371 PackBits(rawrow, width, buf, bits)
372  unsigned char *rawrow;
373  int width;
374  unsigned char *buf;
375  int bits;
376 {
377  register int x, i, shift;
378 
379  shift = i = -1;
380  for( x = 0; x < width; x++ ) {
381  if( shift < 0 ) {
382  shift = 8-bits;
383  buf[++i] = 0;
384  }
385 
386  buf[i] |= (rawrow[x] << shift);
387  shift -= bits;
388  }
389 }
390 
391 
392 static const unsigned char bitmask[] = {1, 2, 4, 8, 16, 32, 64, 128};
393 
394 
395 static void
396 ToPlanes(rawrow, width, buf, plane)
397  unsigned char *rawrow;
398  int width;
399  unsigned char *buf;
400  int plane;
401 {
402  int cbit, x, mask;
403  unsigned char *cp = buf-1;
404 
405  mask = 1 << plane;
406  cbit = -1;
407  for( x = 0; x < width; x++ ) {
408  if( cbit < 0 ) {
409  cbit = 7;
410  *++cp = 0;
411  }
412  if( rawrow[x] & mask )
413  *cp |= bitmask[cbit];
414  --cbit;
415  }
416 }
417 
418 
419 /*
420  * Write out a word to the PCX file
421  */
422 static void
424 int w;
425 FILE *fp;
426 {
427  Putbyte( w & 0xff, fp );
428  Putbyte( (w / 256) & 0xff, fp );
429 }
430 
431 /*
432  * Write out a byte to the PCX file
433  */
434 static void
436 int b;
437 FILE *fp;
438 {
439  if( fputc( b & 0xff, fp ) == EOF )
440  pm_error("write error");
441 }
442 
cp
Definition: action.c:1035
#define width(a)
Definition: aptex-macros.h:198
#define count(a)
Definition: aptex-macros.h:781
static gray maxval
Definition: asciitopgm.c:38
char_entry ** planes[0x08000]
Definition: char_routines.c:74
#define b
Definition: jpegint.h:372
int w
Definition: dviconv.c:26
int pixels
Definition: dvipng.h:106
#define shift
Definition: exp3.c:154
static char usage[]
Definition: giftopnm.c:59
#define c(n)
Definition: gpos-common.c:150
int col
Definition: gsftopk.c:443
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
#define bits
Definition: infblock.c:15
void exit()
#define EOF
Definition: afmparse.c:59
#define buf
float x
Definition: cordic.py:15
void pm_usage(char *usage)
Definition: libpbm1.c:343
char * pm_allocrow(int cols, int size)
Definition: libpbm1.c:30
FILE * pm_openr(char *name)
Definition: libpbm1.c:600
static int rows
Definition: pbmclean.c:15
static int cols
Definition: pbmmask.c:21
#define ARGS(alist)
Definition: pbmplus.h:235
#define fp
#define pm_error
Definition: png22pnm.c:118
#define pm_keymatch(stra, strb, _x)
Definition: png22pnm.c:121
#define pm_freerow(x)
Definition: png22pnm.c:144
#define pm_close(file)
Definition: png22pnm.c:120
#define pm_message
Definition: png22pnm.c:116
void ppm_init(int *argcP, argv)
Definition: libppm1.c:21
pixel ** ppm_readppm(FILE *file, int *colsP, int *rowsP, pixval *maxvalP)
Definition: libppm1.c:178
void ppm_addtocolorhist(colorhist_vector chv, int *colorsP, int maxcolors, pixel *colorP, int value, int position)
Definition: libppm3.c:45
int ppm_lookupcolor(colorhash_table cht, pixel *colorP)
Definition: libppm3.c:226
void ppm_freecolorhist(colorhist_vector chv)
Definition: libppm3.c:242
colorhist_vector ppm_computecolorhist(pixel **pixels, int cols, int rows, int maxcolors, int *colorsP)
Definition: libppm3.c:28
colorhash_table ppm_colorhisttocolorhash(colorhist_vector chv, int colors)
Definition: libppm3.c:193
#define PPM_GETR(p)
Definition: ppm.h:36
#define PPM_ASSIGN(p, red, grn, blu)
Definition: ppm.h:46
#define PPM_GETG(p)
Definition: ppm.h:37
#define PPM_GETB(p)
Definition: ppm.h:38
gray pixval
Definition: ppm.h:9
#define ppm_allocrow(cols)
Definition: ppm.h:72
int g
Definition: ppmqvga.c:68
int r
Definition: ppmqvga.c:68
static colorhash_table cht
Definition: ppmtoacad.c:34
int colors
Definition: ppmtogif.c:51
#define PCX_256_COLORS
Definition: ppmtopcx.c:24
static void PCXEncode()
static short force24
Definition: ppmtopcx.c:41
static void ppm_to_16col_pcx()
#define MAXCOLORS
Definition: ppmtopcx.c:21
static const unsigned char bitmask[]
Definition: ppmtopcx.c:392
static short packbits
Definition: ppmtopcx.c:42
#define PCX_MAXVAL
Definition: ppmtopcx.c:25
static void ppm_to_256col_pcx()
static void Putword()
static void ppm_to_truecol_pcx()
#define PCX_MAGIC
Definition: ppmtopcx.c:23
static void write_header()
static void ToPlanes()
static void PackBits()
int main(int argc, argv)
Definition: ppmtopcx.c:46
static void Putbyte()
static int row
Definition: ps2pk.c:587
#define mask(n)
Definition: lbitlib.c:93
Definition: namelist.c:170
Definition: pdfdev.c:706
Definition: ppm.h:33
#define FILE
Definition: t1stdio.h:34
FILE * ifp
Definition: t1asm.c:88
TT_CharMap cmap
Definition: ttf2pfb.c:163
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269
#define end(cp)
Definition: zic.c:71
#define argn