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)  

ppmtoilbm.c
Go to the documentation of this file.
1 /* ppmtoilbm.c - read a portable pixmap and produce an IFF ILBM file
2 **
3 ** Copyright (C) 1989 by Jef Poskanzer.
4 ** Modified by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
5 ** 20/Jun/93:
6 ** - 24bit support (new options -24if, -24force)
7 ** - HAM8 support (well, anything from HAM3 to HAM(MAXPLANES))
8 ** - now writes up to 8 (16) planes (new options -maxplanes, -fixplanes)
9 ** - colormap file (new option -map)
10 ** - write colormap only (new option -cmaponly)
11 ** - only writes CAMG chunk if it is a HAM-picture
12 ** 29/Aug/93:
13 ** - operates row-by-row whenever possible
14 ** - faster colorscaling with lookup-table (~20% faster on HAM pictures)
15 ** - options -ham8 and -ham6 now imply -hamforce
16 ** 27/Nov/93:
17 ** - byterun1 compression (this is now default) with new options:
18 ** -compress, -nocompress, -cmethod, -savemem
19 ** - floyd-steinberg error diffusion (for std+mapfile and HAM)
20 ** - new options: -lace and -hires --> write CAMG chunk
21 ** - LUT for luminance calculation (used by ppm_to_ham)
22 **
23 **
24 ** std HAM 24bit cmap direct
25 ** -------+-----+-----+-----+-----+-----
26 ** BMHD yes yes yes yes yes
27 ** CMAP yes (1) no yes no
28 ** BODY yes yes yes no yes
29 ** CAMG (2) yes (2) no (2)
30 ** other - - - - DCOL
31 ** nPlanes 1-8 3-8 24 0 3-24 if configured without ILBM_BIGRAW
32 ** nPlanes 1-16 3-16 24 0 3-48 if configured with ILBM_BIGRAW
33 **
34 ** (1): grayscale colormap
35 ** (2): only if "-lace" or "-hires" option used
36 **
37 ** Permission to use, copy, modify, and distribute this software and its
38 ** documentation for any purpose and without fee is hereby granted, provided
39 ** that the above copyright notice appear in all copies and that both that
40 ** copyright notice and this permission notice appear in supporting
41 ** documentation. This software is provided "as is" without express or
42 ** implied warranty.
43 */
44 
45 #include <string.h>
46 #include "ppm.h"
47 #include "ppmcmap.h"
48 #include "ilbm.h"
49 
50 /*#define DEBUG*/
51 
52 #define MODE_DIRECT 4 /* direct color ILBM */
53 #define MODE_CMAP 3 /* write normal file, but colormap only */
54 #define MODE_24 2 /* write a 24bit (deep) ILBM */
55 #define MODE_HAM 1 /* write a HAM */
56 #define MODE_NONE 0 /* write a normal picture */
57 
58 #define ECS_MAXPLANES 5
59 #define ECS_HAMPLANES 6
60 #define AGA_MAXPLANES 8
61 #define AGA_HAMPLANES 8
62 
63 #ifdef AMIGA_AGA
64 #define DEF_MAXPLANES AGA_MAXPLANES
65 #define DEF_HAMPLANES AGA_HAMPLANES
66 #else
67 #define DEF_MAXPLANES ECS_MAXPLANES
68 #define DEF_HAMPLANES ECS_HAMPLANES
69 #endif
70 #define DEF_DCOLPLANES 5
71 #define DEF_COMPRESSION cmpByteRun1
72 
73 
74 typedef struct {
75  int len;
76  unsigned char * row;
77 } bodyrow;
78 typedef struct {
79  long *thisrederr, *thisgreenerr, *thisblueerr;
80  long *nextrederr, *nextgreenerr, *nextblueerr;
81  int lefttoright; /* 1 for left-to-right scan, 0 for right-to-left */
82  int cols;
85  int col, col_end;
86  int alternate;
87  pixval red, green, blue; /* values of current pixel */
88 } floydinfo;
89 
90 
91 static int colorstobpp ARGS((int colors));
92 #define put_fourchars(str) (void)(fputs(str, stdout))
93 static void put_big_short ARGS((short s));
94 static void put_big_long ARGS((long l));
95 #define put_byte(b) (void)(putc((unsigned char)(b), stdout))
96 static void ppm_to_ham ARGS((FILE *fp, int cols, int rows, int maxval, int hambits, int nocolor));
97 static void ppm_to_24 ARGS((FILE *fp, int cols, int rows, int maxval));
98 static void ppm_to_direct ARGS((FILE *fp, int cols, int rows, int maxval, DirectColor *direct));
99 static void ppm_to_std ARGS((FILE *fp, int cols, int rows, int maxval, colorhist_vector chv, int colors, int nPlanes));
100 static void ppm_to_cmap ARGS((int maxval, colorhist_vector chv, int colors));
101 static void write_form_ilbm ARGS((int size));
102 static void write_bmhd ARGS((int cols, int rows, int nPlanes));
103 static void write_std_cmap ARGS((colorhist_vector chv, int colors, int maxval));
104 static int encode_row ARGS((FILE *outfile, rawtype *rawrow, int cols, int nPlanes));
105 static int compress_row ARGS((int bytes));
106 static int runbyte1 ARGS((int bytes));
107 static pixel * next_pixrow ARGS((FILE *fp, int row));
108 static pixval * make_val_table ARGS((pixval oldmaxval, pixval newmaxval));
109 static void * xmalloc ARGS((int bytes));
110 #define MALLOC(n, type) (type *)xmalloc((n) * sizeof(type))
111 static void init_read ARGS((FILE *fp, int *colsP, int *rowsP, pixval *maxvalP, int *formatP, int readall));
112 static void write_body ARGS((void));
113 static void write_camg ARGS((void));
114 static void alloc_body_array ARGS((int rows, int nPlanes));
115 #define PAD(n) odd(n) /* pad to a word */
116 static int closest_color ARGS((colorhist_vector chv, int colors, pixval cmaxval, pixel *pP));
117 static floydinfo *init_floyd ARGS((int cols, pixval maxval, int alternate));
118 static void free_floyd ARGS((floydinfo *fi));
119 static void begin_floyd_row ARGS((floydinfo *fi, pixel *prow));
121 static void update_floyd_pixel ARGS((floydinfo *fi, int r, int g, int b));
122 static void end_floyd_row ARGS((floydinfo *fi));
123 
124 /* global data */
125 static unsigned char *coded_rowbuf; /* buffer for uncompressed scanline */
126 static unsigned char *compr_rowbuf; /* buffer for compressed scanline */
127 static pixel **pixels; /* PPM image (NULL for row-by-row operation) */
128 static pixel *pixrow; /* current row in PPM image (pointer into pixels array, or buffer for row-by-row operation) */
129 static bodyrow *ilbm_body = NULL; /* compressed ILBM BODY */
130 
131 static long viewportmodes = 0;
133 
134 /* flags */
135 static short savemem = 0; /* slow operation, but uses less memory */
136 static short compr_force = 0; /* force compressed output, even if the image got larger - NOT USED */
137 static short floyd = 0; /* apply floyd-steinberg error diffusion */
138 
139 #define WORSTCOMPR(bytes) ((bytes) + (bytes)/128 + 1)
140 #define DO_COMPRESS (compr_type != cmpNone)
141 #define CAMGSIZE (viewportmodes == 0 ? 0 : (4 + 4 + CAMGChunkSize))
142 
143 
144 
145 /* Lookup tables for fast RGB -> luminance calculation. */
146 /* taken from ppmtopgm.c -IUW */
147 
148 static int times77[256] = {
149  0, 77, 154, 231, 308, 385, 462, 539,
150  616, 693, 770, 847, 924, 1001, 1078, 1155,
151  1232, 1309, 1386, 1463, 1540, 1617, 1694, 1771,
152  1848, 1925, 2002, 2079, 2156, 2233, 2310, 2387,
153  2464, 2541, 2618, 2695, 2772, 2849, 2926, 3003,
154  3080, 3157, 3234, 3311, 3388, 3465, 3542, 3619,
155  3696, 3773, 3850, 3927, 4004, 4081, 4158, 4235,
156  4312, 4389, 4466, 4543, 4620, 4697, 4774, 4851,
157  4928, 5005, 5082, 5159, 5236, 5313, 5390, 5467,
158  5544, 5621, 5698, 5775, 5852, 5929, 6006, 6083,
159  6160, 6237, 6314, 6391, 6468, 6545, 6622, 6699,
160  6776, 6853, 6930, 7007, 7084, 7161, 7238, 7315,
161  7392, 7469, 7546, 7623, 7700, 7777, 7854, 7931,
162  8008, 8085, 8162, 8239, 8316, 8393, 8470, 8547,
163  8624, 8701, 8778, 8855, 8932, 9009, 9086, 9163,
164  9240, 9317, 9394, 9471, 9548, 9625, 9702, 9779,
165  9856, 9933, 10010, 10087, 10164, 10241, 10318, 10395,
166  10472, 10549, 10626, 10703, 10780, 10857, 10934, 11011,
167  11088, 11165, 11242, 11319, 11396, 11473, 11550, 11627,
168  11704, 11781, 11858, 11935, 12012, 12089, 12166, 12243,
169  12320, 12397, 12474, 12551, 12628, 12705, 12782, 12859,
170  12936, 13013, 13090, 13167, 13244, 13321, 13398, 13475,
171  13552, 13629, 13706, 13783, 13860, 13937, 14014, 14091,
172  14168, 14245, 14322, 14399, 14476, 14553, 14630, 14707,
173  14784, 14861, 14938, 15015, 15092, 15169, 15246, 15323,
174  15400, 15477, 15554, 15631, 15708, 15785, 15862, 15939,
175  16016, 16093, 16170, 16247, 16324, 16401, 16478, 16555,
176  16632, 16709, 16786, 16863, 16940, 17017, 17094, 17171,
177  17248, 17325, 17402, 17479, 17556, 17633, 17710, 17787,
178  17864, 17941, 18018, 18095, 18172, 18249, 18326, 18403,
179  18480, 18557, 18634, 18711, 18788, 18865, 18942, 19019,
180  19096, 19173, 19250, 19327, 19404, 19481, 19558, 19635 };
181 static int times150[256] = {
182  0, 150, 300, 450, 600, 750, 900, 1050,
183  1200, 1350, 1500, 1650, 1800, 1950, 2100, 2250,
184  2400, 2550, 2700, 2850, 3000, 3150, 3300, 3450,
185  3600, 3750, 3900, 4050, 4200, 4350, 4500, 4650,
186  4800, 4950, 5100, 5250, 5400, 5550, 5700, 5850,
187  6000, 6150, 6300, 6450, 6600, 6750, 6900, 7050,
188  7200, 7350, 7500, 7650, 7800, 7950, 8100, 8250,
189  8400, 8550, 8700, 8850, 9000, 9150, 9300, 9450,
190  9600, 9750, 9900, 10050, 10200, 10350, 10500, 10650,
191  10800, 10950, 11100, 11250, 11400, 11550, 11700, 11850,
192  12000, 12150, 12300, 12450, 12600, 12750, 12900, 13050,
193  13200, 13350, 13500, 13650, 13800, 13950, 14100, 14250,
194  14400, 14550, 14700, 14850, 15000, 15150, 15300, 15450,
195  15600, 15750, 15900, 16050, 16200, 16350, 16500, 16650,
196  16800, 16950, 17100, 17250, 17400, 17550, 17700, 17850,
197  18000, 18150, 18300, 18450, 18600, 18750, 18900, 19050,
198  19200, 19350, 19500, 19650, 19800, 19950, 20100, 20250,
199  20400, 20550, 20700, 20850, 21000, 21150, 21300, 21450,
200  21600, 21750, 21900, 22050, 22200, 22350, 22500, 22650,
201  22800, 22950, 23100, 23250, 23400, 23550, 23700, 23850,
202  24000, 24150, 24300, 24450, 24600, 24750, 24900, 25050,
203  25200, 25350, 25500, 25650, 25800, 25950, 26100, 26250,
204  26400, 26550, 26700, 26850, 27000, 27150, 27300, 27450,
205  27600, 27750, 27900, 28050, 28200, 28350, 28500, 28650,
206  28800, 28950, 29100, 29250, 29400, 29550, 29700, 29850,
207  30000, 30150, 30300, 30450, 30600, 30750, 30900, 31050,
208  31200, 31350, 31500, 31650, 31800, 31950, 32100, 32250,
209  32400, 32550, 32700, 32850, 33000, 33150, 33300, 33450,
210  33600, 33750, 33900, 34050, 34200, 34350, 34500, 34650,
211  34800, 34950, 35100, 35250, 35400, 35550, 35700, 35850,
212  36000, 36150, 36300, 36450, 36600, 36750, 36900, 37050,
213  37200, 37350, 37500, 37650, 37800, 37950, 38100, 38250 };
214 static int times29[256] = {
215  0, 29, 58, 87, 116, 145, 174, 203,
216  232, 261, 290, 319, 348, 377, 406, 435,
217  464, 493, 522, 551, 580, 609, 638, 667,
218  696, 725, 754, 783, 812, 841, 870, 899,
219  928, 957, 986, 1015, 1044, 1073, 1102, 1131,
220  1160, 1189, 1218, 1247, 1276, 1305, 1334, 1363,
221  1392, 1421, 1450, 1479, 1508, 1537, 1566, 1595,
222  1624, 1653, 1682, 1711, 1740, 1769, 1798, 1827,
223  1856, 1885, 1914, 1943, 1972, 2001, 2030, 2059,
224  2088, 2117, 2146, 2175, 2204, 2233, 2262, 2291,
225  2320, 2349, 2378, 2407, 2436, 2465, 2494, 2523,
226  2552, 2581, 2610, 2639, 2668, 2697, 2726, 2755,
227  2784, 2813, 2842, 2871, 2900, 2929, 2958, 2987,
228  3016, 3045, 3074, 3103, 3132, 3161, 3190, 3219,
229  3248, 3277, 3306, 3335, 3364, 3393, 3422, 3451,
230  3480, 3509, 3538, 3567, 3596, 3625, 3654, 3683,
231  3712, 3741, 3770, 3799, 3828, 3857, 3886, 3915,
232  3944, 3973, 4002, 4031, 4060, 4089, 4118, 4147,
233  4176, 4205, 4234, 4263, 4292, 4321, 4350, 4379,
234  4408, 4437, 4466, 4495, 4524, 4553, 4582, 4611,
235  4640, 4669, 4698, 4727, 4756, 4785, 4814, 4843,
236  4872, 4901, 4930, 4959, 4988, 5017, 5046, 5075,
237  5104, 5133, 5162, 5191, 5220, 5249, 5278, 5307,
238  5336, 5365, 5394, 5423, 5452, 5481, 5510, 5539,
239  5568, 5597, 5626, 5655, 5684, 5713, 5742, 5771,
240  5800, 5829, 5858, 5887, 5916, 5945, 5974, 6003,
241  6032, 6061, 6090, 6119, 6148, 6177, 6206, 6235,
242  6264, 6293, 6322, 6351, 6380, 6409, 6438, 6467,
243  6496, 6525, 6554, 6583, 6612, 6641, 6670, 6699,
244  6728, 6757, 6786, 6815, 6844, 6873, 6902, 6931,
245  6960, 6989, 7018, 7047, 7076, 7105, 7134, 7163,
246  7192, 7221, 7250, 7279, 7308, 7337, 7366, 7395 };
247 
248 
249 /************ parse options and figure out what kind of ILBM to write ************/
250 
251 
252 static int get_int_val ARGS((char *string, char *option, int bot, int top));
253 static int get_compr_type ARGS((char *string));
254 #define NEWDEPTH(pix, table) PPM_ASSIGN((pix), (table)[PPM_GETR(pix)], (table)[PPM_GETG(pix)], (table)[PPM_GETB(pix)])
255 
256 
257 int
259  int argc;
260  char *argv[];
261 {
262  FILE *ifp;
263  int argn, rows, cols, format, colors, nPlanes;
264  int ifmode, forcemode, maxplanes, fixplanes, hambits, mode;
265 #define MAXCOLORS (1<<maxplanes)
266  pixval maxval;
267  colorhist_vector chv;
268  DirectColor dcol;
269  char *mapfile;
270  char *usage =
271 "[-ecs|-aga] [-ham6|-ham8] [-maxplanes|-mp n] [-fixplanes|-fp n]\
272  [-normal|-hamif|-hamforce|-24if|-24force|-dcif|-dcforce|-cmaponly]\
273  [-hambits|-hamplanes n] [-dcbits|-dcplanes r g b] [-hires] [-lace]\
274  [-floyd|-fs] [-compress|-nocompress] [-cmethod none|byterun1]\
275  [-map ppmfile] [-savemem] [ppmfile]";
276 
277  ppm_init(&argc, argv);
278 
279  ifmode = MODE_NONE; forcemode = MODE_NONE;
280  maxplanes = DEF_MAXPLANES; fixplanes = 0;
281  hambits = DEF_HAMPLANES;
282  mapfile = NULL;
283  dcol.r = dcol.g = dcol.b = DEF_DCOLPLANES;
284 
285  argn = 1;
286  while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
287  if( pm_keymatch(argv[argn], "-maxplanes", 4) || pm_keymatch(argv[argn], "-mp", 3) ) {
288  if( ++argn >= argc )
289  pm_usage(usage);
290  maxplanes = get_int_val(argv[argn], argv[argn-1], 1, MAXPLANES);
291  fixplanes = 0;
292  }
293  else
294  if( pm_keymatch(argv[argn], "-fixplanes", 4) || pm_keymatch(argv[argn], "-fp", 3) ) {
295  if( ++argn >= argc )
296  pm_usage(usage);
297  fixplanes = get_int_val(argv[argn], argv[argn-1], 1, MAXPLANES);
298  maxplanes = fixplanes;
299  }
300  else
301  if( pm_keymatch(argv[argn], "-map", 4) ) {
302  if( ++argn >= argc )
303  pm_usage(usage);
304  mapfile = argv[argn];
305  }
306  else
307  if( pm_keymatch(argv[argn], "-cmaponly", 3) ) {
308  forcemode = MODE_CMAP;
309  }
310  else
311  if( pm_keymatch(argv[argn], "-hambits", 5) || pm_keymatch(argv[argn], "-hamplanes", 5) ) {
312  if( ++argn > argc )
313  pm_usage(usage);
314  hambits = get_int_val(argv[argn], argv[argn-1], 3, MAXPLANES);
315  }
316  else
317  if( pm_keymatch(argv[argn], "-ham6", 5) ) {
318  hambits = ECS_HAMPLANES;
319  forcemode = MODE_HAM;
320  }
321  else
322  if( pm_keymatch(argv[argn], "-ham8", 5) ) {
323  hambits = AGA_HAMPLANES;
324  forcemode = MODE_HAM;
325  }
326  else
327  if( pm_keymatch(argv[argn], "-lace", 2) ) {
328 #ifdef ILBM_PCHG
329  slicesize = 2;
330 #endif
332  }
333  else
334  if( pm_keymatch(argv[argn], "-nolace", 4) ) {
335 #ifdef ILBM_PCHG
336  slicesize = 1;
337 #endif
338  viewportmodes &= ~~vmLACE;
339  }
340  else
341  if( pm_keymatch(argv[argn], "-hires", 3) )
343  else
344  if( pm_keymatch(argv[argn], "-nohires", 5) )
345  viewportmodes &= ~~vmHIRES;
346  else
347  if( pm_keymatch(argv[argn], "-ecs", 2) ) {
348  maxplanes = ECS_MAXPLANES;
349  hambits = ECS_HAMPLANES;
350  }
351  else
352  if( pm_keymatch(argv[argn], "-aga", 2) ) {
353  maxplanes = AGA_MAXPLANES;
354  hambits = AGA_HAMPLANES;
355  }
356  else
357  if( pm_keymatch(argv[argn], "-hamif", 5) )
358  ifmode = MODE_HAM;
359  else
360  if( pm_keymatch(argv[argn], "-nohamif", 7) ) {
361  if( ifmode == MODE_HAM )
362  ifmode = MODE_NONE;
363  }
364  else
365  if( pm_keymatch(argv[argn], "-hamforce", 5) )
366  forcemode = MODE_HAM;
367  else
368  if( pm_keymatch(argv[argn], "-nohamforce", 7) ) {
369  if( forcemode == MODE_HAM )
370  forcemode = MODE_NONE;
371  }
372  else
373  if( pm_keymatch(argv[argn], "-24if", 4) )
374  ifmode = MODE_24;
375  else
376  if( pm_keymatch(argv[argn], "-no24if", 6) ) {
377  if( ifmode == MODE_24 )
378  ifmode = MODE_NONE;
379  }
380  else
381  if( pm_keymatch(argv[argn], "-24force", 4) )
382  forcemode = MODE_24;
383  else
384  if( pm_keymatch(argv[argn], "-no24force", 6) ) {
385  if( forcemode == MODE_24 )
386  forcemode = MODE_NONE;
387  }
388  else
389  if( pm_keymatch(argv[argn], "-dcif", 4) ) {
390  ifmode = MODE_DIRECT;
391  }
392  else
393  if( pm_keymatch(argv[argn], "-nodcif", 6) ) {
394  if( ifmode == MODE_DIRECT )
395  ifmode = MODE_NONE;
396  }
397  else
398  if( pm_keymatch(argv[argn], "-dcforce", 4) ) {
399  forcemode = MODE_DIRECT;
400  }
401  else
402  if( pm_keymatch(argv[argn], "-nodcforce", 6) ) {
403  if( forcemode == MODE_DIRECT )
404  forcemode = MODE_NONE;
405  }
406  else
407  if( pm_keymatch(argv[argn], "-dcbits", 4) || pm_keymatch(argv[argn], "-dcplanes", 4) ) {
408  char *option = argv[argn];
409 
410  if( ++argn >= argc )
411  pm_usage(usage);
412  dcol.r = (unsigned char) get_int_val(argv[argn], option, 1, MAXPLANES);
413  if( ++argn >= argc )
414  pm_usage(usage);
415  dcol.g = (unsigned char) get_int_val(argv[argn], option, 1, MAXPLANES);
416  if( ++argn >= argc )
417  pm_usage(usage);
418  dcol.b = (unsigned char) get_int_val(argv[argn], option, 1, MAXPLANES);
419  }
420  else
421  if( pm_keymatch(argv[argn], "-normal", 4) ) {
422  ifmode = forcemode = MODE_NONE;
424  }
425  else
426  if( pm_keymatch(argv[argn], "-compress", 3) ) {
427  compr_force = 1;
428  if( compr_type == cmpNone )
430  cmpByteRun1 :
432  }
433  else
434  if( pm_keymatch(argv[argn], "-nocompress", 4) ) {
435  compr_force = 0;
437  }
438  else
439  if( pm_keymatch(argv[argn], "-cmethod", 4) ) {
440  if( ++argn >= argc )
441  pm_usage(usage);
443  }
444  else
445  if( pm_keymatch(argv[argn], "-savemem", 2) )
446  savemem = 1;
447  else
448  if( pm_keymatch(argv[argn], "-fs1", 4) ) /* EXPERIMENTAL */
449  floyd = 2;
450  else
451  if( pm_keymatch(argv[argn], "-floyd", 3) || pm_keymatch(argv[argn], "-fs", 3) )
452  floyd = 1;
453  else
454  if( pm_keymatch(argv[argn], "-nofloyd", 5) || pm_keymatch(argv[argn], "-nofs", 5) )
455  floyd = 0;
456  else
457  pm_usage(usage);
458  ++argn;
459  }
460 
461  if( argn < argc ) {
462  ifp = pm_openr(argv[argn]);
463  ++argn;
464  }
465  else
466  ifp = stdin;
467 
468  if( argn != argc )
469  pm_usage( usage );
470 
471  if( forcemode != MODE_NONE && mapfile != NULL )
472  pm_message("warning - mapfile only used for normal ILBMs");
473 
474  mode = forcemode;
475  switch( forcemode ) {
476  case MODE_HAM:
477  /* grayscale colormap for now - we don't need to read the whole
478  file into memory and can use row-by-row operation */
479  init_read(ifp, &cols, &rows, &maxval, &format, 0);
480  pm_message("hamforce option used - proceeding to write a HAM%d file", hambits);
481  break;
482  case MODE_24:
483  init_read(ifp, &cols, &rows, &maxval, &format, 0);
484  pm_message("24force option used - proceeding to write a 24bit file");
485  break;
486  case MODE_DIRECT:
487  init_read(ifp, &cols, &rows, &maxval, &format, 0);
488  pm_message("dcforce option used - proceeding to write a %d:%d:%d direct color file",
489  dcol.r, dcol.g, dcol.b);
490  break;
491  case MODE_CMAP:
492  /* must read the whole file into memory */
493  init_read(ifp, &cols, &rows, &maxval, &format, 1);
494 
495  /* Figure out the colormap. */
496  pm_message("computing colormap...");
498  if( chv == (colorhist_vector)NULL )
499  pm_error("too many colors - try doing a 'ppmquant %d'", MAXCMAPCOLORS);
500  pm_message("%d colors found", colors);
501  break;
502  default:
503  /* must read the whole file into memory */
504  init_read(ifp, &cols, &rows, &maxval, &format, 1);
505 
506  /* Figure out the colormap. */
507  if( mapfile ) {
508  int mapcols, maprows, row, col;
509  pixel **mappixels, *pP;
510  pixval mapmaxval;
511  FILE *mapfp;
512 
513  pm_message("reading colormap file...");
514  mapfp = pm_openr(mapfile);
515  mappixels = ppm_readppm(mapfp, &mapcols, &maprows, &mapmaxval);
516  pm_close(mapfp);
517  if( mapcols == 0 || maprows == 0 )
518  pm_error("null colormap??");
519 
520  /* if the maxvals of the ppmfile and the mapfile are the same,
521  * then the scaling to MAXCOLVAL (if necessary) will be done by
522  * the write_std_cmap() function.
523  * Otherwise scale them both to MAXCOLVAL.
524  */
525  if( maxval != mapmaxval ) {
526  if( mapmaxval != MAXCOLVAL ) {
527  pixval *table;
528  pm_message("colormap maxval is not %d - rescaling colormap...", MAXCOLVAL);
529  table = make_val_table(mapmaxval, MAXCOLVAL);
530  for( row = 0; row < maprows; ++row )
531  for( col = 0, pP = mappixels[row]; col < mapcols; ++col, ++pP )
532  NEWDEPTH(*pP, table); /* was PPM_DEPTH( *pP, *pP, mapmaxval, MAXCOLVAL ); */
533  mapmaxval = MAXCOLVAL;
534  free(table);
535  }
536 
537  if( maxval != mapmaxval ) {
538  pixval *table;
539  pm_message("rescaling colors of picture...");
540  table = make_val_table(maxval, mapmaxval);
541  for( row = 0; row < rows; ++row )
542  for( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
543  NEWDEPTH(*pP, table); /* was PPM_DEPTH( *pP, *pP, maxval, mapmaxval ); */
544  maxval = mapmaxval;
545  free(table);
546  }
547  }
548 
549  pm_message("computing colormap...");
550  chv = ppm_computecolorhist(mappixels, mapcols, maprows, MAXCMAPCOLORS, &colors);
551  ppm_freearray(mappixels, maprows);
552  if( chv == (colorhist_vector)0 )
553  pm_error("too many colors in colormap!");
554  pm_message("%d colors found in colormap", colors);
555 
556  nPlanes = fixplanes = maxplanes = colorstobpp(colors);
557  }
558  else { /* no mapfile */
559  pm_message("computing colormap...");
561  if( chv == (colorhist_vector)0 ) {
562  /* too many colors */
563  mode = ifmode;
564  switch( ifmode ) {
565  case MODE_HAM:
566  pm_message("too many colors - proceeding to write a HAM%d file", hambits);
567  pm_message("if you want a non-HAM file, try doing a 'ppmquant %d'", MAXCOLORS);
568  break;
569  case MODE_24:
570  pm_message("too many colors - proceeding to write a 24bit file" );
571  pm_message("if you want a non-24bit file, try doing a 'ppmquant %d'", MAXCOLORS);
572  break;
573  case MODE_DIRECT:
574  pm_message("too many colors - proceeding to write a %d:%d:%d direct color file",
575  dcol.r, dcol.g, dcol.b);
576  pm_message("if you want a non-direct-color file, try doing a 'ppmquant %d'", MAXCOLORS);
577  break;
578  default:
579  pm_message( "too many colors for %d planes", maxplanes );
580  pm_message( "either use -hamif/-hamforce/-24if/-24force/-dcif/-dcforce/-maxplanes,");
581  pm_error( "or try doing a 'ppmquant %d'", MAXCOLORS );
582  break;
583  }
584  }
585  else {
586  pm_message("%d colors found", colors);
587  nPlanes = colorstobpp(colors);
588  if( fixplanes > nPlanes )
589  nPlanes = fixplanes;
590  }
591  }
592  break;
593  }
594 
595  if( mode != MODE_CMAP ) {
596  register int i;
597  coded_rowbuf = MALLOC(RowBytes(cols), unsigned char);
598  for( i = 0; i < RowBytes(cols); i++ )
599  coded_rowbuf[i] = 0;
600  if( DO_COMPRESS )
601  compr_rowbuf = MALLOC(WORSTCOMPR(RowBytes(cols)), unsigned char);
602  }
603 
604  switch( mode ) {
605  case MODE_HAM: {
606  int nocolor;
607 
608  nocolor = !(PPM_FORMAT_TYPE(format) == PPM_TYPE);
609  if( nocolor )
610  floyd = 0;
611 
612  viewportmodes |= vmHAM;
613  ppm_to_ham(ifp, cols, rows, maxval, hambits, nocolor);
614  }
615  break;
616  case MODE_24:
618  break;
619  case MODE_DIRECT:
620  ppm_to_direct(ifp, cols, rows, maxval, &dcol);
621  break;
622  case MODE_CMAP:
623  ppm_to_cmap(maxval, chv, colors);
624  break;
625  default:
626  if( mapfile == NULL )
627  floyd = 0; /* would only slow down conversion */
628  ppm_to_std(ifp, cols, rows, maxval, chv, colors, nPlanes);
629  break;
630  }
631  pm_close(ifp);
632  exit(0);
633  /*NOTREACHED*/
634 }
635 
636 
637 static int
638 get_int_val(string, option, bot, top)
639  char *string, *option;
640  int bot, top;
641 {
642  int val;
643 
644  if( sscanf(string, "%d", &val) != 1 )
645  pm_error("option \"%s\" needs integer argument", option);
646 
647  if( val < bot || val > top )
648  pm_error("option \"%s\" argument value out of range (%d..%d)", option, bot, top);
649 
650  return val;
651 }
652 
653 
654 static int
656  char *string;
657 {
658  int i;
659 
660  for( i = 0; i <= cmpMAXKNOWN; i++ ) {
661  if( strcmp(string, cmpNAME[i]) == 0 )
662  return i;
663  }
664  pm_message("unknown compression method: %s", string);
665  pm_message("using default compression (%s)", cmpNAME[DEF_COMPRESSION]);
666  return DEF_COMPRESSION;
667 }
668 
669 
670 /************ colormap file ************/
671 
672 static void
674  int maxval;
675  colorhist_vector chv;
676  int colors;
677 {
678  int formsize, cmapsize;
679 
680  cmapsize = colors * 3;
681 
682  formsize =
683  4 + /* ILBM */
684  4 + 4 + BitMapHeaderSize + /* BMHD size header */
685  4 + 4 + cmapsize + PAD(cmapsize); /* CMAP size colormap */
686 
687  write_form_ilbm(formsize);
688  write_bmhd(0, 0, 0);
690 }
691 
692 /************ HAM ************/
693 
694 static long do_ham_body ARGS((FILE *ifp, FILE *ofp, int cols, int rows, pixval maxval, pixval hammaxval, int nPlanes, int colbits, int no));
695 
696 static void
697 ppm_to_ham(fp, cols, rows, maxval, hambits, nocolor)
698  FILE *fp;
699  int cols, rows, maxval, hambits, nocolor;
700 {
701  int colors, colbits, nPlanes, i, hammaxval;
702  long oldsize, bodysize, formsize, cmapsize;
703  pixval *table = NULL;
704 
705  colbits = hambits-2;
706  colors = 1 << colbits;
707  hammaxval = pm_bitstomaxval(colbits);
708  nPlanes = hambits;
709  cmapsize = colors * 3;
710 
711  bodysize = oldsize = rows * nPlanes * RowBytes(cols);
712  if( DO_COMPRESS ) {
713  alloc_body_array(rows, nPlanes);
714  bodysize = do_ham_body(fp, NULL, cols, rows, maxval, hammaxval, nPlanes, colbits, nocolor);
715  if( bodysize > oldsize )
716  pm_message("warning - %s compression increases BODY size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
717  else
718  pm_message("BODY compression (%s): %d%%", cmpNAME[compr_type], 100*(oldsize-bodysize)/oldsize);
719  }
720 
721 
722  formsize =
723  4 + /* ILBM */
724  4 + 4 + BitMapHeaderSize + /* BMHD size header */
725  CAMGSIZE + /* 0 or CAMG size val */
726  4 + 4 + cmapsize + PAD(cmapsize) + /* CMAP size colormap */
727  4 + 4 + bodysize + PAD(bodysize); /* BODY size data */
728 
729  write_form_ilbm(formsize);
730  write_bmhd(cols, rows, nPlanes);
731  write_camg();
732 
733  /* write grayscale colormap */
734  put_fourchars("CMAP");
736  table = make_val_table(hammaxval, MAXCOLVAL);
737  for( i = 0; i < colors; i++ ) {
738  put_byte( table[i] ); /* red */
739  put_byte( table[i] ); /* green */
740  put_byte( table[i] ); /* blue */
741  }
742  free(table);
743  if( odd(cmapsize) )
744  put_byte(0);
745 
746  /* write body */
747  put_fourchars("BODY");
748  put_big_long(bodysize);
749  if( DO_COMPRESS )
750  write_body();
751  else
752  do_ham_body(fp, stdout, cols, rows, maxval, hammaxval, nPlanes, colbits, nocolor);
753  if( odd(bodysize) )
754  put_byte(0);
755 }
756 
757 
758 static long
760  pixval maxval, pixval hammaxval,
761  int nPlanes, int colbits, int nocolor)
762 {
763  register int col, row;
764  pixel *pP;
765  pixval *table = NULL;
766  rawtype *raw_rowbuf;
767  floydinfo *fi;
768  long bodysize = 0;
769 
770  raw_rowbuf = MALLOC(cols, rawtype);
771 
772  if( hammaxval != maxval )
773  table = make_val_table(maxval, hammaxval);
774 
775  if( floyd ) {
776  fi = init_floyd(cols, maxval, 0);
777  }
778 
779  for( row = 0; row < rows; row++ ) {
780  register int noprev, pr, pg, pb, r, g, b, l;
781  int fpr, fpg, fpb; /* unscaled previous color values, for floyd */
782 
783  pP = next_pixrow(ifp, row);
784  if( floyd )
785  begin_floyd_row(fi, pP);
786 
787  noprev = 1;
788  for( col = 0; col < cols; col++, pP++ ) {
789  int fr, fg, fb, fl; /* unscaled color values, for floyd */
790  if( floyd )
791  pP = next_floyd_pixel(fi);
792 
793  r = fr = PPM_GETR( *pP );
794  g = fg = PPM_GETG( *pP );
795  b = fb = PPM_GETB( *pP );
796  if( maxval <= 255 ) /* Use fast approximation to 0.299 r + 0.587 g + 0.114 b. */
797  l = fl = (int)((times77[r] + times150[g] + times29[b] + 128) >> 8);
798  else /* Can't use fast approximation, so fall back on floats. */
799  l = fl = (int)(PPM_LUMIN(*pP) + 0.5); /* -IUW added '+ 0.5' */
800 
801  if( table ) {
802  r = table[r];
803  g = table[g];
804  b = table[b];
805  l = table[l];
806  }
807 
808  if( noprev || nocolor ) {
809  /* No previous pixels, gotta use the gray option. */
810  raw_rowbuf[col] = l /* + (HAMCODE_CMAP << colbits) */;
811  pr = pg = pb = l;
812  fpr = fpg = fpb = fl;
813  noprev = 0;
814  }
815  else {
816  register int dred, dgreen, dblue, dgray;
817  /* Compute distances for the four options. */
818  dred = abs( g - pg ) + abs( b - pb );
819  dgreen = abs( r - pr ) + abs( b - pb );
820  dblue = abs( r - pr ) + abs( g - pg );
821  dgray = abs( r - l ) + abs( g - l ) + abs( b - l );
822 
823  /* simply doing raw_rowbuf[col] = ...
824  * is ok here because there is no fs-alternation performed
825  * for HAM. Otherwise we would have to do
826  * if( floyd ) raw_rowbuf[fi->col] = ...
827  * else raw_rowbuf[col] = ...
828  */
829  if( dgray <= dred && dgray <= dgreen && dgray <= dblue ) { /* -IUW '<=' was '<' */
830  raw_rowbuf[col] = l /* + (HAMCODE_CMAP << colbits) */;
831  pr = pg = pb = l;
832  fpr = fpg = fpb = fl;
833  }
834  else
835  if( dblue <= dred && dblue <= dgreen ) {
836  raw_rowbuf[col] = b + (HAMCODE_BLUE << colbits);
837  pb = b;
838  fpb = fb;
839  }
840  else
841  if( dred <= dgreen ) {
842  raw_rowbuf[col] = r + (HAMCODE_RED << colbits);
843  pr = r;
844  fpr = fr;
845  }
846  else {
847  raw_rowbuf[col] = g + (HAMCODE_GREEN << colbits);
848  pg = g;
849  fpg = fg;
850  }
851  }
852  if( floyd )
853  update_floyd_pixel(fi, fpr, fpg, fpb);
854  }
855  bodysize += encode_row(ofp, raw_rowbuf, cols, nPlanes);
856  if( floyd )
857  end_floyd_row(fi);
858  }
859  /* clean up */
860  if( table )
861  free(table);
862  free(raw_rowbuf);
863  if( floyd )
864  free_floyd(fi);
865 
866  return bodysize;
867 }
868 
869 /************ 24bit ************/
870 
871 static long do_24_body ARGS((FILE *ifp, FILE *ofp, int cols, int rows, pixval maxval));
872 
873 static void
875  FILE *fp;
876  int cols, rows, maxval;
877 {
878  int nPlanes;
879  long bodysize, oldsize, formsize;
880 
881  nPlanes = 24;
882 
883  bodysize = oldsize = rows * nPlanes * RowBytes(cols);
884  if( DO_COMPRESS ) {
885  alloc_body_array(rows, nPlanes);
886  bodysize = do_24_body(fp, NULL, cols, rows, maxval);
887  if( bodysize > oldsize )
888  pm_message("warning - %s compression increases BODY size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
889  else
890  pm_message("BODY compression (%s): %d%%", cmpNAME[compr_type], 100*(oldsize-bodysize)/oldsize);
891 #if 0
892  if( bodysize > oldsize && !compr_force ) {
893  pm_message("%s compression would increase body size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
894  pm_message("writing uncompressed image");
895  free_body_array();
897  bodysize = oldsize;
898  }
899 #endif
900  }
901 
902 
903  formsize =
904  4 + /* ILBM */
905  4 + 4 + BitMapHeaderSize + /* BMHD size header */
906  CAMGSIZE + /* 0 or CAMG size val */
907  4 + 4 + bodysize + PAD(bodysize); /* BODY size data */
908 
909  write_form_ilbm(formsize);
910  write_bmhd(cols, rows, nPlanes);
911  write_camg();
912 
913  /* write body */
914  put_fourchars("BODY");
915  put_big_long(bodysize);
916  if( DO_COMPRESS )
917  write_body();
918  else
920  if( odd(bodysize) )
921  put_byte(0);
922 }
923 
924 
925 static long
927 {
928  register int row, col;
929  pixel *pP;
930  pixval *table = NULL;
931  long bodysize = 0;
932  rawtype *redbuf, *greenbuf, *bluebuf;
933 
934  redbuf = MALLOC(cols, rawtype);
935  greenbuf = MALLOC(cols, rawtype);
936  bluebuf = MALLOC(cols, rawtype);
937 
938  if( maxval != MAXCOLVAL ) {
939  pm_message("maxval is not %d - automatically rescaling colors", MAXCOLVAL);
941  }
942 
943  for( row = 0; row < rows; row++ ) {
944  pP = next_pixrow(ifp, row);
945  if( table ) {
946  for( col = 0; col < cols; col++, pP++ ) {
947  redbuf[col] = table[PPM_GETR(*pP)];
948  greenbuf[col] = table[PPM_GETG(*pP)];
949  bluebuf[col] = table[PPM_GETB(*pP)];
950  }
951  }
952  else {
953  for( col = 0; col < cols; col++, pP++ ) {
954  redbuf[col] = PPM_GETR(*pP);
955  greenbuf[col] = PPM_GETG(*pP);
956  bluebuf[col] = PPM_GETB(*pP);
957  }
958  }
959  bodysize += encode_row(ofp, redbuf, cols, 8);
960  bodysize += encode_row(ofp, greenbuf, cols, 8);
961  bodysize += encode_row(ofp, bluebuf, cols, 8);
962  }
963  /* clean up */
964  if( table )
965  free(table);
966  free(redbuf);
967  free(greenbuf);
968  free(bluebuf);
969 
970  return bodysize;
971 }
972 
973 
974 /************ direct color ************/
975 
976 static long do_direct_body ARGS((FILE *ifp, FILE *ofp, int cols, int rows, pixval maxval, DirectColor *dcol));
977 
978 static void
980  FILE *fp;
981  int cols, rows, maxval;
982  DirectColor *dcol;
983 {
984  int nPlanes;
985  long formsize, bodysize, oldsize;
986 
987  nPlanes = dcol->r + dcol->g + dcol->b;
988 
989  bodysize = oldsize = rows * nPlanes * RowBytes(cols);
990  if( DO_COMPRESS ) {
991  alloc_body_array(rows, nPlanes);
992  bodysize = do_direct_body(fp, NULL, cols, rows, maxval, dcol);
993  if( bodysize > oldsize )
994  pm_message("warning - %s compression increases BODY size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
995  else
996  pm_message("BODY compression (%s): %d%%", cmpNAME[compr_type], 100*(oldsize-bodysize)/oldsize);
997 #if 0
998  if( bodysize > oldsize && !compr_force ) {
999  pm_message("%s compression would increase body size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
1000  pm_message("writing uncompressed image");
1001  free_body_array();
1002  compr_type = cmpNone;
1003  bodysize = oldsize;
1004  }
1005 #endif
1006  }
1007 
1008  formsize =
1009  4 + /* ILBM */
1010  4 + 4 + BitMapHeaderSize + /* BMHD size header */
1011  CAMGSIZE + /* 0 or CAMG size val */
1012  4 + 4 + DirectColorSize + /* DCOL size description */
1013  4 + 4 + bodysize + PAD(bodysize); /* BODY size data */
1014 
1015  write_form_ilbm(formsize);
1016  write_bmhd(cols, rows, nPlanes);
1017  write_camg();
1018 
1019  /* write DCOL */
1020  put_fourchars("DCOL");
1022  put_byte(dcol->r);
1023  put_byte(dcol->g);
1024  put_byte(dcol->b);
1025  put_byte(0); /* pad */
1026 
1027  /* write body */
1028  put_fourchars("BODY");
1029  put_big_long(bodysize);
1030  if( DO_COMPRESS )
1031  write_body();
1032  else
1033  do_direct_body(fp, stdout, cols, rows, maxval, dcol);
1034  if( odd(bodysize) )
1035  put_byte(0);
1036 }
1037 
1038 
1039 static long
1041  DirectColor *dcol)
1042 {
1043  register int row, col;
1044  pixel *pP;
1045  pixval *redtable = NULL, *greentable = NULL, *bluetable = NULL;
1046  pixval redmaxval, greenmaxval, bluemaxval;
1047  rawtype *redbuf, *greenbuf, *bluebuf;
1048  long bodysize = 0;
1049 
1050  redbuf = MALLOC(cols, rawtype);
1051  greenbuf = MALLOC(cols, rawtype);
1052  bluebuf = MALLOC(cols, rawtype);
1053 
1054  redmaxval = pm_bitstomaxval(dcol->r);
1055  if( redmaxval != maxval ) {
1056  pm_message("rescaling reds to %d bits", dcol->r);
1057  redtable = make_val_table(maxval, redmaxval);
1058  }
1059  greenmaxval = pm_bitstomaxval(dcol->g);
1060  if( greenmaxval != maxval ) {
1061  pm_message("rescaling greens to %d bits", dcol->g);
1062  greentable = make_val_table(maxval, greenmaxval);
1063  }
1064  bluemaxval = pm_bitstomaxval(dcol->b);
1065  if( bluemaxval != maxval ) {
1066  pm_message("rescaling blues to %d bits", dcol->b);
1067  bluetable = make_val_table(maxval, bluemaxval);
1068  }
1069 
1070  for( row = 0; row < rows; row++ ) {
1071  pP = next_pixrow(ifp, row);
1072  for( col = 0; col < cols; col++, pP++ ) {
1073  register pixval r, g, b;
1074 
1075  r = PPM_GETR(*pP); if( redtable ) r = redtable[r];
1076  g = PPM_GETG(*pP); if( greentable ) g = greentable[g];
1077  b = PPM_GETB(*pP); if( bluetable ) b = bluetable[b];
1078 
1079  redbuf[col] = r;
1080  greenbuf[col] = g;
1081  bluebuf[col] = b;
1082  }
1083  bodysize += encode_row(ofp, redbuf, cols, dcol->r);
1084  bodysize += encode_row(ofp, greenbuf, cols, dcol->g);
1085  bodysize += encode_row(ofp, bluebuf, cols, dcol->b);
1086  }
1087  /* clean up */
1088  if( redtable )
1089  free(redtable);
1090  if( greentable )
1091  free(greentable);
1092  if( bluetable )
1093  free(bluetable);
1094  free(redbuf);
1095  free(greenbuf);
1096  free(bluebuf);
1097 
1098  return bodysize;
1099 }
1100 
1101 
1102 /************ normal colormapped ************/
1103 
1104 static long do_std_body ARGS((FILE *ifp, FILE *ofp, int cols, int rows, pixval maxval, colorhist_vector chv, int colors, int nPlanes));
1105 
1106 static void
1107 ppm_to_std(fp, cols, rows, maxval, chv, colors, nPlanes)
1108  FILE *fp;
1109  int cols, rows, maxval;
1110  colorhist_vector chv;
1111  int colors, nPlanes;
1112 {
1113  long formsize, cmapsize, bodysize, oldsize;
1114 
1115  bodysize = oldsize = rows * nPlanes * RowBytes(cols);
1116  if( DO_COMPRESS ) {
1117  alloc_body_array(rows, nPlanes);
1118  bodysize = do_std_body(fp, NULL, cols, rows, maxval, chv, colors, nPlanes);
1119  if( bodysize > oldsize )
1120  pm_message("warning - %s compression increases BODY size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
1121  else
1122  pm_message("BODY compression (%s): %d%%", cmpNAME[compr_type], 100*(oldsize-bodysize)/oldsize);
1123 #if 0
1124  if( bodysize > oldsize && !compr_force ) {
1125  pm_message("%s compression would increase body size by %d%%", cmpNAME[compr_type], 100*(bodysize-oldsize)/oldsize);
1126  pm_message("writing uncompressed image");
1127  free_body_array();
1128  compr_type = cmpNone;
1129  bodysize = oldsize;
1130  }
1131 #endif
1132  }
1133 
1134  cmapsize = colors * 3;
1135 
1136  formsize =
1137  4 + /* ILBM */
1138  4 + 4 + BitMapHeaderSize + /* BMHD size header */
1139  CAMGSIZE + /* 0 or CAMG size val */
1140  4 + 4 + cmapsize + PAD(cmapsize) + /* CMAP size colormap */
1141  4 + 4 + bodysize + PAD(bodysize); /* BODY size data */
1142 
1143  write_form_ilbm(formsize);
1144  write_bmhd(cols, rows, nPlanes);
1145  write_camg();
1146  write_std_cmap(chv, colors, maxval);
1147 
1148  /* write body */
1149  put_fourchars("BODY");
1150  put_big_long(bodysize);
1151  if( DO_COMPRESS )
1152  write_body();
1153  else
1154  do_std_body(fp, stdout, cols, rows, maxval, chv, colors, nPlanes);
1155  if( odd(bodysize) )
1156  put_byte(0);
1157 }
1158 
1159 
1160 static long
1162  pixval maxval, colorhist_vector chv, int colors, int nPlanes)
1163 {
1165  register int row, col;
1166  pixel *pP;
1167  rawtype *raw_rowbuf;
1168  floydinfo *fi;
1169  long bodysize = 0;
1170  short usehash = !savemem;
1171 
1172  raw_rowbuf = MALLOC(cols, rawtype);
1173 
1174  /* Make a hash table for fast color lookup. */
1176 
1177  if( floyd )
1178  fi = init_floyd(cols, maxval, 1);
1179 
1180  for( row = 0; row < rows; row++ ) {
1181  pP = next_pixrow(ifp, row);
1182  if( floyd )
1183  begin_floyd_row(fi, pP);
1184 
1185  for( col = 0; col < cols; col++, pP++ ) {
1186  int ind;
1187 
1188  if( floyd )
1189  pP = next_floyd_pixel(fi);
1190 
1191  /* Check hash table to see if we have already matched this color. */
1192  ind = ppm_lookupcolor(cht, pP);
1193  if( ind == -1 ) {
1194  ind = closest_color(chv, colors, maxval, pP); /* No; search colormap for closest match. */
1195  if( usehash ) {
1196  if( ppm_addtocolorhash(cht, pP, ind) < 0 ) {
1197  pm_message("out of memory adding to hash table, proceeding without it");
1198  usehash = 0;
1199  }
1200  }
1201  }
1202  if( floyd ) {
1203  raw_rowbuf[fi->col] = ind;
1204  update_floyd_pixel(fi, (int)PPM_GETR(chv[ind].color), (int)PPM_GETG(chv[ind].color), (int)PPM_GETB(chv[ind].color));
1205  }
1206  else
1207  raw_rowbuf[col] = ind;
1208  }
1209  if( floyd )
1210  end_floyd_row(fi);
1211  bodysize += encode_row(ofp, raw_rowbuf, cols, nPlanes);
1212  }
1213  /* clean up */
1214  free(raw_rowbuf);
1216  if( floyd )
1217  free_floyd(fi);
1218 
1219  return bodysize;
1220 }
1221 
1222 /************ multipalette ************/
1223 
1224 #ifdef ILBM_PCHG
1225 static pixel *ppmslice[2]; /* need 2 for laced ILBMs, else 1 */
1226 
1227 void ppm_to_pchg()
1228 {
1229 /*
1230  read first slice
1231  build a colormap from this slice
1232  select upto <maxcolors> colors
1233  build colormap from selected colors
1234  map slice to colormap
1235  write slice
1236  while( !finished ) {
1237  read next slice
1238  compute distances for each pixel and select upto
1239  <maxchangesperslice> unused colors in this slice
1240  modify selected colors to the ones with maximum(?) distance
1241  map slice to colormap
1242  write slice
1243  }
1244 
1245 
1246  for HAM use a different mapping:
1247  compute distance to closest color in colormap
1248  if( there is no matching color in colormap ) {
1249  compute distances for the three "modify" cases
1250  use the shortest distance from the four cases
1251  }
1252 */
1253 }
1254 #endif
1255 
1256 /************ ILBM functions ************/
1257 
1258 static void
1260  colorhist_vector chv;
1261  int colors, maxval;
1262 {
1263  int cmapsize, i;
1264 
1265  cmapsize = 3 * colors;
1266 
1267  /* write colormap */
1268  put_fourchars("CMAP");
1270  if( maxval != MAXCOLVAL ) {
1271  pixval *table;
1272  pm_message("maxval is not %d - automatically rescaling colors", MAXCOLVAL);
1274  for( i = 0; i < colors; i++ ) {
1275  put_byte(table[PPM_GETR(chv[i].color)]);
1276  put_byte(table[PPM_GETG(chv[i].color)]);
1277  put_byte(table[PPM_GETB(chv[i].color)]);
1278  }
1279  free(table);
1280  }
1281  else {
1282  for( i = 0; i < colors; i++ ) {
1283  put_byte(PPM_GETR(chv[i].color));
1284  put_byte(PPM_GETG(chv[i].color));
1285  put_byte(PPM_GETB(chv[i].color));
1286  }
1287  }
1288  if( odd(cmapsize) )
1289  put_byte(0);
1290 }
1291 
1292 
1293 static void
1295  int size;
1296 {
1297  put_fourchars("FORM");
1298  put_big_long(size);
1299  put_fourchars("ILBM");
1300 }
1301 
1302 
1303 static void
1305  int cols, rows, nPlanes;
1306 {
1307  unsigned int xasp = 10, yasp = 10;
1308 
1309  if( viewportmodes & vmLACE )
1310  xasp *= 2;
1311  if( viewportmodes & vmHIRES )
1312  yasp *= 2;
1313 
1314  put_fourchars("BMHD");
1316 
1319  put_big_short(0); /* x-offset */
1320  put_big_short(0); /* y-offset */
1321  put_byte(nPlanes); /* no of planes */
1322  put_byte(mskNone); /* masking type */
1323  put_byte((unsigned char)compr_type); /* compression type */
1324  put_byte(0); /* pad1 */
1325  put_big_short(0); /* tranparentColor */
1326  put_byte(xasp); /* x-aspect */
1327  put_byte(yasp); /* y-aspect */
1328  put_big_short(cols); /* pageWidth */
1329  put_big_short(rows); /* pageHeight */
1330 }
1331 
1332 
1333 /* encode algorithm by Johan Widen (jw@jwdata.se) */
1334 const unsigned char ppmtoilbm_bitmask[] = {1, 2, 4, 8, 16, 32, 64, 128};
1335 
1336 static int
1337 encode_row(outfile, rawrow, cols, nPlanes)
1338  FILE *outfile; /* if non-NULL, write uncompressed row to this file */
1339  rawtype *rawrow;
1340  int cols, nPlanes;
1341 {
1342  int plane, bytes;
1343  long retbytes = 0;
1344 
1345  bytes = RowBytes(cols);
1346 
1347  /* Encode and write raw bytes in plane-interleaved form. */
1348  for( plane = 0; plane < nPlanes; plane++ ) {
1349  register int col, cbit;
1350  register rawtype *rp;
1351  register unsigned char *cp;
1352  int mask;
1353 
1354  mask = 1 << plane;
1355  cbit = -1;
1356  cp = coded_rowbuf-1;
1357  rp = rawrow;
1358  for( col = 0; col < cols; col++, cbit--, rp++ ) {
1359  if( cbit < 0 ) {
1360  cbit = 7;
1361  *++cp = 0;
1362  }
1363  if( *rp & mask )
1364  *cp |= ppmtoilbm_bitmask[cbit];
1365  }
1366  if( outfile ) {
1367  retbytes += bytes;
1368  if( fwrite(coded_rowbuf, 1, bytes, stdout) != bytes )
1369  pm_error("write error");
1370  }
1371  else
1372  retbytes += compress_row(bytes);
1373  }
1374  return retbytes;
1375 }
1376 
1377 
1378 static int
1380  int bytes;
1381 {
1382  static int count;
1383  int newbytes;
1384 
1385  /* if new compression methods are defined, do a switch here */
1386  newbytes = runbyte1(bytes);
1387 
1388  if( savemem ) {
1389  ilbm_body[count].row = MALLOC(newbytes, unsigned char);
1390  bcopy(compr_rowbuf, ilbm_body[count].row, newbytes);
1391  }
1392  else {
1394  compr_rowbuf = MALLOC(WORSTCOMPR(bytes), unsigned char);
1395  }
1396  ilbm_body[count].len = newbytes;
1397  ++count;
1398 
1399  return newbytes;
1400 }
1401 
1402 
1403 static void
1405 {
1406  bodyrow *p;
1407 
1408  for( p = ilbm_body; p->row != NULL; p++ ) {
1409  if( fwrite(p->row, 1, p->len, stdout) != p->len )
1410  pm_error("write error");
1411  }
1412  /* pad byte (if neccessary) is written by do_xxx_body() function */
1413 }
1414 
1415 
1416 static void
1418 {
1419  if( viewportmodes ) {
1420  put_fourchars("CAMG");
1423  }
1424 }
1425 
1426 
1427 /************ compression ************/
1428 
1429 
1430 /* runbyte1 algorithm by Robert A. Knop (rknop@mop.caltech.edu) */
1431 static int
1433  int size;
1434 {
1435  int in,out,count,hold;
1436  register unsigned char *inbuf = coded_rowbuf;
1437  register unsigned char *outbuf = compr_rowbuf;
1438 
1439 
1440  in=out=0;
1441  while( in<size ) {
1442  if( (in<size-1) && (inbuf[in]==inbuf[in+1]) ) { /*Begin replicate run*/
1443  for( count=0,hold=in; in<size && inbuf[in]==inbuf[hold] && count<128; in++,count++)
1444  ;
1445  outbuf[out++]=(unsigned char)(char)(-count+1);
1446  outbuf[out++]=inbuf[hold];
1447  }
1448  else { /*Do a literal run*/
1449  hold=out; out++; count=0;
1450  while( ((in>=size-2)&&(in<size)) || ((in<size-2) && ((inbuf[in]!=inbuf[in+1])||(inbuf[in]!=inbuf[in+2]))) ) {
1451  outbuf[out++]=inbuf[in++];
1452  if( ++count>=128 )
1453  break;
1454  }
1455  outbuf[hold]=count-1;
1456  }
1457  }
1458  return(out);
1459 }
1460 
1461 
1462 /************ PPM functions ************/
1463 
1464 
1465 static int
1467 {
1468  /* Search colormap for closest match. */
1469  /* algorithm taken from ppmquant.c -IUW */
1470  register int i, r1, g1, b1;
1471  int ind;
1472  long dist;
1473 
1474  r1 = PPM_GETR(*pP);
1475  g1 = PPM_GETG(*pP);
1476  b1 = PPM_GETB(*pP);
1477  dist = 2000000000;
1478  for( i = 0; i < colors; i++ ) {
1479  register int r2, g2, b2;
1480  long newdist;
1481 
1482  r2 = PPM_GETR(chv[i].color);
1483  g2 = PPM_GETG(chv[i].color);
1484  b2 = PPM_GETB(chv[i].color);
1485  newdist = ( r1 - r2 ) * ( r1 - r2 ) +
1486  ( g1 - g2 ) * ( g1 - g2 ) +
1487  ( b1 - b2 ) * ( b1 - b2 );
1488 
1489  if( newdist < dist ) {
1490  ind = i;
1491  dist = newdist;
1492  }
1493  }
1494  return ind;
1495 }
1496 
1497 
1498 /************ floyd-steinberg error diffusion ************/
1499 
1500 static floydinfo *
1501 init_floyd(int cols, pixval maxval, int alternate)
1502 {
1503  register int i;
1504  floydinfo *fi;
1505 
1506  fi = MALLOC(1, floydinfo);
1507 
1508  fi->thisrederr = MALLOC(cols + 2, long);
1509  fi->thisgreenerr= MALLOC(cols + 2, long);
1510  fi->thisblueerr = MALLOC(cols + 2, long);
1511  fi->nextrederr = MALLOC(cols + 2, long);
1512  fi->nextgreenerr= MALLOC(cols + 2, long);
1513  fi->nextblueerr = MALLOC(cols + 2, long);
1514  fi->lefttoright = 1;
1515  fi->cols = cols;
1516  fi->maxval = maxval;
1517  fi->alternate = alternate;
1518 
1519  for( i = 0; i < cols + 2; i++ )
1520  fi->thisrederr[i] = fi->thisgreenerr[i] = fi->thisblueerr[i] = 0;
1521 
1522  return fi;
1523 }
1524 
1525 
1526 static void
1528  floydinfo *fi;
1529 {
1530  free(fi->thisrederr); free(fi->thisgreenerr); free(fi->thisblueerr);
1531  free(fi->nextrederr); free(fi->nextgreenerr); free(fi->nextblueerr);
1532  free(fi);
1533 }
1534 
1535 
1536 static void
1538  floydinfo *fi;
1539  pixel *prow;
1540 {
1541  register int i;
1542 
1543  fi->pixrow = prow;
1544 
1545  for( i = 0; i < fi->cols + 2; i++ )
1546  fi->nextrederr[i] = fi->nextgreenerr[i] = fi->nextblueerr[i] = 0;
1547 
1548  if( fi->lefttoright ) {
1549  fi->col = 0;
1550  fi->col_end = fi->cols;
1551  }
1552  else {
1553  fi->col = fi->cols - 1;
1554  fi->col_end = -1;
1555  }
1556 }
1557 
1558 
1559 #define FS_GREEN_WEIGHT 1
1560 #define FS_RED_WEIGHT 2 /* luminance of component relative to green */
1561 #define FS_BLUE_WEIGHT 5
1562 
1563 static pixel *
1565  floydinfo *fi;
1566 {
1567  register long r, g, b;
1568  register pixel *pP;
1569  int errcol = fi->col+1;
1570  pixval maxval = fi->maxval;
1571 
1572 #ifdef DEBUG
1573  if( fi->col == fi->col_end )
1574  pm_error("fs - access out of array bounds"); /* should never happen */
1575 #endif
1576 
1577  pP = &(fi->pixrow[fi->col]);
1578 
1579  /* Use Floyd-Steinberg errors to adjust actual color. */
1580  r = fi->thisrederr [errcol]; if( r < 0 ) r -= 8; else r += 8; r /= 16;
1581  g = fi->thisgreenerr[errcol]; if( g < 0 ) g -= 8; else g += 8; g /= 16;
1582  b = fi->thisblueerr [errcol]; if( b < 0 ) b -= 8; else b += 8; b /= 16;
1583 
1584  if( floyd == 2 ) { /* EXPERIMENTAL */
1586  }
1587 
1588  r += PPM_GETR(*pP); if ( r < 0 ) r = 0; else if ( r > maxval ) r = maxval;
1589  g += PPM_GETG(*pP); if ( g < 0 ) g = 0; else if ( g > maxval ) g = maxval;
1590  b += PPM_GETB(*pP); if ( b < 0 ) b = 0; else if ( b > maxval ) b = maxval;
1591 
1592  PPM_ASSIGN(*pP, r, g, b);
1593 
1594  fi->red = r;
1595  fi->green = g;
1596  fi->blue = b;
1597 
1598  return pP;
1599 }
1600 
1601 
1602 static void
1604  floydinfo *fi;
1605  int r, g, b;
1606 {
1607  register long rerr, gerr, berr, err;
1608  int col = fi->col;
1609  int errcol = col+1;
1610  long two_err;
1611 
1612  rerr = (long)(fi->red) - r;
1613  gerr = (long)(fi->green) - g;
1614  berr = (long)(fi->blue) - b;
1615 
1616  if( fi->lefttoright ) {
1617  two_err = 2*rerr;
1618  err = rerr; fi->nextrederr[errcol+1] += err; /* 1/16 */
1619  err += two_err; fi->nextrederr[errcol-1] += err; /* 3/16 */
1620  err += two_err; fi->nextrederr[errcol ] += err; /* 5/16 */
1621  err += two_err; fi->thisrederr[errcol+1] += err; /* 7/16 */
1622 
1623  two_err = 2*gerr;
1624  err = gerr; fi->nextgreenerr[errcol+1] += err; /* 1/16 */
1625  err += two_err; fi->nextgreenerr[errcol-1] += err; /* 3/16 */
1626  err += two_err; fi->nextgreenerr[errcol ] += err; /* 5/16 */
1627  err += two_err; fi->thisgreenerr[errcol+1] += err; /* 7/16 */
1628 
1629  two_err = 2*berr;
1630  err = berr; fi->nextblueerr[errcol+1] += err; /* 1/16 */
1631  err += two_err; fi->nextblueerr[errcol-1] += err; /* 3/16 */
1632  err += two_err; fi->nextblueerr[errcol ] += err; /* 5/16 */
1633  err += two_err; fi->thisblueerr[errcol+1] += err; /* 7/16 */
1634 
1635  fi->col++;
1636  }
1637  else {
1638  two_err = 2*rerr;
1639  err = rerr; fi->nextrederr[errcol-1] += err; /* 1/16 */
1640  err += two_err; fi->nextrederr[errcol+1] += err; /* 3/16 */
1641  err += two_err; fi->nextrederr[errcol ] += err; /* 5/16 */
1642  err += two_err; fi->thisrederr[errcol-1] += err; /* 7/16 */
1643 
1644  two_err = 2*gerr;
1645  err = gerr; fi->nextgreenerr[errcol-1] += err; /* 1/16 */
1646  err += two_err; fi->nextgreenerr[errcol+1] += err; /* 3/16 */
1647  err += two_err; fi->nextgreenerr[errcol ] += err; /* 5/16 */
1648  err += two_err; fi->thisgreenerr[errcol-1] += err; /* 7/16 */
1649 
1650  two_err = 2*berr;
1651  err = berr; fi->nextblueerr[errcol-1] += err; /* 1/16 */
1652  err += two_err; fi->nextblueerr[errcol+1] += err; /* 3/16 */
1653  err += two_err; fi->nextblueerr[errcol ] += err; /* 5/16 */
1654  err += two_err; fi->thisblueerr[errcol-1] += err; /* 7/16 */
1655 
1656  fi->col--;
1657  }
1658 }
1659 
1660 
1661 static void
1663  floydinfo *fi;
1664 {
1665  long *tmp;
1666 
1667  tmp = fi->thisrederr; fi->thisrederr = fi->nextrederr; fi->nextrederr = tmp;
1668  tmp = fi->thisgreenerr; fi->thisgreenerr = fi->nextgreenerr; fi->nextgreenerr = tmp;
1669  tmp = fi->thisblueerr; fi->thisblueerr = fi->nextblueerr; fi->nextblueerr = tmp;
1670  if( fi->alternate )
1671  fi->lefttoright = !(fi->lefttoright);
1672 }
1673 
1674 
1675 /************ other utility functions ************/
1676 
1677 static void
1679  int rows, nPlanes;
1680 {
1681  ilbm_body = MALLOC(rows * nPlanes + 1, bodyrow);
1682  ilbm_body[rows * nPlanes].row = NULL;
1683 }
1684 
1685 #if 0 /* not used for now */
1686 static void
1687 free_body_array ARGS((void))
1688 {
1689  bodyrow *p;
1690 
1691  for( p = ilbm_body; p->row != NULL; p++ )
1692  free(p->row);
1693  free(ilbm_body);
1694 }
1695 #endif
1696 
1697 static int
1699  int colors;
1700 {
1701  int i;
1702 
1703  for( i = 1; i <= MAXPLANES; i++ ) {
1704  if( colors <= (1 << i) )
1705  return i;
1706  }
1707  pm_error("too many planes (max %d)", MAXPLANES);
1708  /*NOTREACHED*/
1709  return -1;
1710 }
1711 
1712 
1713 static void
1715 {
1716  if ( pm_writebigshort( stdout, s ) == -1 )
1717  pm_error( "write error" );
1718 }
1719 
1720 
1721 static void
1723  long l;
1724 {
1725  if ( pm_writebiglong( stdout, l ) == -1 )
1726  pm_error( "write error" );
1727 }
1728 
1729 
1730 #if 0
1731 static void
1732 put_byte(b)
1733  unsigned char b;
1734 {
1735  (void) putc( b, stdout );
1736 }
1737 #endif
1738 
1739 
1740 static pixval *
1741 make_val_table(pixval oldmaxval, pixval newmaxval)
1742 {
1743  int i;
1744  pixval *table;
1745 
1746  table = MALLOC(oldmaxval + 1, pixval);
1747  for(i = 0; i <= oldmaxval; i++ )
1748  table[i] = (i * newmaxval + oldmaxval/2) / oldmaxval;
1749 
1750  return table;
1751 }
1752 
1753 
1754 static void *
1756  int bytes;
1757 {
1758  void *mem;
1759 
1760  mem = malloc(bytes);
1761  if( mem == NULL )
1762  pm_error("out of memory allocating %d bytes", bytes);
1763  return mem;
1764 }
1765 
1766 
1767 static int gFormat;
1768 static int gCols;
1769 static int gMaxval;
1770 
1771 static void
1772 init_read(fp, colsP, rowsP, maxvalP, formatP, readall)
1773  FILE *fp;
1774  int *colsP, *rowsP;
1775  pixval *maxvalP;
1776  int *formatP;
1777  int readall;
1778 {
1779  ppm_readppminit(fp, colsP, rowsP, maxvalP, formatP);
1780  if( readall ) {
1781  int row;
1782 
1783  pixels = ppm_allocarray(*colsP, *rowsP);
1784  for( row = 0; row < *rowsP; row++ )
1785  ppm_readppmrow(fp, pixels[row], *colsP, *maxvalP, *formatP);
1786  /* pixels = ppm_readppm(fp, colsP, rowsP, maxvalP); */
1787  }
1788  else {
1789  pixrow = ppm_allocrow(*colsP);
1790  }
1791  gCols = *colsP;
1792  gMaxval = *maxvalP;
1793  gFormat = *formatP;
1794 }
1795 
1796 
1797 static pixel *
1799  FILE *fp;
1800  int row;
1801 {
1802  if( pixels )
1803  pixrow = pixels[row];
1804  else {
1805 #ifdef DEBUG
1806  static int rowcnt;
1807  if( row != rowcnt )
1808  pm_error("big mistake");
1809  rowcnt++;
1810 #endif
1812  }
1813  return pixrow;
1814 }
1815 
static int pr(int(*writeFunc)(void *stream, const char *data, int size), void *stream, const char *data)
Definition: HTMLGen.cc:249
rp
Definition: action.c:992
cp
Definition: action.c:1035
struct @88 table[500]
#define count(a)
Definition: aptex-macros.h:781
#define mode
Definition: aptex-macros.h:510
static char * dist
Definition: aptex-src.c:59
static gray maxval
Definition: asciitopgm.c:38
#define green
Definition: backend_eps.c:36
#define red
Definition: backend_eps.c:35
int * g2
Definition: bmpfont.h:57
#define b
Definition: jpegint.h:372
#define free(a)
Definition: decNumber.cpp:310
int strcmp()
Definition: coll.cpp:143
int sscanf()
int pixels
Definition: dvipng.h:106
static struct line hold
Definition: execute.c:172
static void
Definition: fpif.c:118
#define s
Definition: afcover.h:80
#define r1
#define r2
static char usage[]
Definition: giftopnm.c:59
char * mapfile
Definition: gsftopk.c:415
int col
Definition: gsftopk.c:443
FILE * out
Definition: hbf2gf.c:286
static char * cmpNAME[]
Definition: ilbm.h:27
#define vmHAM
Definition: ilbm.h:44
#define CAMGChunkSize
Definition: ilbm.h:40
#define vmLACE
Definition: ilbm.h:42
#define HAMCODE_BLUE
Definition: ilbm.h:49
#define BitMapHeaderSize
Definition: ilbm.h:17
#define mskNone
Definition: ilbm.h:19
#define DirectColorSize
Definition: ilbm.h:59
unsigned short rawtype
Definition: ilbm.h:144
#define RowBytes(cols)
Definition: ilbm.h:4
#define cmpByteRun1
Definition: ilbm.h:25
#define cmpMAXKNOWN
Definition: ilbm.h:26
#define cmpNone
Definition: ilbm.h:24
#define MAXCOLVAL
Definition: ilbm.h:151
#define HAMCODE_GREEN
Definition: ilbm.h:51
#define MAXCMAPCOLORS
Definition: ilbm.h:150
#define vmHIRES
Definition: ilbm.h:45
#define MAXPLANES
Definition: ilbm.h:143
#define HAMCODE_RED
Definition: ilbm.h:50
#define putc
Definition: jbib.h:20
JCOPY_OPTION option
Definition: transupp.h:131
static FILE * outfile
Definition: wrjpgcom.c:80
uchar inbuf[1000000]
Definition: unzcrash.c:40
uchar outbuf[(1000000+1000000)]
Definition: unzcrash.c:41
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
int int double double double char double char * top
Definition: gdfx.h:19
int cmapsize
Definition: bmp.h:90
#define string
Definition: ctangleboot.c:111
Code related to b fwrite(a, sizeof(char), b, stdout) @d C_printf(c
#define b1
Definition: texmfmem.h:169
#define b2
Definition: texmfmem.h:170
#define malloc
Definition: alloca.c:91
#define mem
Definition: synctex.c:171
char ind[999]
Definition: mkind.c:58
@ err
Definition: mtxline.h:24
void pm_usage(char *usage)
Definition: libpbm1.c:343
FILE * pm_openr(char *name)
Definition: libpbm1.c:600
int pm_bitstomaxval(int bits)
Definition: libpbm1.c:201
int pm_writebigshort(FILE *out, short s)
Definition: libpbm1.c:678
int pm_writebiglong(FILE *out, long l)
Definition: libpbm1.c:711
static int rows
Definition: pbmclean.c:15
static int format
Definition: pbmclean.c:15
static int cols
Definition: pbmmask.c:21
#define abs(a)
Definition: pbmplus.h:225
#define ARGS(alist)
Definition: pbmplus.h:235
#define odd(n)
Definition: pbmplus.h:227
#define fp
#define pm_error
Definition: png22pnm.c:118
#define pm_keymatch(stra, strb, _x)
Definition: png22pnm.c:121
#define pm_close(file)
Definition: png22pnm.c:120
#define pm_message
Definition: png22pnm.c:116
void ppm_readppmrow(FILE *file, pixel *pixelrow, int cols, pixval maxval, int format)
Definition: libppm1.c:87
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_readppminit(FILE *file, int *colsP, int *rowsP, pixval *maxvalP, int *formatP)
Definition: libppm1.c:53
int ppm_lookupcolor(colorhash_table cht, pixel *colorP)
Definition: libppm3.c:226
int ppm_addtocolorhash(colorhash_table cht, pixel *colorP, int value)
Definition: libppm3.c:144
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
void ppm_freecolorhash(colorhash_table cht)
Definition: libppm3.c:249
#define PPM_GETR(p)
Definition: ppm.h:36
#define PPM_ASSIGN(p, red, grn, blu)
Definition: ppm.h:46
#define PPM_LUMIN(p)
Definition: ppm.h:104
#define PPM_GETG(p)
Definition: ppm.h:37
#define ppm_freearray(pixels, rows)
Definition: ppm.h:73
#define PPM_FORMAT_TYPE(f)
Definition: ppm.h:64
#define ppm_allocarray(cols, rows)
Definition: ppm.h:71
#define PPM_GETB(p)
Definition: ppm.h:38
gray pixval
Definition: ppm.h:9
#define ppm_allocrow(cols)
Definition: ppm.h:72
#define PPM_TYPE
Definition: ppm.h:59
static int size
Definition: ppmlabel.c:24
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 put_byte(b)
Definition: ppmtoilbm.c:95
#define MODE_CMAP
Definition: ppmtoilbm.c:53
static long do_ham_body()
static void write_std_cmap()
#define CAMGSIZE
Definition: ppmtoilbm.c:141
#define FS_BLUE_WEIGHT
Definition: ppmtoilbm.c:1561
static pixel ** pixels
Definition: ppmtoilbm.c:127
#define put_fourchars(str)
Definition: ppmtoilbm.c:92
static int get_int_val()
const unsigned char ppmtoilbm_bitmask[]
Definition: ppmtoilbm.c:1334
static void alloc_body_array()
static void put_big_short()
#define MODE_HAM
Definition: ppmtoilbm.c:55
static int runbyte1()
static short savemem
Definition: ppmtoilbm.c:135
static long do_std_body()
#define WORSTCOMPR(bytes)
Definition: ppmtoilbm.c:139
static void write_body()
Definition: ppmtoilbm.c:1404
static void ppm_to_cmap()
static int times150[256]
Definition: ppmtoilbm.c:181
#define ECS_HAMPLANES
Definition: ppmtoilbm.c:59
static int colorstobpp()
#define ECS_MAXPLANES
Definition: ppmtoilbm.c:58
static void ppm_to_direct()
static void update_floyd_pixel()
#define FS_RED_WEIGHT
Definition: ppmtoilbm.c:1560
static void put_big_long()
#define MAXCOLORS
static unsigned char * compr_rowbuf
Definition: ppmtoilbm.c:126
static int encode_row()
static void ppm_to_ham()
static void * xmalloc()
static int times77[256]
Definition: ppmtoilbm.c:148
#define MODE_NONE
Definition: ppmtoilbm.c:56
static pixval * make_val_table()
#define NEWDEPTH(pix, table)
Definition: ppmtoilbm.c:254
static short floyd
Definition: ppmtoilbm.c:137
static long viewportmodes
Definition: ppmtoilbm.c:131
static floydinfo * init_floyd()
#define DEF_DCOLPLANES
Definition: ppmtoilbm.c:70
#define DEF_HAMPLANES
Definition: ppmtoilbm.c:68
static void write_form_ilbm()
#define AGA_MAXPLANES
Definition: ppmtoilbm.c:60
static int compr_type
Definition: ppmtoilbm.c:132
static pixel * next_pixrow()
static void write_bmhd()
static void write_camg()
Definition: ppmtoilbm.c:1417
#define DEF_COMPRESSION
Definition: ppmtoilbm.c:71
static bodyrow * ilbm_body
Definition: ppmtoilbm.c:129
static long do_direct_body()
#define AGA_HAMPLANES
Definition: ppmtoilbm.c:61
#define DO_COMPRESS
Definition: ppmtoilbm.c:140
#define MODE_DIRECT
Definition: ppmtoilbm.c:52
static short compr_force
Definition: ppmtoilbm.c:136
static unsigned char * coded_rowbuf
Definition: ppmtoilbm.c:125
#define MODE_24
Definition: ppmtoilbm.c:54
static long do_24_body()
static int gFormat
Definition: ppmtoilbm.c:1767
static int gMaxval
Definition: ppmtoilbm.c:1769
static int closest_color()
#define DEF_MAXPLANES
Definition: ppmtoilbm.c:67
static void begin_floyd_row()
static int compress_row()
static void ppm_to_std()
#define MALLOC(n, type)
Definition: ppmtoilbm.c:110
static pixel * pixrow
Definition: ppmtoilbm.c:128
static void end_floyd_row()
static int times29[256]
Definition: ppmtoilbm.c:214
static pixel * next_floyd_pixel()
#define PAD(n)
Definition: ppmtoilbm.c:115
static void free_floyd()
static void init_read()
static int get_compr_type()
static void ppm_to_24()
static int gCols
Definition: ppmtoilbm.c:1768
int main(int argc, argv)
Definition: ppmtoilbm.c:258
static int row
Definition: ps2pk.c:587
static long bytes
Definition: psutil.c:35
#define mask(n)
Definition: lbitlib.c:93
static char no[99]
Definition: scanid.c:41
static FILE * in
Definition: squeeze.c:36
unsigned char r
Definition: ilbm.h:57
unsigned char b
Definition: ilbm.h:57
unsigned char g
Definition: ilbm.h:57
int len
Definition: ppmtoilbm.c:75
unsigned char * row
Definition: ppmtoilbm.c:76
Definition: pdfdev.c:706
Definition: vmsdir.h:32
long * thisblueerr
Definition: ppmtoilbm.c:79
int col
Definition: ppmtoilbm.c:85
pixel * pixrow
Definition: ppmtoilbm.c:83
int lefttoright
Definition: ppmtoilbm.c:81
long * nextgreenerr
Definition: ppmtoilbm.c:80
long * nextrederr
Definition: ppmtoilbm.c:80
pixval maxval
Definition: ppmtoilbm.c:84
int col_end
Definition: ppmtoilbm.c:85
pixval blue
Definition: ppmtoilbm.c:87
long * nextblueerr
Definition: ppmtoilbm.c:80
int alternate
Definition: ppmtoilbm.c:86
long * thisgreenerr
Definition: ppmtoilbm.c:79
pixval green
Definition: ppmtoilbm.c:87
pixval red
Definition: ppmtoilbm.c:87
int cols
Definition: ppmtoilbm.c:82
long * thisrederr
Definition: ppmtoilbm.c:79
Definition: getopt.h:95
Definition: ppm.h:33
Definition: table.h:30
Definition: strexpr.c:21
#define FILE
Definition: t1stdio.h:34
val
Definition: tex4ht.c:3227
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
FILE * ofp
Definition: t1asm.c:89
FILE * ifp
Definition: t1asm.c:88
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269
#define argn