1 /* g3topbm.c - read a Group 3 FAX file and produce a portable bitmap *
2 *
3 * Copyright (C) 1989 by Paul Haeberli <paul@manray.sgi.com>. *
4 *
5 * pnmtoxwd.c - read a portable anymap and produce a color X11 window dump
6 *
7 * Copyright (C) 1989, 1991 by Jef Poskanzer.
8 *
9 * gcc -g -o g3toxwd -O2 g3toxwd.c
10 *
11 * Permission to use, copy, modify, and distribute this software and its *
12 * documentation for any purpose and without fee is hereby granted, provided *
13 * that the above copyright notice appear in all copies and that both that *
14 * copyright notice and this permission notice appear in supporting *
15 * documentation. This software is provided "as is" without express or *
16 * implied warranty. *
17 *
18 * Update aug 31,1993, Chel van Gennip, combined two programs, delated large
19 * array and added simple scaling to improve speed.
20 *
21 * Update 22 may 1994, better EOF handling by transmission errors chel. Added
22 * -skiprows for long faxes.
23 *
24 * $Log: g3toxwd.c,v $
25 * Revision 1.2 2003/10/03 11:36:03 gert
26 * fix some return types and prototypes (Debian/ABA)
27 *
28 * Revision 1.1 2003/10/03 11:34:56 gert
29 * G3 -> X11 xwd, initial checkin
30 *
31 *
32 */
33
34 #include <sys/types.h>
35 #include <ctype.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 typedef unsigned char bit;
41
42 #define PBM_WHITE 0
43 #define PBM_BLACK 1
44 #define pm_error(a,b,c,d,e,f) {fprintf(stderr,a,b,c,d,e,f);fprintf(stderr,"\n");}
45 #define pm_message(a,b,c,d,e,f) {fprintf(stderr,a,b,c,d,e,f);fprintf(stderr,"\n");}
46 #define pm_usage(a) { fprintf(stderr,"usage: %s\n",a); exit(7); }
47 #define pbm_allocrow(a) (bit*)malloc(a)
48
49 /* x11wd.h - the following defs are taken from various X.V11R2 header files */
50
51 #ifndef _X11WD_H_
52 #define _X11WD_H_
53
54 #define LSBFirst 0
55 #define MSBFirst 1
56
57 #define XYBitmap 0
58 #define XYPixmap 1
59 #define ZPixmap 2
60
61 #define StaticGray 0
62 #define GrayScale 1
63 #define StaticColor 2
64 #define PseudoColor 3
65 #define TrueColor 4
66 #define DirectColor 5
67
68 typedef unsigned long xwdval;
69
70 #define X11WD_FILE_VERSION 7
71 typedef struct {
72 xwdval header_size; /* Size of the entire file header (bytes). */
73 xwdval file_version; /* X11WD_FILE_VERSION */
74 xwdval pixmap_format; /* Pixmap format */
75 xwdval pixmap_depth; /* Pixmap depth */
76 xwdval pixmap_width; /* Pixmap width */
77 xwdval pixmap_height; /* Pixmap height */
78 xwdval xoffset; /* Bitmap x offset */
79 xwdval byte_order; /* MSBFirst, LSBFirst */
80 xwdval bitmap_unit; /* Bitmap unit */
81 xwdval bitmap_bit_order; /* MSBFirst, LSBFirst */
82 xwdval bitmap_pad; /* Bitmap scanline pad */
83 xwdval bits_per_pixel; /* Bits per pixel */
84 xwdval bytes_per_line; /* Bytes per scanline */
85 xwdval visual_class; /* Class of colormap */
86 xwdval red_mask; /* Z red mask */
87 xwdval green_mask; /* Z green mask */
88 xwdval blue_mask; /* Z blue mask */
89 xwdval bits_per_rgb; /* Log base 2 of distinct color values */
90 xwdval colormap_entries; /* Number of entries in colormap */
91 xwdval ncolors; /* Number of Color structures */
92 xwdval window_width; /* Window width */
93 xwdval window_height; /* Window height */
94 long window_x; /* Window upper left X coordinate */
95 long window_y; /* Window upper left Y coordinate */
96 xwdval window_bdrwidth; /* Window border width */
97 } X11WDFileHeader;
98
99 typedef struct {
100 unsigned long pixel;
101 unsigned short red, green, blue;
102 char flags; /* do_red, do_green, do_blue */
103 char pad;
104 } X11XColor;
105
106 #endif /* _X11WD_H_ */
107
108 /* g3.h - header file for group 3 FAX compression filters from pm package */
109
110 #ifndef _G3_H_
111 #define _G3_H_
112
113 typedef struct tableentry {
114 int tabid;
115 int code;
116 int length;
117 int count;
118 } tableentry;
119
120 #define TWTABLE 23
121 #define MWTABLE 24
122 #define TBTABLE 25
123 #define MBTABLE 26
124 #define EXTABLE 27
125 #define VRTABLE 28
126
127 static struct tableentry twtable[]=
128 {
129 {TWTABLE, 0x35, 8, 0},
130 {TWTABLE, 0x7, 6, 1},
131 {TWTABLE, 0x7, 4, 2},
132 {TWTABLE, 0x8, 4, 3},
133 {TWTABLE, 0xb, 4, 4},
134 {TWTABLE, 0xc, 4, 5},
135 {TWTABLE, 0xe, 4, 6},
136 {TWTABLE, 0xf, 4, 7},
137 {TWTABLE, 0x13, 5, 8},
138 {TWTABLE, 0x14, 5, 9},
139 {TWTABLE, 0x7, 5, 10},
140 {TWTABLE, 0x8, 5, 11},
141 {TWTABLE, 0x8, 6, 12},
142 {TWTABLE, 0x3, 6, 13},
143 {TWTABLE, 0x34, 6, 14},
144 {TWTABLE, 0x35, 6, 15},
145 {TWTABLE, 0x2a, 6, 16},
146 {TWTABLE, 0x2b, 6, 17},
147 {TWTABLE, 0x27, 7, 18},
148 {TWTABLE, 0xc, 7, 19},
149 {TWTABLE, 0x8, 7, 20},
150 {TWTABLE, 0x17, 7, 21},
151 {TWTABLE, 0x3, 7, 22},
152 {TWTABLE, 0x4, 7, 23},
153 {TWTABLE, 0x28, 7, 24},
154 {TWTABLE, 0x2b, 7, 25},
155 {TWTABLE, 0x13, 7, 26},
156 {TWTABLE, 0x24, 7, 27},
157 {TWTABLE, 0x18, 7, 28},
158 {TWTABLE, 0x2, 8, 29},
159 {TWTABLE, 0x3, 8, 30},
160 {TWTABLE, 0x1a, 8, 31},
161 {TWTABLE, 0x1b, 8, 32},
162 {TWTABLE, 0x12, 8, 33},
163 {TWTABLE, 0x13, 8, 34},
164 {TWTABLE, 0x14, 8, 35},
165 {TWTABLE, 0x15, 8, 36},
166 {TWTABLE, 0x16, 8, 37},
167 {TWTABLE, 0x17, 8, 38},
168 {TWTABLE, 0x28, 8, 39},
169 {TWTABLE, 0x29, 8, 40},
170 {TWTABLE, 0x2a, 8, 41},
171 {TWTABLE, 0x2b, 8, 42},
172 {TWTABLE, 0x2c, 8, 43},
173 {TWTABLE, 0x2d, 8, 44},
174 {TWTABLE, 0x4, 8, 45},
175 {TWTABLE, 0x5, 8, 46},
176 {TWTABLE, 0xa, 8, 47},
177 {TWTABLE, 0xb, 8, 48},
178 {TWTABLE, 0x52, 8, 49},
179 {TWTABLE, 0x53, 8, 50},
180 {TWTABLE, 0x54, 8, 51},
181 {TWTABLE, 0x55, 8, 52},
182 {TWTABLE, 0x24, 8, 53},
183 {TWTABLE, 0x25, 8, 54},
184 {TWTABLE, 0x58, 8, 55},
185 {TWTABLE, 0x59, 8, 56},
186 {TWTABLE, 0x5a, 8, 57},
187 {TWTABLE, 0x5b, 8, 58},
188 {TWTABLE, 0x4a, 8, 59},
189 {TWTABLE, 0x4b, 8, 60},
190 {TWTABLE, 0x32, 8, 61},
191 {TWTABLE, 0x33, 8, 62},
192 {TWTABLE, 0x34, 8, 63},
193 };
194
195 static struct tableentry mwtable[]=
196 {
197 {MWTABLE, 0x1b, 5, 64},
198 {MWTABLE, 0x12, 5, 128},
199 {MWTABLE, 0x17, 6, 192},
200 {MWTABLE, 0x37, 7, 256},
201 {MWTABLE, 0x36, 8, 320},
202 {MWTABLE, 0x37, 8, 384},
203 {MWTABLE, 0x64, 8, 448},
204 {MWTABLE, 0x65, 8, 512},
205 {MWTABLE, 0x68, 8, 576},
206 {MWTABLE, 0x67, 8, 640},
207 {MWTABLE, 0xcc, 9, 704},
208 {MWTABLE, 0xcd, 9, 768},
209 {MWTABLE, 0xd2, 9, 832},
210 {MWTABLE, 0xd3, 9, 896},
211 {MWTABLE, 0xd4, 9, 960},
212 {MWTABLE, 0xd5, 9, 1024},
213 {MWTABLE, 0xd6, 9, 1088},
214 {MWTABLE, 0xd7, 9, 1152},
215 {MWTABLE, 0xd8, 9, 1216},
216 {MWTABLE, 0xd9, 9, 1280},
217 {MWTABLE, 0xda, 9, 1344},
218 {MWTABLE, 0xdb, 9, 1408},
219 {MWTABLE, 0x98, 9, 1472},
220 {MWTABLE, 0x99, 9, 1536},
221 {MWTABLE, 0x9a, 9, 1600},
222 {MWTABLE, 0x18, 6, 1664},
223 {MWTABLE, 0x9b, 9, 1728},
224 };
225
226 static struct tableentry tbtable[]=
227 {
228 {TBTABLE, 0x37, 10, 0},
229 {TBTABLE, 0x2, 3, 1},
230 {TBTABLE, 0x3, 2, 2},
231 {TBTABLE, 0x2, 2, 3},
232 {TBTABLE, 0x3, 3, 4},
233 {TBTABLE, 0x3, 4, 5},
234 {TBTABLE, 0x2, 4, 6},
235 {TBTABLE, 0x3, 5, 7},
236 {TBTABLE, 0x5, 6, 8},
237 {TBTABLE, 0x4, 6, 9},
238 {TBTABLE, 0x4, 7, 10},
239 {TBTABLE, 0x5, 7, 11},
240 {TBTABLE, 0x7, 7, 12},
241 {TBTABLE, 0x4, 8, 13},
242 {TBTABLE, 0x7, 8, 14},
243 {TBTABLE, 0x18, 9, 15},
244 {TBTABLE, 0x17, 10, 16},
245 {TBTABLE, 0x18, 10, 17},
246 {TBTABLE, 0x8, 10, 18},
247 {TBTABLE, 0x67, 11, 19},
248 {TBTABLE, 0x68, 11, 20},
249 {TBTABLE, 0x6c, 11, 21},
250 {TBTABLE, 0x37, 11, 22},
251 {TBTABLE, 0x28, 11, 23},
252 {TBTABLE, 0x17, 11, 24},
253 {TBTABLE, 0x18, 11, 25},
254 {TBTABLE, 0xca, 12, 26},
255 {TBTABLE, 0xcb, 12, 27},
256 {TBTABLE, 0xcc, 12, 28},
257 {TBTABLE, 0xcd, 12, 29},
258 {TBTABLE, 0x68, 12, 30},
259 {TBTABLE, 0x69, 12, 31},
260 {TBTABLE, 0x6a, 12, 32},
261 {TBTABLE, 0x6b, 12, 33},
262 {TBTABLE, 0xd2, 12, 34},
263 {TBTABLE, 0xd3, 12, 35},
264 {TBTABLE, 0xd4, 12, 36},
265 {TBTABLE, 0xd5, 12, 37},
266 {TBTABLE, 0xd6, 12, 38},
267 {TBTABLE, 0xd7, 12, 39},
268 {TBTABLE, 0x6c, 12, 40},
269 {TBTABLE, 0x6d, 12, 41},
270 {TBTABLE, 0xda, 12, 42},
271 {TBTABLE, 0xdb, 12, 43},
272 {TBTABLE, 0x54, 12, 44},
273 {TBTABLE, 0x55, 12, 45},
274 {TBTABLE, 0x56, 12, 46},
275 {TBTABLE, 0x57, 12, 47},
276 {TBTABLE, 0x64, 12, 48},
277 {TBTABLE, 0x65, 12, 49},
278 {TBTABLE, 0x52, 12, 50},
279 {TBTABLE, 0x53, 12, 51},
280 {TBTABLE, 0x24, 12, 52},
281 {TBTABLE, 0x37, 12, 53},
282 {TBTABLE, 0x38, 12, 54},
283 {TBTABLE, 0x27, 12, 55},
284 {TBTABLE, 0x28, 12, 56},
285 {TBTABLE, 0x58, 12, 57},
286 {TBTABLE, 0x59, 12, 58},
287 {TBTABLE, 0x2b, 12, 59},
288 {TBTABLE, 0x2c, 12, 60},
289 {TBTABLE, 0x5a, 12, 61},
290 {TBTABLE, 0x66, 12, 62},
291 {TBTABLE, 0x67, 12, 63},
292 };
293
294 static struct tableentry mbtable[]=
295 {
296 {MBTABLE, 0xf, 10, 64},
297 {MBTABLE, 0xc8, 12, 128},
298 {MBTABLE, 0xc9, 12, 192},
299 {MBTABLE, 0x5b, 12, 256},
300 {MBTABLE, 0x33, 12, 320},
301 {MBTABLE, 0x34, 12, 384},
302 {MBTABLE, 0x35, 12, 448},
303 {MBTABLE, 0x6c, 13, 512},
304 {MBTABLE, 0x6d, 13, 576},
305 {MBTABLE, 0x4a, 13, 640},
306 {MBTABLE, 0x4b, 13, 704},
307 {MBTABLE, 0x4c, 13, 768},
308 {MBTABLE, 0x4d, 13, 832},
309 {MBTABLE, 0x72, 13, 896},
310 {MBTABLE, 0x73, 13, 960},
311 {MBTABLE, 0x74, 13, 1024},
312 {MBTABLE, 0x75, 13, 1088},
313 {MBTABLE, 0x76, 13, 1152},
314 {MBTABLE, 0x77, 13, 1216},
315 {MBTABLE, 0x52, 13, 1280},
316 {MBTABLE, 0x53, 13, 1344},
317 {MBTABLE, 0x54, 13, 1408},
318 {MBTABLE, 0x55, 13, 1472},
319 {MBTABLE, 0x5a, 13, 1536},
320 {MBTABLE, 0x5b, 13, 1600},
321 {MBTABLE, 0x64, 13, 1664},
322 {MBTABLE, 0x65, 13, 1728},
323 };
324
325 static struct tableentry extable[]=
326 {
327 {EXTABLE, 0x8, 11, 1792},
328 {EXTABLE, 0xc, 11, 1856},
329 {EXTABLE, 0xd, 11, 1920},
330 {EXTABLE, 0x12, 12, 1984},
331 {EXTABLE, 0x13, 12, 2048},
332 {EXTABLE, 0x14, 12, 2112},
333 {EXTABLE, 0x15, 12, 2176},
334 {EXTABLE, 0x16, 12, 2240},
335 {EXTABLE, 0x17, 12, 2304},
336 {EXTABLE, 0x1c, 12, 2368},
337 {EXTABLE, 0x1d, 12, 2432},
338 {EXTABLE, 0x1e, 12, 2496},
339 {EXTABLE, 0x1f, 12, 2560},
340 };
341
342 #endif /* _G3_H_ */
343
344 void skiptoeol (void);
345
346 FILE *
pm_openr(name)347 pm_openr (name)
348 char *name;
349 {
350 FILE *f;
351
352 if (strcmp (name, "-") == 0)
353 f = stdin;
354 else {
355 f = fopen (name, "r");
356 if (f == NULL) {
357 perror (name);
358 exit (1);
359 }
360 }
361 return f;
362 }
363
pm_keymatch(str,keyword,minchars)364 int pm_keymatch (str, keyword, minchars)
365 char *str;
366 char *keyword;
367 int minchars;
368 {
369 register int len;
370
371 len = strlen (str);
372 if (len < minchars)
373 return 0;
374 while (--len >= 0) {
375 register char c1, c2;
376
377 c1 = *str++;
378 c2 = *keyword++;
379 if (c2 == '\0')
380 return 0;
381 if (isupper (c1))
382 c1 = tolower (c1);
383 if (isupper (c2))
384 c1 = tolower (c2);
385 if (c1 != c2)
386 return 0;
387 }
388 return 1;
389 }
390
pm_writebigshort(out,s)391 int pm_writebigshort (out, s)
392 FILE *out;
393 short s;
394 {
395 if (putc ((s >> 8) & 0xff, out) == EOF)
396 return -1;
397 if (putc (s & 0xff, out) == EOF)
398 return -1;
399 return 0;
400 }
401
pm_writebiglong(out,l)402 int pm_writebiglong (out, l)
403 FILE *out;
404 long l;
405 {
406 if (putc ((l >> 24) & 0xff, out) == EOF)
407 return -1;
408 if (putc ((l >> 16) & 0xff, out) == EOF)
409 return -1;
410 if (putc ((l >> 8) & 0xff, out) == EOF)
411 return -1;
412 if (putc (l & 0xff, out) == EOF)
413 return -1;
414 return 0;
415 }
416
417 static int doubleheight = 1;
418 static hscale = 100;
419 static vscale = 100;
420
421 static void putinit (), putbit (), putrest (), putitem ();
422 static int item, bitsperitem;
423 static char *line;
424 static int bytecnt;
425
426 #define TABSIZE(tab) (sizeof(tab)/sizeof(struct tableentry))
427 #define MAXCOLS 1728
428 #define MAXROWS 4300 /* up to two pages long */
429 #define XWDCOLS 1000
430 #define XWDROWS XWDCOLS*290/215
431
432 int eof = 0;
433 int eols;
434 int rawzeros;
435 int shdata;
436 int kludge;
437 int reversebits;
438 int stretch;
439
440 #define WHASHA 3510
441 #define WHASHB 1178
442
443 #define BHASHA 293
444 #define BHASHB 2695
445
446 #define HASHSIZE 1021
447 tableentry *whash[HASHSIZE];
448 tableentry *bhash[HASHSIZE];
449
450 static FILE *ifp;
451 static int shbit = 0;
452 static int eof_err = 0;
rawgetbit()453 static inline int rawgetbit ()
454 {
455 int b;
456
457 if (eof_err) {
458 rawzeros = 20;
459 return (1);
460 }
461 if ((shbit & 0xff) == 0) {
462 shdata = getc (ifp);
463 if (shdata == EOF) {
464 eof_err++;
465 pm_error ("EOF / read error at line %d", eols, 0, 0, 0, 0);
466 }
467 shbit = reversebits ? 0x01 : 0x80;
468 }
469 if (shdata & shbit) {
470 rawzeros = 0;
471 b = 1;
472 } else {
473 rawzeros++;
474 b = 0;
475 }
476 if (reversebits)
477 shbit <<= 1;
478 else
479 shbit >>= 1;
480 return b;
481 }
482
addtohash(hash,te,n,a,b)483 addtohash (hash, te, n, a, b)
484 tableentry *hash[];
485 tableentry *te;
486 int n, a, b;
487 {
488 unsigned int pos;
489
490 while (n--) {
491 pos = ((te->length + a) * (te->code + b)) % HASHSIZE;
492 if (hash[pos] != 0)
493 pm_error (
494 "internal error: addtohash fatal hash collision",
495 0, 0, 0, 0, 0);
496 hash[pos] = te;
497 te++;
498 }
499 }
500
501 static inline tableentry *
hashfind(hash,length,code,a,b)502 hashfind (hash, length, code, a, b)
503 tableentry *hash[];
504 int length, code;
505 int a, b;
506 {
507 unsigned int pos;
508 tableentry *te;
509
510 pos = ((length + a) * (code + b)) % HASHSIZE;
511 if (pos < 0 || pos >= HASHSIZE)
512 pm_error (
513 "internal error: bad hash position, length %d code %d pos %d",
514 length, code, pos, 0, 0);
515 te = hash[pos];
516 return ((te && te->length == length && te->code == code) ? te : 0);
517 }
518
getfaxrow(row,bitrow)519 getfaxrow (row, bitrow)
520 int row;
521 bit *bitrow;
522 {
523 int col;
524 bit *bP;
525 int curlen, curcode, nextbit;
526 int count, color;
527 tableentry *te;
528
529 for (col = 0, bP = bitrow; col < MAXCOLS; ++col, ++bP)
530 *bP = PBM_WHITE;
531 col = 0;
532 rawzeros = 0;
533 curlen = 0;
534 curcode = 0;
535 color = 1;
536 count = 0;
537 while (!eof) {
538 if (col >= MAXCOLS) {
539 skiptoeol ();
540 return (col);
541 }
542 do {
543 if (rawzeros >= 11) {
544 nextbit = rawgetbit ();
545 if (nextbit) {
546 if (col == 0)
547 /* XXX should be 6 */
548 eof = (++eols == 3);
549 else
550 eols = 0;
551 #ifdef notdef
552 if (col && col < 1728)
553 pm_message (
554 "warning, row %d short (len %d)",
555 row, col, 0, 0, 0);
556 #endif /* notdef */
557 return (col);
558 }
559 } else
560 nextbit = rawgetbit ();
561 curcode = (curcode << 1) + nextbit;
562 curlen++;
563 } while (curcode <= 0);
564 if (curlen > 13) {
565 pm_message (
566 "bad code word at row %d, col %d (len %d code 0x%x), skipping to EOL",
567 row, col, curlen, curcode, 0);
568 skiptoeol ();
569 return (col);
570 }
571 if (color) {
572 if (curlen < 4)
573 continue;
574 te = hashfind (whash, curlen, curcode, WHASHA, WHASHB);
575 } else {
576 if (curlen < 2)
577 continue;
578 te = hashfind (bhash, curlen, curcode, BHASHA, BHASHB);
579 }
580 if (!te)
581 continue;
582 switch (te->tabid) {
583 case TWTABLE:
584 case TBTABLE:
585 count += te->count;
586 if (col + count > MAXCOLS)
587 count = MAXCOLS - col;
588 if (count > 0) {
589 if (color) {
590 col += count;
591 count = 0;
592 } else {
593 for (; count > 0; --count, ++col)
594 bitrow[col] = PBM_BLACK;
595 }
596 }
597 curcode = 0;
598 curlen = 0;
599 color = !color;
600 break;
601 case MWTABLE:
602 case MBTABLE:
603 count += te->count;
604 curcode = 0;
605 curlen = 0;
606 break;
607 case EXTABLE:
608 count += te->count;
609 curcode = 0;
610 curlen = 0;
611 break;
612 default:
613 pm_error ("internal bad poop", 0, 0, 0, 0, 0);
614 }
615 }
616 return (0);
617 }
618
skiptoeol()619 void skiptoeol ()
620 {
621 while (rawzeros < 11)
622 (void) rawgetbit ();
623 for (;;) {
624 if (rawgetbit ())
625 break;
626 }
627 }
628
629 static X11WDFileHeader h11;
630 static char *dumpname;
631
putinit()632 static void putinit ()
633 {
634 int i;
635 X11XColor color;
636
637 /* Init outfil. */
638 /* Set up the header. */
639 h11.header_size = sizeof (h11) + strlen (dumpname) + 1;
640 h11.file_version = X11WD_FILE_VERSION;
641 h11.pixmap_format = ZPixmap;
642 h11.pixmap_width = XWDCOLS;
643 h11.pixmap_height = XWDROWS;
644 h11.xoffset = 0;
645 h11.byte_order = MSBFirst;
646 h11.bitmap_bit_order = MSBFirst;
647 h11.window_width = XWDCOLS;
648 h11.window_height = XWDROWS;
649 h11.window_x = 0;
650 h11.window_y = 0;
651 h11.window_bdrwidth = 0;
652
653 h11.pixmap_depth = 1;
654 h11.bits_per_pixel = 1;
655 h11.colormap_entries = 2;
656 h11.ncolors = 2;
657 h11.bytes_per_line = (XWDCOLS + 7) / 8;
658 h11.bitmap_unit = 8;
659 h11.bitmap_pad = 8;
660 h11.visual_class = StaticGray;
661 h11.red_mask = 0;
662 h11.green_mask = 0;
663 h11.blue_mask = 0;
664 h11.bits_per_rgb = h11.pixmap_depth;
665
666 /* Write out the header in big-endian order. */
667 pm_writebiglong (stdout, h11.header_size);
668 pm_writebiglong (stdout, h11.file_version);
669 pm_writebiglong (stdout, h11.pixmap_format);
670 pm_writebiglong (stdout, h11.pixmap_depth);
671 pm_writebiglong (stdout, h11.pixmap_width);
672 pm_writebiglong (stdout, h11.pixmap_height);
673 pm_writebiglong (stdout, h11.xoffset);
674 pm_writebiglong (stdout, h11.byte_order);
675 pm_writebiglong (stdout, h11.bitmap_unit);
676 pm_writebiglong (stdout, h11.bitmap_bit_order);
677 pm_writebiglong (stdout, h11.bitmap_pad);
678 pm_writebiglong (stdout, h11.bits_per_pixel);
679 pm_writebiglong (stdout, h11.bytes_per_line);
680 pm_writebiglong (stdout, h11.visual_class);
681 pm_writebiglong (stdout, h11.red_mask);
682 pm_writebiglong (stdout, h11.green_mask);
683 pm_writebiglong (stdout, h11.blue_mask);
684 pm_writebiglong (stdout, h11.bits_per_rgb);
685 pm_writebiglong (stdout, h11.colormap_entries);
686 pm_writebiglong (stdout, h11.ncolors);
687 pm_writebiglong (stdout, h11.window_width);
688 pm_writebiglong (stdout, h11.window_height);
689 pm_writebiglong (stdout, h11.window_x);
690 pm_writebiglong (stdout, h11.window_y);
691 pm_writebiglong (stdout, h11.window_bdrwidth);
692
693 /* Write out the dump name. */
694 fwrite (dumpname, 1, strlen (dumpname) + 1, stdout);
695
696 /* Write out the colormap, big-endian order. */
697 color.flags = 7;
698 color.pad = 0;
699 for (i = 0; i < 2; ++i) {
700 color.pixel = i;
701
702 /* Stupid hack because xloadimage and xwud disagree on * how to
703 * interpret bitmaps. */
704 if (1)
705 color.red = (long) (2 - 1 - i) * 65535 / (2 - 1);
706 else
707 color.red = (long) i *65535 / (2 - 1);
708
709 color.green = color.red;
710 color.blue = color.red;
711 pm_writebiglong (stdout, color.pixel);
712 pm_writebigshort (stdout, color.red);
713 pm_writebigshort (stdout, color.green);
714 pm_writebigshort (stdout, color.blue);
715 putc (color.flags, stdout);
716 putc (color.pad, stdout);
717 }
718 }
719
putrest()720 static void putrest ()
721 {
722 }
723
xwd_writerow(FILE * fd,bit * writerow,int wcols)724 static void xwd_writerow (FILE * fd, bit * writerow, int wcols)
725 {
726 register int bitshift;
727 unsigned char byte;
728 register int s, col;
729
730 bitshift = 7;
731 byte = 0;
732 for (col = 0; col < XWDCOLS; col++) {
733 s = writerow[col] & 1;
734
735 byte |= s << bitshift;
736 bitshift -= h11.bits_per_pixel;
737 if (bitshift < 0) {
738 putchar (byte);
739 bitshift = 7;
740 byte = 0;
741 }
742 }
743 if (bitshift < 7)
744 putchar (byte);
745 };
746
main(argc,argv)747 int main (argc, argv)
748 int argc;
749 char *argv[];
750 {
751 int argn, rows, wrows, cols, wcols, row, wrow, col, wcol, i;
752 int vval, hval, skiprows;
753 bit *readrow, *writerow, *bP, *wbP, bitval;
754 float aspect, scale;
755 int format;
756 register int nzcol;
757
758 char *usage =
759 "g3toxwd [-kludge] [-reversebits] [-scale N] [-aspect N] [-skiprows N] [g3file]";
760
761 argn = 1;
762 kludge = 0;
763 reversebits = 0;
764 aspect = 1.0;
765 scale = (1.0 * XWDCOLS) / (1.0 * MAXCOLS);
766 skiprows = 0;
767 dumpname = "";
768
769 /* Check for flags. */
770 while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
771 if (pm_keymatch (argv[argn], "-kludge", 2))
772 kludge = 1;
773 else if (pm_keymatch (argv[argn], "-reversebits", 2))
774 reversebits = 1;
775 else if (pm_keymatch (argv[argn], "-aspect", 2)) {
776 ++argn;
777 if (argn == argc || sscanf (argv[argn], "%f", &aspect) != 1)
778 pm_usage (usage);
779 } else if (pm_keymatch (argv[argn], "-scale", 2)) {
780 ++argn;
781 if (argn == argc || sscanf (argv[argn], "%f", &scale) != 1)
782 pm_usage (usage);
783 } else if (pm_keymatch (argv[argn], "-skiprows", 2)) {
784 ++argn;
785 if (argn == argc || sscanf (argv[argn], "%d", &skiprows) != 1)
786 pm_usage (usage);
787 } else if (pm_keymatch (argv[argn], "-name", 2)) {
788 ++argn;
789 dumpname = argv[argn];
790 if (argn == argc)
791 pm_usage (usage);
792 } else
793 pm_usage (usage);
794 argn++;
795 }
796
797 if (argn < argc) {
798 if (dumpname[0] == '\0')
799 dumpname = argv[argn];
800 ifp = pm_openr (argv[argn]);
801 argn++;
802 } else {
803 if (dumpname[0] == '\0')
804 dumpname = "stdin";
805 ifp = stdin;
806 }
807
808 if (argn != argc)
809 pm_usage (usage);
810
811 vscale = aspect * scale * 100;
812 hscale = scale * 100;
813 eols = 0;
814
815 putinit ();
816
817 if (kludge) {
818 /* Skip extra lines to get in sync. */
819 skiptoeol ();
820 skiptoeol ();
821 skiptoeol ();
822 }
823 skiptoeol ();
824 for (i = 0; i < HASHSIZE; ++i)
825 whash[i] = bhash[i] = (tableentry *) 0;
826 addtohash (whash, twtable, TABSIZE (twtable), WHASHA, WHASHB);
827 addtohash (whash, mwtable, TABSIZE (mwtable), WHASHA, WHASHB);
828 addtohash (whash, extable, TABSIZE (extable), WHASHA, WHASHB);
829 addtohash (bhash, tbtable, TABSIZE (tbtable), BHASHA, BHASHB);
830 addtohash (bhash, mbtable, TABSIZE (mbtable), BHASHA, BHASHB);
831 addtohash (bhash, extable, TABSIZE (extable), BHASHA, BHASHB);
832
833 wcols = (MAXCOLS * hscale) / 100;
834 writerow = pbm_allocrow (wcols);
835 readrow = pbm_allocrow (MAXCOLS);
836 vval = wrow = row = 0;
837 while (skiprows > 0) {
838 hval = wcol = 0;
839 bP = readrow;
840 wbP = writerow;
841 col = getfaxrow (row, readrow);
842 skiprows--;
843 }
844 while (row < MAXROWS) {
845 for (col = 0, bP = writerow; col < (MAXCOLS * hscale) / 100;
846 ++col, ++bP)
847 *bP = PBM_WHITE;
848 cols = 1;
849 while (vval < 100) {
850 if (row < MAXROWS) {
851 hval = wcol = 0;
852 bP = readrow;
853 wbP = writerow;
854 col = getfaxrow (row, readrow);
855 col--;
856 while ((col > 0) && (readrow[col] == PBM_WHITE))
857 col--;
858 col++;
859 if (col > cols)
860 cols = col;
861 wcols = (cols * hscale) / 100;
862 col = 0;
863 while (col < cols) {
864 bitval = *wbP;
865 while (hval < 100) {
866 if (col++ < cols)
867 if (*bP++ == PBM_BLACK)
868 bitval = PBM_BLACK;
869 hval += hscale;
870 }
871 while (hval >= 100) {
872 if (wcol++ < wcols)
873 *wbP++ = bitval;
874 hval -= 100;
875 }
876 } /* while(col */
877 } /* if(row */
878 vval += vscale;
879 row++;
880 } /* while vval */
881 while (vval >= 100) {
882 if (wrow < XWDROWS) {
883 xwd_writerow (stdout, writerow, wcols);
884 wrow++;
885 }
886 vval -= 100;
887 }
888 if (eof)
889 break;
890 }
891 for (col = 0, bP = writerow; col < (MAXCOLS * hscale) / 100;
892 ++col, ++bP)
893 *bP = PBM_WHITE;
894 while (wrow < XWDROWS) {
895 xwd_writerow (stdout, writerow, wcols);
896 wrow++;
897 }
898
899 return 0;
900 }
901