Bug Summary

File:xpr.c
Location:line 1929, column 6
Description:Value stored to 'ffcount' is never read

Annotated Source Code

1/* $XConsortium: xpr.c,v 1.59 94/10/14 21:22:08 kaleb Exp $ */
2/*
3
4Copyright (c) 1985 X Consortium
5
6Permission is hereby granted, free of charge, to any person obtaining
7a copy of this software and associated documentation files (the
8"Software"), to deal in the Software without restriction, including
9without limitation the rights to use, copy, modify, merge, publish,
10distribute, sublicense, and/or sell copies of the Software, and to
11permit persons to whom the Software is furnished to do so, subject to
12the following conditions:
13
14The above copyright notice and this permission notice shall be included
15in all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of the X Consortium shall
26not be used in advertising or otherwise to promote the sale, use or
27other dealings in this Software without prior written authorization
28from the X Consortium.
29
30*/
31
32/*
33 * XPR - process xwd(1) files for various printers
34 *
35 * Author: Michael R. Gretzinger, MIT Project Athena
36 *
37 * Modified by Marvin Solomon, Univeristy of Wisconsin, to handle Apple
38 * Laserwriter (PostScript) devices (-device ps).
39 * Also accepts the -compact flag that produces more compact output
40 * by using run-length encoding on white (1) pixels.
41 * This version does not (yet) support the following options
42 * -append -dump -noff -nosixopt -split
43 *
44 * Changes
45 * Copyright 1986 by Marvin Solomon and the University of Wisconsin
46 *
47 * Permission to use, copy, modify, and distribute this
48 * software and its documentation for any purpose and without
49 * fee is hereby granted, provided that the above copyright
50 * notice appear in all copies and that both that copyright
51 * notice and this permission notice appear in supporting
52 * documentation, and that the names of Marvin Solomon and
53 * the University of Wisconsin not be used in
54 * advertising or publicity pertaining to distribution of the
55 * software without specific, written prior permission.
56 * Neither Marvin Solomon nor the University of Wisconsin
57 * makes any representations about the suitability of
58 * this software for any purpose. It is provided "as is"
59 * without express or implied warranty.
60 *
61 * Modified by Bob Scheifler for 2x2 grayscale, then ...
62 * Modified by Angela Bock and E. Mike Durbin, Rich Inc., to produce output
63 * using 2x2, 3x3, or 4x4 grayscales. This version modifies the grayscale
64 * conversion option of -gray to accept an input of 2, 3, or 4 to signify
65 * the gray level desired. The output is produced, using 5, 10, or 17-level
66 * gray scales, respectively.
67 *
68 * Modifications by Larry Rupp, Hewlett-Packard Company, to support HP
69 * LaserJet, PaintJet, and other PCL printers. Added "ljet" and "pjet"
70 * to devices recognized. Also added -density, -cutoff, and -noposition
71 * command line options.
72 *
73 */
74
75#include <X11/Xos.h>
76#include <X11/Xfuncs.h>
77#include <X11/Xlib.h>
78#include <X11/Xutil.h>
79#include <stdio.h>
80#include <string.h>
81#ifndef WIN32
82#include <pwd.h>
83#endif
84#include "lncmd.h"
85#include "xpr.h"
86#include <X11/XWDFile.h>
87#include <X11/Xmu/SysUtil.h>
88#ifndef O_BINARY0
89#define O_BINARY0 0
90#endif
91
92#ifdef NLS16
93#ifndef NLS
94#define NLS
95#endif
96#endif
97
98#ifndef NLS
99#define catgets(i, sn,mn,s)(s) (s)
100#else /* NLS */
101#define NL_SETN 1 /* set number */
102#include <nl_types.h>
103
104nl_catd nlmsg_fd;
105#endif /* NLS */
106
107int debug = 0;
108
109#define W_MAX2400 2400
110#define H_MAX3150 3150
111#define W_MARGIN75 75
112#define H_MARGIN37 37
113#define W_PAGE2550 2550
114#define H_PAGE3225 3225
115
116#ifdef NOINLINE1
117#define min(x,y)(((x)<(y))?(x):(y)) (((x)<(y))?(x):(y))
118#endif /* NOINLINE */
119
120#define F_PORTRAIT1 1
121#define F_LANDSCAPE2 2
122#define F_DUMP4 4
123#define F_NOSIXOPT8 8
124#define F_APPEND16 16
125#define F_NOFF32 32
126#define F_REPORT64 64
127#define F_COMPACT128 128
128#define F_INVERT256 256
129#define F_GRAY512 512
130#define F_NPOSITION1024 1024
131#define F_SLIDE2048 2048
132
133#define DEFAULT_CUTOFF((unsigned int) (0xFFFF * 0.50)) ((unsigned int) (0xFFFF * 0.50))
134
135static const char *infilename = NULL((void*)0);
136const char *progname = NULL((void*)0);
137
138typedef struct _grayRec {
139 int level;
140 int sizeX, sizeY; /* 2x2, 3x3, 4x4 */
141 unsigned long *grayscales; /* pointer to the encoded pixels */
142} GrayRec, *GrayPtr;
143
144static unsigned long grayscale2x2[] =
145 {0, 1, 9, 11, 15};
146static unsigned long grayscale3x3[] =
147 {0, 16, 68, 81, 325, 341, 349, 381, 383, 511};
148static unsigned long grayscale4x4[] =
149 {0, 64, 4160, 4161, 20545, 21057, 23105,
150 23113, 23145, 24169, 24171, 56939, 55275, 55279,
151 57327, 65519, 65535};
152
153static GrayRec gray2x2 = {sizeof(grayscale2x2)/sizeof(long), 2, 2, grayscale2x2};
154static GrayRec gray3x3 = {sizeof(grayscale3x3)/sizeof(long), 3, 3, grayscale3x3};
155static GrayRec gray4x4 = {sizeof(grayscale4x4)/sizeof(long), 4, 4, grayscale4x4};
156
157/* mapping tables to map a byte in to the hex representation of its
158 * bit-reversal
159 */
160static const
161char hex1[]="084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
162084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
163084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
164084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f";
165
166static const
167char hex2[]="000000000000000088888888888888884444444444444444cccccccccccccccc\
1682222222222222222aaaaaaaaaaaaaaaa6666666666666666eeeeeeeeeeeeeeee\
169111111111111111199999999999999995555555555555555dddddddddddddddd\
1703333333333333333bbbbbbbbbbbbbbbb7777777777777777ffffffffffffffff";
171
172
173/* Local prototypes */
174static void usage(void) _X_NORETURN__attribute((noreturn));
175static
176void parse_args(
177 int argc,
178 char **argv,
179 int *scale,
180 int *width,
181 int *height,
182 int *left,
183 int *top,
184 enum device *device,
185 int *flags,
186 int *split,
187 char **header,
188 char **trailer,
189 int *plane,
190 GrayPtr *gray,
191 int *density,
192 unsigned int *cutoff,
193 float *gamma,
194 int *render);
195static
196void setup_layout(
197 enum device device,
198 int win_width,
199 int win_height,
200 int flags,
201 int width,
202 int height,
203 char *header,
204 char *trailer,
205 int *scale,
206 enum orientation *orientation);
207static
208char *convert_data(
209 XWDFileHeader *win,
210 char *data,
211 int plane,
212 GrayPtr gray,
213 XColor *colors,
214 int flags);
215static
216void dump_sixmap(
217 register unsigned char (*sixmap)[],
218 int iw,
219 int ih);
220static
221void build_sixmap(
222 int ih,
223 int iw,
224 unsigned char (*sixmap)[],
225 int hpad,
226 XWDFileHeader *win,
227 const char *data);
228static
229void ln03_setup(
230 int iw,
231 int ih,
232 enum orientation orientation,
233 int scale,
234 int left,
235 int top,
236 int *left_margin,
237 int *top_margin,
238 int flags,
239 const char *header,
240 const char *trailer);
241static void ln03_finish(void);
242static void la100_setup(int iw, int ih, int scale);
243static void la100_finish(void);
244static void dump_prolog(int flags);
245static int points(int n);
246static char *escape(const char *s);
247static
248void ps_setup(
249 int iw,
250 int ih,
251 enum orientation orientation,
252 int scale,
253 int left,
254 int top,
255 int flags,
256 const char *header,
257 const char *trailer,
258 const char *name);
259static void ps_finish(void);
260static
261void ln03_output_sixels(
262 unsigned char (*sixmap)[],
263 int iw,
264 int ih,
265 int nosixopt,
266 int split,
267 int scale,
268 int top_margin,
269 int left_margin);
270static void la100_output_sixels(
271 unsigned char (*sixmap)[],
272 int iw,
273 int ih,
274 int nosixopt);
275static void ps_output_bits(
276 int iw,
277 int ih,
278 int flags,
279 enum orientation orientation,
280 XWDFileHeader *win,
281 const char *data);
282static int ps_putbuf(
283 register unsigned char *s,
284 register int n,
285 register int ocount,
286 int compact);
287static void ps_bitrot(
288 unsigned char *s,
289 register int n,
290 int col,
291 register int owidth,
292 char *obuf);
293static void fullread (
294 int file,
295 char *data,
296 int nbytes);
297
298int main(int argc, char **argv)
299{
300 unsigned long swaptest = 1;
301 XWDFileHeader win;
302 register unsigned char (*sixmap)[];
303 register int i;
304 register int iw;
305 register int ih;
306 register int sixel_count;
307 char *w_name;
308 int scale, width, height, flags, split;
309 int left, top;
310 int top_margin, left_margin;
311 int hpad;
312 char *header, *trailer;
313 int plane;
314 int density, render;
315 unsigned int cutoff;
316 float gamma;
317 GrayPtr gray;
318 char *data;
319 long size;
320 enum orientation orientation;
321 enum device device;
322 XColor *colors = (XColor *)NULL((void*)0);
323
324 if (!(progname = argv[0]))
325 progname = "xpr";
326#ifdef NLS
327 nlmsg_fd = catopen("xpr", 0);
328#endif
329 parse_args (argc, argv, &scale, &width, &height, &left, &top, &device,
330 &flags, &split, &header, &trailer, &plane, &gray,
331 &density, &cutoff, &gamma, &render);
332
333 if (device == PP) {
334 x2pmp(stdinstdin, stdoutstdout, scale,
335 width >= 0? inch2pel((float)width/300.0)((int) (((float)width/300.0) * 240)): X_MAX_PELS((int) ((8.5) * 240)),
336 height >= 0? inch2pel((float)height/300.0)((int) (((float)height/300.0) * 240)): Y_MAX_PELS((int) ((11) * 240)),
337 left >= 0? inch2pel((float)left/300.0)((int) (((float)left/300.0) * 240)): inch2pel(0.60)((int) ((0.60) * 240)),
338 top >= 0? inch2pel((float)top/300.0)((int) (((float)top/300.0) * 240)): inch2pel(0.70)((int) ((0.70) * 240)),
339 header, trailer,
340 (flags & F_PORTRAIT1)? PORTRAIT:
341 ((flags & F_LANDSCAPE2)? LANDSCAPE: UNSPECIFIED),
342 (flags & F_INVERT256));
343 exit(0);
344 } else if ((device == LJET) || (device == PJET) || (device == PJETXL)) {
345 x2jet(stdinstdin, stdoutstdout, scale, density, width, height, left, top,
346 header, trailer,
347 (flags & F_PORTRAIT1)? PORTRAIT:
348 ((flags & F_LANDSCAPE2)? LANDSCAPE: UNSPECIFIED),
349 (flags & F_INVERT256),
350 ((flags & F_APPEND16) && !(flags & F_NOFF32)),
351 !(flags & F_NPOSITION1024),
352 (flags & F_SLIDE2048),
353 device, cutoff, gamma, render);
354 exit(0);
355 }
356
357 /* read in window header */
358 fullread(0, (char *)&win, sizeof win);
359 if (*(char *) &swaptest)
360 _swaplong((char *) &win, (long)sizeof(win));
361
362 if (win.file_version != XWD_FILE_VERSION7) {
363 fprintf(stderrstderr,"xpr: file format version missmatch.\n");
364 exit(1);
365 }
366 if (win.header_size < sizeof(win)) {
367 fprintf(stderrstderr,"xpr: header size is too small.\n");
368 exit(1);
369 }
370
371 w_name = malloc((unsigned)(win.header_size - sizeof win));
372 fullread(0, w_name, (int) (win.header_size - sizeof win));
373
374 if(win.ncolors) {
375 XWDColor xwdcolor;
376 colors = (XColor *)malloc((unsigned) (win.ncolors * sizeof(XColor)));
377 for (i = 0; i < win.ncolors; i++) {
378 fullread(0, (char*)&xwdcolor, (int) sizeof xwdcolor);
379 colors[i].pixel = xwdcolor.pixel;
380 colors[i].red = xwdcolor.red;
381 colors[i].green = xwdcolor.green;
382 colors[i].blue = xwdcolor.blue;
383 colors[i].flags = xwdcolor.flags;
384 }
385 if (*(char *) &swaptest) {
386 for (i = 0; i < win.ncolors; i++) {
387 _swaplong((char *) &colors[i].pixel, (long)sizeof(long));
388 _swapshort((char *) &colors[i].red, (long) (3 * sizeof(short)));
389 }
390 }
391 if ((win.ncolors == 2) &&
392 (INTENSITY(&colors[0])(30L*(int)(&colors[0])->red + 59L*(int)(&colors[0]
)->green + 11L*(int)(&colors[0])->blue)
> INTENSITY(&colors[1])(30L*(int)(&colors[1])->red + 59L*(int)(&colors[1]
)->green + 11L*(int)(&colors[1])->blue)
))
393 flags ^= F_INVERT256;
394 }
395 if (plane >= (long)win.pixmap_depth) {
396 fprintf(stderrstderr,"xpr: plane number exceeds image depth\n");
397 exit(1);
398 }
399 size = win.bytes_per_line * win.pixmap_height;
400 if (win.pixmap_format == XYPixmap1)
401 size *= win.pixmap_depth;
402 data = malloc((unsigned)size);
403 fullread(0, data, (int)size);
404 if ((win.pixmap_depth > 1) || (win.byte_order != win.bitmap_bit_order)) {
405 data = convert_data(&win, data, plane, gray, colors, flags);
406 size = win.bytes_per_line * win.pixmap_height;
407 }
408 if (win.bitmap_bit_order == MSBFirst1) {
409 _swapbits((unsigned char *)data, size);
410 win.bitmap_bit_order = LSBFirst0;
411 }
412 if (flags & F_INVERT256)
413 _invbits((unsigned char *)data, size);
414
415 /* calculate orientation and scale */
416 setup_layout(device, (int) win.pixmap_width, (int) win.pixmap_height,
417 flags, width, height, header, trailer, &scale, &orientation);
418
419 if (device == PS) {
420 iw = win.pixmap_width;
421 ih = win.pixmap_height;
422 sixmap = NULL((void*)0);
423 } else {
424 /* calculate w and h cell count */
425 iw = win.pixmap_width;
426 ih = (win.pixmap_height + 5) / 6;
427 hpad = (ih * 6) - win.pixmap_height;
428
429 /* build pixcells from input file */
430 sixel_count = iw * ih;
431 sixmap = (unsigned char (*)[])malloc((unsigned)sixel_count);
432 build_sixmap(iw, ih, sixmap, hpad, &win, data);
433 }
434
435 /* output commands and sixel graphics */
436 if (device == LN03) {
437/* ln03_grind_fonts(sixmap, iw, ih, scale, &pixmap); */
438 ln03_setup(iw, ih, orientation, scale, left, top,
439 &left_margin, &top_margin, flags, header, trailer);
440 ln03_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT8), split,
441 scale, top_margin, left_margin);
442 ln03_finish();
443 } else if (device == LA100) {
444 la100_setup(iw, ih, scale);
445 la100_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT8));
446 la100_finish();
447 } else if (device == PS) {
448 ps_setup(iw, ih, orientation, scale, left, top,
449 flags, header, trailer, w_name);
450 ps_output_bits(iw, ih, flags, orientation, &win, data);
451 ps_finish();
452 } else {
453 fprintf(stderrstderr, "xpr: device not supported\n");
454 }
455
456 /* print some statistics */
457 if (flags & F_REPORT64) {
458 fprintf(stderrstderr, "Name: %s\n", w_name);
459 fprintf(stderrstderr, "Width: %d, Height: %d\n", (int)win.pixmap_width,
460 (int)win.pixmap_height);
461 fprintf(stderrstderr, "Orientation: %s, Scale: %d\n",
462 (orientation==PORTRAIT) ? "Portrait" : "Landscape", scale);
463 }
464 if (((device == LN03) || (device == LA100)) && (flags & F_DUMP4))
465 dump_sixmap(sixmap, iw, ih);
466 exit(EXIT_SUCCESS0);
467}
468
469static
470void usage(void)
471{
472 fprintf(stderrstderr, "usage: %s [options] [file]\n", progname);
473 fprintf(stderrstderr, " -append <file> -noff -output <file>\n");
474 fprintf(stderrstderr, " -compact\n");
475 fprintf(stderrstderr, " -device {ln03 | la100 | ps | lw | pp | ljet | pjet | pjetxl}\n");
476 fprintf(stderrstderr, " -dump\n");
477 fprintf(stderrstderr, " -gamma <correction>\n");
478 fprintf(stderrstderr, " -gray {2 | 3 | 4}\n");
479 fprintf(stderrstderr, " -height <inches> -width <inches>\n");
480 fprintf(stderrstderr, " -header <string> -trailer <string>\n");
481 fprintf(stderrstderr, " -landscape -portrait\n");
482 fprintf(stderrstderr, " -left <inches> -top <inches>\n");
483 fprintf(stderrstderr, " -noposition\n");
484 fprintf(stderrstderr, " -nosixopt\n");
485 fprintf(stderrstderr, " -plane <n>\n");
486 fprintf(stderrstderr, " -psfig\n");
487 fprintf(stderrstderr, " -render <type>\n");
488 fprintf(stderrstderr, " -report\n");
489 fprintf(stderrstderr, " -rv\n");
490 fprintf(stderrstderr, " -scale <scale>\n");
491 fprintf(stderrstderr, " -slide\n");
492 fprintf(stderrstderr, " -split <n-pages>\n");
493 exit(EXIT_FAILURE1);
494}
495
496static
497void parse_args(
498 int argc,
499 char **argv,
500 int *scale,
501 int *width,
502 int *height,
503 int *left,
504 int *top,
505 enum device *device,
506 int *flags,
507 int *split,
508 char **header,
509 char **trailer,
510 int *plane,
511 GrayPtr *gray,
512 int *density,
513 unsigned int *cutoff,
514 float *gamma,
515 int *render)
516{
517 register char *output_filename;
518 register int f;
519 register int len;
520 register int pos;
521
522 output_filename = NULL((void*)0);
523 *device = PS; /* default */
524 *flags = 0;
525 *scale = 0;
526 *split = 1;
527 *width = -1;
528 *height = -1;
529 *top = -1;
530 *left = -1;
531 *header = NULL((void*)0);
532 *trailer = NULL((void*)0);
533 *plane = -1;
534 *gray = (GrayPtr)NULL((void*)0);
535 *density = 0;
536 *cutoff = DEFAULT_CUTOFF((unsigned int) (0xFFFF * 0.50));
537 *gamma = -1.0;
538 *render = 0;
539
540 for (argc--, argv++; argc > 0; argc--, argv++) {
541 if (argv[0][0] != '-') {
542 infilename = *argv;
543 continue;
544 }
545 len = strlen(*argv);
546 switch (argv[0][1]) {
547 case 'a': /* -append <filename> */
548 if (!bcmp(*argv, "-append", len)) {
549 argc--; argv++;
550 if (argc == 0) usage();
551 output_filename = *argv;
552 *flags |= F_APPEND16;
553 } else
554 usage();
555 break;
556
557 case 'c': /* -compact | -cutoff <intensity> */
558 if (len <= 2 )
559 usage();
560 if (!bcmp(*argv, "-compact", len)) {
561 *flags |= F_COMPACT128;
562 } else if (!bcmp(*argv, "-cutoff", len)) {
563 argc--; argv++;
564 if (argc == 0) usage();
565 *cutoff = min((atof(*argv) / 100.0 * 0xFFFF), 0xFFFF)((((atof(*argv) / 100.0 * 0xFFFF))<(0xFFFF))?((atof(*argv)
/ 100.0 * 0xFFFF)):(0xFFFF))
;
566 } else
567 usage();
568 break;
569
570 case 'd': /* -density <num> | -device <dev> | -dump */
571 if (len <= 2)
572 usage();
573 if (!bcmp(*argv, "-dump", len)) {
574 *flags |= F_DUMP4;
575 } else if (len <= 3) {
576 usage();
577 } else if (!bcmp(*argv, "-density", len)) {
578 argc--; argv++;
579 if (argc == 0) usage();
580 *density = atoi(*argv);
581 } else if (!bcmp(*argv, "-device", len)) {
582 argc--; argv++;
583 if (argc == 0) usage();
584 len = strlen(*argv);
585 if (len < 2)
586 usage();
587 if (!bcmp(*argv, "ln03", len)) {
588 *device = LN03;
589 } else if (!bcmp(*argv, "la100", len)) {
590 *device = LA100;
591 } else if (!bcmp(*argv, "ps", len)) {
592 *device = PS;
593 } else if (!bcmp(*argv, "lw", len)) {
594 *device = PS;
595 } else if (!bcmp(*argv, "pp", len)) {
596 *device = PP;
597 } else if (!bcmp(*argv, "ljet", len)) {
598 *device = LJET;
599 } else if (!bcmp(*argv, "pjet", len)) {
600 *device = PJET;
601 } else if (!bcmp(*argv, "pjetxl", len)) {
602 *device = PJETXL;
603 } else
604 usage();
605 } else
606 usage();
607 break;
608
609 case 'g': /* -gamma <float> | -gray <num> */
610 if (len <= 2)
611 usage();
612 if (!bcmp(*argv, "-gamma", len)) {
613 argc--; argv++;
614 if (argc == 0) usage();
615 *gamma = atof(*argv);
616 } else if (!bcmp(*argv, "-gray", len) ||
617 !bcmp(*argv, "-grey", len)) {
618 argc--; argv++;
619 if (argc == 0) usage();
620 switch (atoi(*argv)) {
621 case 2:
622 *gray = &gray2x2;
623 break;
624 case 3:
625 *gray = &gray3x3;
626 break;
627 case 4:
628 *gray = &gray4x4;
629 break;
630 default:
631 usage();
632 }
633 *flags |= F_GRAY512;
634 } else
635 usage();
636 break;
637
638 case 'h': /* -height <inches> | -header <string> */
639 if (len <= 3)
640 usage();
641 if (!bcmp(*argv, "-height", len)) {
642 argc--; argv++;
643 if (argc == 0) usage();
644 *height = (int)(300.0 * atof(*argv));
645 } else if (!bcmp(*argv, "-header", len)) {
646 argc--; argv++;
647 if (argc == 0) usage();
648 *header = *argv;
649 } else
650 usage();
651 break;
652
653 case 'l': /* -landscape | -left <inches> */
654 if (len <= 2)
655 usage();
656 if (!bcmp(*argv, "-landscape", len)) {
657 *flags |= F_LANDSCAPE2;
658 } else if (!bcmp(*argv, "-left", len)) {
659 argc--; argv++;
660 if (argc == 0) usage();
661 *left = (int)(300.0 * atof(*argv));
662 } else
663 usage();
664 break;
665
666 case 'n': /* -nosixopt | -noff | -noposition */
667 if (len <= 3)
668 usage();
669 if (!bcmp(*argv, "-nosixopt", len)) {
670 *flags |= F_NOSIXOPT8;
671 } else if (!bcmp(*argv, "-noff", len)) {
672 *flags |= F_NOFF32;
673 } else if (!bcmp(*argv, "-noposition", len)) {
674 *flags |= F_NPOSITION1024;
675 } else
676 usage();
677 break;
678
679 case 'o': /* -output <filename> */
680 if (!bcmp(*argv, "-output", len)) {
681 argc--; argv++;
682 if (argc == 0) usage();
683 output_filename = *argv;
684 } else
685 usage();
686 break;
687
688 case 'p': /* -portrait | -plane <n> */
689 if (len <= 2)
690 usage();
691 if (!bcmp(*argv, "-portrait", len)) {
692 *flags |= F_PORTRAIT1;
693 } else if (!bcmp(*argv, "-plane", len)) {
694 argc--; argv++;
695 if (argc == 0) usage();
696 *plane = atoi(*argv);
697 } else if (!bcmp(*argv, "-psfig", len)) {
698 *flags |= F_NPOSITION1024;
699 } else
700 usage();
701 break;
702
703 case 'r': /* -render <type> | -report | -rv */
704 if (len <= 2)
705 usage();
706 if (!bcmp(*argv, "-rv", len)) {
707 *flags |= F_INVERT256;
708 } else if (len <= 3) {
709 usage();
710 } else if (!bcmp(*argv, "-render", len)) {
711 argc--; argv++;
712 if (argc == 0) usage();
713 *render = atoi(*argv);
714 } else if (!bcmp(*argv, "-report", len)) {
715 *flags |= F_REPORT64;
716 } else
717 usage();
718 break;
719
720 case 's': /* -scale <scale> | -slide | -split <n-pages> */
721 if (len <= 2)
722 usage();
723 if (!bcmp(*argv, "-scale", len)) {
724 argc--; argv++;
725 if (argc == 0) usage();
726 *scale = atoi(*argv);
727 } else if (!bcmp(*argv, "-slide", len)) {
728 *flags |= F_SLIDE2048;
729 } else if (!bcmp(*argv, "-split", len)) {
730 argc--; argv++;
731 if (argc == 0) usage();
732 *split = atoi(*argv);
733 } else
734 usage();
735 break;
736
737 case 't': /* -top <inches> | -trailer <string> */
738 if (len <= 2)
739 usage();
740 if (!bcmp(*argv, "-top", len)) {
741 argc--; argv++;
742 if (argc == 0) usage();
743 *top = (int)(300.0 * atof(*argv));
744 } else if (!bcmp(*argv, "-trailer", len)) {
745 argc--; argv++;
746 if (argc == 0) usage();
747 *trailer = *argv;
748 } else
749 usage();
750 break;
751
752 case 'w': /* -width <inches> */
753 if (!bcmp(*argv, "-width", len)) {
754 argc--; argv++;
755 if (argc == 0) usage();
756 *width = (int)(300.0 * atof(*argv));
757 } else
758 usage();
759 break;
760
761 default:
762 usage();
763 break;
764 }
765 }
766
767 if (infilename) {
768 f = open(infilename, O_RDONLY00|O_BINARY0, 0);
769 if (f < 0) {
770 fprintf(stderrstderr, "xpr: error opening \"%s\" for input\n",
771 infilename);
772 perror("");
773 exit(1);
774 }
775 dup2(f, 0);
776 close(f);
777 } else
778 infilename = "stdin";
779
780 if (output_filename != NULL((void*)0)) {
781 if (!(*flags & F_APPEND16)) {
782 f = open(output_filename, O_CREAT0100|O_WRONLY01|O_TRUNC01000, 0664);
783 } else {
784 f = open(output_filename, O_WRONLY01, 0);
785 }
786 if (f < 0) {
787 fprintf(stderrstderr, "xpr: error opening \"%s\" for output\n",
788 output_filename);
789 perror("xpr");
790 exit(1);
791 }
792 if (*flags & F_APPEND16) {
793 pos = lseek(f, 0, 2); /* get eof position */
794 if ((*flags & F_NOFF32) &&
795 !(*device == LJET || *device == PJET || *device == PJETXL))
796 pos -= 3; /* set position before trailing */
797 /* formfeed and reset */
798 lseek(f, pos, 0); /* set pointer */
799 }
800 dup2(f, 1);
801 close(f);
802 }
803}
804
805static
806void setup_layout(
807 enum device device,
808 int win_width,
809 int win_height,
810 int flags,
811 int width,
812 int height,
813 char *header,
814 char *trailer,
815 int *scale,
816 enum orientation *orientation)
817{
818 register int w_scale;
819 register int h_scale;
820 register int iscale = *scale;
821 register int w_max;
822 register int h_max;
823
824 if (header != NULL((void*)0)) win_height += 75;
825 if (trailer != NULL((void*)0)) win_height += 75;
826
827 /* check maximum width and height; set orientation and scale*/
828 if (device == LN03 || device == PS) {
829 if ((win_width < win_height || (flags & F_PORTRAIT1)) &&
830 !(flags & F_LANDSCAPE2)) {
831 *orientation = PORTRAIT;
832 w_max = (width > 0)? width : W_MAX2400;
833 h_max = (height > 0)? height : H_MAX3150;
834 w_scale = w_max / win_width;
835 h_scale = h_max / win_height;
836 *scale = min(w_scale, h_scale)(((w_scale)<(h_scale))?(w_scale):(h_scale));
837 } else {
838 *orientation = LANDSCAPE;
839 w_max = (width > 0)? width : H_MAX3150;
840 h_max = (height > 0)? height : W_MAX2400;
841 w_scale = w_max / win_width;
842 h_scale = h_max / win_height;
843 *scale = min(w_scale, h_scale)(((w_scale)<(h_scale))?(w_scale):(h_scale));
844 }
845 } else { /* device == LA100 */
846 *orientation = PORTRAIT;
847 *scale = W_MAX2400 / win_width;
848 }
849 if (*scale == 0) *scale = 1;
850 if (*scale > 6) *scale = 6;
851 if (iscale > 0 && iscale < *scale) *scale = iscale;
852}
853
854static
855char *convert_data(
856 XWDFileHeader *win,
857 char *data,
858 int plane,
859 GrayPtr gray,
860 XColor *colors,
861 int flags)
862{
863 XImage in_image_struct, out_image_struct;
864 register XImage *in_image, *out_image;
865 register int x, y;
866
867 if ((win->pixmap_format == XYPixmap1) && (plane >= 0)) {
868 data += win->bytes_per_line * win->pixmap_height *
869 (win->pixmap_depth - (plane + 1));
870 win->pixmap_format = XYBitmap0;
871 win->pixmap_depth = 1;
872 return data;
873 }
874
875 /* initialize the input image */
876
877 in_image = &in_image_struct;
878 in_image->byte_order = win->byte_order;
879 in_image->bitmap_unit = win->bitmap_unit;
880 in_image->bitmap_bit_order = win->bitmap_bit_order;
881 in_image->depth = win->pixmap_depth;
882 in_image->bits_per_pixel = win->bits_per_pixel;
883 in_image->format = win->pixmap_format,
884 in_image->xoffset = win->xoffset,
885 in_image->data = data;
886 in_image->width = win->pixmap_width;
887 in_image->height = win->pixmap_height;
888 in_image->bitmap_pad = win->bitmap_pad;
889 in_image->bytes_per_line = win->bytes_per_line;
890 in_image->red_mask = win->red_mask;
891 in_image->green_mask = win->green_mask;
892 in_image->blue_mask = win->blue_mask;
893 in_image->obdata = NULL((void*)0);
894 if (!XInitImage(in_image)) {
895 fprintf(stderrstderr,"xpr: bad input image header data.\n");
896 exit(1);
897 }
898 if ((flags & F_GRAY512) && (in_image->depth > 1) && (plane < 0)) {
899 win->pixmap_width *= gray->sizeX;
900 win->pixmap_height *= gray->sizeY;
901 }
902 win->xoffset = 0;
903 win->pixmap_format = XYBitmap0;
904 win->byte_order = LSBFirst0;
905 win->bitmap_unit = 8;
906 win->bitmap_bit_order = LSBFirst0;
907 win->bitmap_pad = 8;
908 win->pixmap_depth = 1;
909 win->bits_per_pixel = 1;
910 win->bytes_per_line = (win->pixmap_width + 7) >> 3;
911
912 out_image = &out_image_struct;
913 out_image->byte_order = win->byte_order;
914 out_image->bitmap_unit = win->bitmap_unit;
915 out_image->bitmap_bit_order = win->bitmap_bit_order;
916 out_image->depth = win->pixmap_depth;
917 out_image->bits_per_pixel = win->bits_per_pixel;
918 out_image->format = win->pixmap_format;
919 out_image->xoffset = win->xoffset,
920 out_image->width = win->pixmap_width;
921 out_image->height = win->pixmap_height;
922 out_image->bitmap_pad = win->bitmap_pad;
923 out_image->bytes_per_line = win->bytes_per_line;
924 out_image->red_mask = 0;
925 out_image->green_mask = 0;
926 out_image->blue_mask = 0;
927 out_image->obdata = NULL((void*)0);
928 out_image->data = malloc((unsigned)out_image->bytes_per_line *
929 out_image->height);
930 if (!XInitImage(out_image)) {
931 fprintf(stderrstderr,"xpr: bad output image header data.\n");
932 exit(1);
933 }
934
935 if ((in_image->depth > 1) && (plane > 0)) {
936 for (y = 0; y < in_image->height; y++)
937 for (x = 0; x < in_image->width; x++)
938 XPutPixel(out_image, x, y,((*((out_image)->f.put_pixel))((out_image), (x), (y), ((((
*((in_image)->f.get_pixel))((in_image), (x), (y))) >>
plane) & 1)))
939 (XGetPixel(in_image, x, y) >> plane) & 1)((*((out_image)->f.put_pixel))((out_image), (x), (y), ((((
*((in_image)->f.get_pixel))((in_image), (x), (y))) >>
plane) & 1)))
;
940 } else if (plane == 0) {
941 for (y = 0; y < in_image->height; y++)
942 for (x = 0; x < in_image->width; x++)
943 XPutPixel(out_image, x, y, XGetPixel(in_image, x, y))((*((out_image)->f.put_pixel))((out_image), (x), (y), (((*
((in_image)->f.get_pixel))((in_image), (x), (y))))))
;
944 } else if ((in_image->depth > 1) &&
945 ((win->visual_class == TrueColor4) ||
946 (win->visual_class == DirectColor5))) {
947 XColor color;
948 int direct = 0;
949 unsigned long rmask, gmask, bmask;
950 int rshift = 0, gshift = 0, bshift = 0;
951
952 rmask = win->red_mask;
953 while (!(rmask & 1)) {
954 rmask >>= 1;
955 rshift++;
956 }
957 gmask = win->green_mask;
958 while (!(gmask & 1)) {
959 gmask >>= 1;
960 gshift++;
961 }
962 bmask = win->blue_mask;
963 while (!(bmask & 1)) {
964 bmask >>= 1;
965 bshift++;
966 }
967 if ((win->ncolors == 0) || (win->visual_class == DirectColor5))
968 direct = 1;
969 if (flags & F_GRAY512) {
970 register int ox, oy;
971 int ix, iy;
972 unsigned long bits;
973 for (y = 0, oy = 0; y < in_image->height; y++, oy += gray->sizeY)
974 for (x = 0, ox = 0; x < in_image->width; x++, ox += gray->sizeX)
975 {
976 color.pixel = XGetPixel(in_image, x, y)((*((in_image)->f.get_pixel))((in_image), (x), (y)));
977 color.red = (color.pixel >> rshift) & rmask;
978 color.green = (color.pixel >> gshift) & gmask;
979 color.blue = (color.pixel >> bshift) & bmask;
980 if (!direct) {
981 color.red = colors[color.red].red;
982 color.green = colors[color.green].green;
983 color.blue = colors[color.blue].blue;
984 }
985 bits = gray->grayscales[(int)(gray->level *
986 INTENSITY(&color)(30L*(int)(&color)->red + 59L*(int)(&color)->green
+ 11L*(int)(&color)->blue)
) /
987 (INTENSITYPER(100)(((1<<16)-1)*((long)(100))) + 1)];
988 for (iy = 0; iy < gray->sizeY; iy++)
989 for (ix = 0; ix < gray->sizeX; ix++, bits >>= 1)
990 XPutPixel(out_image, ox + ix, oy + iy, bits)((*((out_image)->f.put_pixel))((out_image), (ox + ix), (oy
+ iy), (bits)))
;
991 }
992 } else {
993 for (y = 0; y < in_image->height; y++)
994 for (x = 0; x < in_image->width; x++) {
995 color.pixel = XGetPixel(in_image, x, y)((*((in_image)->f.get_pixel))((in_image), (x), (y)));
996 color.red = (color.pixel >> rshift) & rmask;
997 color.green = (color.pixel >> gshift) & gmask;
998 color.blue = (color.pixel >> bshift) & bmask;
999 if (!direct) {
1000 color.red = colors[color.red].red;
1001 color.green = colors[color.green].green;
1002 color.blue = colors[color.blue].blue;
1003 }
1004 XPutPixel(out_image, x, y,((*((out_image)->f.put_pixel))((out_image), (x), (y), ((30L
*(int)(&color)->red + 59L*(int)(&color)->green +
11L*(int)(&color)->blue) > (((1<<16)-1)*((long
)(50))))))
1005 INTENSITY(&color) > HALFINTENSITY)((*((out_image)->f.put_pixel))((out_image), (x), (y), ((30L
*(int)(&color)->red + 59L*(int)(&color)->green +
11L*(int)(&color)->blue) > (((1<<16)-1)*((long
)(50))))))
;
1006 }
1007 }
1008 } else if (flags & F_GRAY512) {
1009 register int ox, oy;
1010 int ix, iy;
1011 unsigned long bits;
1012
1013 if (win->ncolors == 0) {
1014 fprintf(stderrstderr, "no colors in data, can't remap\n");
1015 exit(1);
1016 }
1017 for (x = 0; x < win->ncolors; x++) {
1018 register XColor *color = &colors[x];
1019
1020 color->pixel = gray->grayscales[(gray->level * INTENSITY(color)(30L*(int)(color)->red + 59L*(int)(color)->green + 11L*
(int)(color)->blue)
) /
1021 (INTENSITYPER(100)(((1<<16)-1)*((long)(100))) + 1)];
1022 }
1023 for (y = 0, oy = 0; y < in_image->height; y++, oy += gray->sizeY)
1024 for (x = 0, ox = 0; x < in_image->width; x++, ox += gray->sizeX) {
1025 bits = colors[XGetPixel(in_image, x, y)((*((in_image)->f.get_pixel))((in_image), (x), (y)))].pixel;
1026 for (iy = 0; iy < gray->sizeY; iy++)
1027 for (ix = 0; ix < gray->sizeX; ix++, bits >>= 1)
1028 XPutPixel(out_image, ox + ix, oy + iy, bits)((*((out_image)->f.put_pixel))((out_image), (ox + ix), (oy
+ iy), (bits)))
;
1029 }
1030 } else {
1031 if (win->ncolors == 0) {
1032 fprintf(stderrstderr, "no colors in data, can't remap\n");
1033 exit(1);
1034 }
1035 for (x = 0; x < win->ncolors; x++) {
1036 register XColor *color = &colors[x];
1037 color->pixel = (INTENSITY(color)(30L*(int)(color)->red + 59L*(int)(color)->green + 11L*
(int)(color)->blue)
> HALFINTENSITY(((1<<16)-1)*((long)(50))));
1038 }
1039 for (y = 0; y < in_image->height; y++)
1040 for (x = 0; x < in_image->width; x++)
1041 XPutPixel(out_image, x, y,((*((out_image)->f.put_pixel))((out_image), (x), (y), (colors
[((*((in_image)->f.get_pixel))((in_image), (x), (y)))].pixel
)))
1042 colors[XGetPixel(in_image, x, y)].pixel)((*((out_image)->f.put_pixel))((out_image), (x), (y), (colors
[((*((in_image)->f.get_pixel))((in_image), (x), (y)))].pixel
)))
;
1043 }
1044 free(data);
1045 return (out_image->data);
1046}
1047
1048static
1049void dump_sixmap(
1050 register unsigned char (*sixmap)[],
1051 int iw,
1052 int ih)
1053{
1054 register int i, j;
1055 register unsigned char *c;
1056
1057 c = (unsigned char *)sixmap;
1058 fprintf(stderrstderr, "Sixmap:\n");
1059 for (i = 0; i < ih; i++) {
1060 for (j = 0; j < iw; j++) {
1061 fprintf(stderrstderr, "%02X ", *c++);
1062 }
1063 fprintf(stderrstderr, "\n\n");
1064 }
1065}
1066
1067static
1068void build_sixmap(
1069 int ih,
1070 int iw,
1071 unsigned char (*sixmap)[],
1072 int hpad,
1073 XWDFileHeader *win,
1074 const char *data)
1075{
1076 int iwb = win->bytes_per_line;
1077 unsigned char *line[6];
1078 register unsigned char *c;
1079 register int i, j;
1080#ifdef NOINLINE1
1081 register int w;
1082#endif
1083 register int sixel;
1084 unsigned char *buffer = (unsigned char *)data;
1085
1086 c = (unsigned char *)sixmap;
1087
1088
1089 while (--ih >= 0) {
1090 for (i = 0; i <= 5; i++) {
1091 line[i] = buffer;
1092 buffer += iwb;
1093 }
1094 if ((ih == 0) && (hpad > 0)) {
1095 unsigned char *ffbuf;
1096
1097 ffbuf = (unsigned char *)malloc((unsigned)iwb);
1098 for (j = 0; j < iwb; j++)
1099 ffbuf[j] = 0xFF;
1100 for (; --hpad >= 0; i--)
1101 line[i] = ffbuf;
1102 }
1103
1104#ifndef NOINLINE1
1105 for (i = 0; i < iw; i++) {
1106 sixel = extzv(line[0], i, 1);
1107 sixel |= extzv(line[1], i, 1) << 1;
1108 sixel |= extzv(line[2], i, 1) << 2;
1109 sixel |= extzv(line[3], i, 1) << 3;
1110 sixel |= extzv(line[4], i, 1) << 4;
1111 sixel |= extzv(line[5], i, 1) << 5;
1112 *c++ = sixel;
1113 }
1114#else
1115 for (i = 0, w = iw; w > 0; i++) {
1116 for (j = 0; j <= 7; j++) {
1117 sixel = ((line[0][i] >> j) & 1);
1118 sixel |= ((line[1][i] >> j) & 1) << 1;
1119 sixel |= ((line[2][i] >> j) & 1) << 2;
1120 sixel |= ((line[3][i] >> j) & 1) << 3;
1121 sixel |= ((line[4][i] >> j) & 1) << 4;
1122 sixel |= ((line[5][i] >> j) & 1) << 5;
1123 *c++ = sixel;
1124 if (--w == 0) break;
1125 }
1126 }
1127#endif
1128 }
1129}
1130
1131/*
1132ln03_grind_fonts(sixmap, iw, ih, scale, pixmap)
1133unsigned char (*sixmap)[];
1134int iw;
1135int ih;
1136int scale;
1137struct pixmap (**pixmap)[];
1138{
1139}
1140*/
1141
1142static
1143void ln03_setup(
1144 int iw,
1145 int ih,
1146 enum orientation orientation,
1147 int scale,
1148 int left,
1149 int top,
1150 int *left_margin,
1151 int *top_margin,
1152 int flags,
1153 const char *header,
1154 const char *trailer)
1155{
1156 register int i;
1157 register int lm, tm, xm;
1158 char buf[256];
1159 register char *bp = buf;
1160
1161 if (!(flags & F_APPEND16)) {
1162 sprintf(bp, LN_STR"\033[!p"); bp += 4;
1163 sprintf(bp, LN_SSU"\033[%d I", 7); bp += 5;
1164 sprintf(bp, LN_PUM_SET"\033[11h"); bp += sizeof LN_PUM_SET"\033[11h" - 1;
1165 }
1166
1167 if (orientation == PORTRAIT) {
1168 lm = (left > 0)? left : (((W_MAX2400 - scale * iw) / 2) + W_MARGIN75);
1169 tm = (top > 0)? top : (((H_MAX3150 - scale * ih * 6) / 2) + H_MARGIN37);
1170 sprintf(bp, LN_PFS"\033[%s J", "?20"); bp += 7;
1171 sprintf(bp, LN_DECOPM_SET"\033[?52h"); bp += sizeof LN_DECOPM_SET"\033[?52h" - 1;
1172 sprintf(bp, LN_DECSLRM"\033[%d;%ds", lm, W_PAGE2550 - lm); bp += strlen(bp);
1173 } else {
1174 lm = (left > 0)? left : (((H_MAX3150 - scale * iw) / 2) + H_MARGIN37);
1175 tm = (top > 0)? top : (((W_MAX2400 - scale * ih * 6) / 2) + W_MARGIN75);
1176 sprintf(bp, LN_PFS"\033[%s J", "?21"); bp += 7;
1177 sprintf(bp, LN_DECOPM_SET"\033[?52h"); bp += sizeof LN_DECOPM_SET"\033[?52h" - 1;
1178 sprintf(bp, LN_DECSLRM"\033[%d;%ds", lm, H_PAGE3225 - lm); bp += strlen(bp);
1179 }
1180
1181 if (header != NULL((void*)0)) {
1182 sprintf(bp, LN_VPA"\033[%dd", tm - 100); bp += strlen(bp);
1183 i = strlen(header);
1184 xm = (((scale * iw) - (i * 30)) / 2) + lm;
1185 sprintf(bp, LN_HPA"\033[%d`", xm); bp += strlen(bp);
1186 sprintf(bp, LN_SGR"\033[1%dm", 3); bp += strlen(bp);
1187 memmove(bp, header, i);
1188 bp += i;
1189 }
1190 if (trailer != NULL((void*)0)) {
1191 sprintf(bp, LN_VPA"\033[%dd", tm + (scale * ih * 6) + 75); bp += strlen(bp);
1192 i = strlen(trailer);
1193 xm = (((scale * iw) - (i * 30)) / 2) + lm;
1194 sprintf(bp, LN_HPA"\033[%d`", xm); bp += strlen(bp);
1195 sprintf(bp, LN_SGR"\033[1%dm", 3); bp += strlen(bp);
1196 memmove(bp, trailer, i);
1197 bp += i;
1198 }
1199
1200 sprintf(bp, LN_HPA"\033[%d`", lm); bp += strlen(bp);
1201 sprintf(bp, LN_VPA"\033[%dd", tm); bp += strlen(bp);
1202 sprintf(bp, LN_SIXEL_GRAPHICS"\033P%d;%d;%dq", 9, 0, scale); bp += strlen(bp);
1203 sprintf(bp, "\"1;1"); bp += 4; /* Pixel aspect ratio */
1204 write(1, buf, bp-buf);
1205 *top_margin = tm;
1206 *left_margin = lm;
1207}
1208
1209static
1210void ln03_finish(void)
1211{
1212 char buf[256];
1213 register char *bp = buf;
1214
1215 sprintf(bp, LN_DECOPM_RESET"\033[?52I"); bp += sizeof LN_DECOPM_SET"\033[?52h" - 1;
1216 sprintf(bp, LN_LNM"\033[20h"); bp += 5;
1217 sprintf(bp, LN_PUM"\033[11I"); bp += 5;
1218 sprintf(bp, LN_PFS"\033[%s J", "?20"); bp += 7;
1219 sprintf(bp, LN_SGR"\033[1%dm", 0); bp += strlen(bp);
1220 sprintf(bp, LN_HPA"\033[%d`", 1); bp += strlen(bp);
1221 sprintf(bp, LN_VPA"\033[%dd", 1); bp += strlen(bp);
1222
1223
1224 write(1, buf, bp-buf);
1225}
1226
1227/*ARGSUSED*/
1228static
1229void la100_setup(int iw, int ih, int scale)
1230{
1231 char buf[256];
1232 register char *bp;
1233 int lm, tm;
1234
1235 bp = buf;
1236 lm = ((80 - (int)((double)iw / 6.6)) / 2) - 1;
1237 if (lm < 1) lm = 1;
1238 tm = ((66 - (int)((double)ih / 2)) / 2) - 1;
1239 if (tm < 1) tm = 1;
1240 sprintf(bp, "\033[%d;%ds", lm, 81-lm); bp += strlen(bp);
1241 sprintf(bp, "\033[?7l"); bp += 5;
1242 sprintf(bp, "\033[%dd", tm); bp += strlen(bp);
1243 sprintf(bp, "\033[%d`", lm); bp += strlen(bp);
1244 sprintf(bp, "\033P0q"); bp += 4;
1245 write(1, buf, bp-buf);
1246}
1247
1248#define LA100_RESET"\033[1;80s\033[?7h" "\033[1;80s\033[?7h"
1249
1250static
1251void la100_finish(void)
1252{
1253 write(1, LA100_RESET"\033[1;80s\033[?7h", sizeof LA100_RESET"\033[1;80s\033[?7h" - 1);
1254}
1255
1256#define COMMENTVERSION"PS-Adobe-1.0" "PS-Adobe-1.0"
1257
1258#ifdef XPROLOG
1259/* for debugging, get the prolog from a file */
1260static
1261void dump_prolog(int flags)
1262{
1263 char *fname=(flags & F_COMPACT128) ? "prolog.compact" : "prolog";
1264 FILE *fi = fopen(fname,"r");
1265 char buf[1024];
1266
1267 if (fi==NULL((void*)0)) {
1268 perror(fname);
1269 exit(1);
1270 }
1271 while (fgets(buf,1024,fi)) fputs(buf,stdoutstdout);
1272 fclose(fi);
1273}
1274
1275#else /* XPROLOG */
1276/* postscript "programs" to unpack and print the bitmaps being sent */
1277
1278static const
1279char *ps_prolog_compact[] = {
1280 "%%Pages: 1",
1281 "%%EndProlog",
1282 "%%Page: 1 1",
1283 "",
1284 "/bitgen",
1285 " {",
1286 " /nextpos 0 def",
1287 " currentfile bufspace readhexstring pop % get a chunk of input",
1288 " % interpret each byte of the input",
1289 " {",
1290 " flag { % if the previous byte was FF",
1291 " /len exch def % this byte is a count",
1292 " result",
1293 " nextpos",
1294 " FFstring 0 len getinterval % grap a chunk of FF's",
1295 " putinterval % and stuff them into the result",
1296 " /nextpos nextpos len add def",
1297 " /flag false def",
1298 " }{ % otherwise",
1299 " dup 255 eq { % if this byte is FF",
1300 " /flag true def % just set the flag",
1301 " pop % and toss the FF",
1302 " }{ % otherwise",
1303 " % move this byte to the result",
1304 " result nextpos",
1305 " 3 -1 roll % roll the current byte back to the top",
1306 " put",
1307 " /nextpos nextpos 1 add def",
1308 " } ifelse",
1309 " } ifelse",
1310 " } forall",
1311 " % trim unused space from end of result",
1312 " result 0 nextpos getinterval",
1313 " } def",
1314 "",
1315 "",
1316 "/bitdump % stk: width, height, iscale",
1317 " % dump a bit image with lower left corner at current origin,",
1318 " % scaling by iscale (iscale=1 means 1/300 inch per pixel)",
1319 " {",
1320 " % read arguments",
1321 " /iscale exch def",
1322 " /height exch def",
1323 " /width exch def",
1324 "",
1325 " % scale appropriately",
1326 " width iscale mul height iscale mul scale",
1327 "",
1328 " % data structures:",
1329 "",
1330 " % allocate space for one line of input",
1331 " /bufspace 36 string def",
1332 "",
1333 " % string of FF's",
1334 " /FFstring 256 string def",
1335 " % for all i FFstring[i]=255",
1336 " 0 1 255 { FFstring exch 255 put } for",
1337 "",
1338 " % 'escape' flag",
1339 " /flag false def",
1340 "",
1341 " % space for a chunk of generated bits",
1342 " /result 4590 string def",
1343 "",
1344 " % read and dump the image",
1345 " width height 1 [width 0 0 height neg 0 height]",
1346 " { bitgen }",
1347 " image",
1348 " } def",
1349 NULL((void*)0)
1350};
1351
1352static const
1353char *ps_prolog[] = {
1354 "%%Pages: 1",
1355 "%%EndProlog",
1356 "%%Page: 1 1",
1357 "",
1358 "/bitdump % stk: width, height, iscale",
1359 "% dump a bit image with lower left corner at current origin,",
1360 "% scaling by iscale (iscale=1 means 1/300 inch per pixel)",
1361 "{",
1362 " % read arguments",
1363 " /iscale exch def",
1364 " /height exch def",
1365 " /width exch def",
1366 "",
1367 " % scale appropriately",
1368 " width iscale mul height iscale mul scale",
1369 "",
1370 " % allocate space for one scanline of input",
1371 " /picstr % picstr holds one scan line",
1372 " width 7 add 8 idiv % width of image in bytes = ceiling(width/8)",
1373 " string",
1374 " def",
1375 "",
1376 " % read and dump the image",
1377 " width height 1 [width 0 0 height neg 0 height]",
1378 " { currentfile picstr readhexstring pop }",
1379 " image",
1380 "} def",
1381 NULL((void*)0)
1382};
1383
1384static
1385void dump_prolog(int flags) {
1386 const char **p = (flags & F_COMPACT128) ? ps_prolog_compact : ps_prolog;
1387 while (*p)
1388 printf("%s\n", *p++);
1389}
1390#endif /* XPROLOG */
1391
1392#define PAPER_WIDTH85*30 85*30 /* 8.5 inches */
1393#define PAPER_LENGTH11*300 11*300 /* 11 inches */
1394
1395static
1396int points(int n)
1397{
1398 /* scale n from pixels (1/300 inch) to points (1/72 inch) */
1399 n *= 72;
1400 return n/300;
1401}
1402
1403static
1404char *escape(const char *s)
1405{
1406 /* make a version of s in which control characters are deleted and
1407 * special characters are escaped.
1408 */
1409 static char buf[200];
1410 char *p = buf;
1411
1412 for (;*s;s++) {
1413 if (*s < ' ' || *s > 0176) continue;
1414 if (*s==')' || *s=='(' || *s == '\\') {
1415 sprintf(p,"\\%03o",*s);
1416 p += 4;
1417 }
1418 else *p++ = *s;
1419 }
1420 *p = 0;
1421 return buf;
1422}
1423
1424static
1425void ps_setup(
1426 int iw,
1427 int ih,
1428 enum orientation orientation,
1429 int scale,
1430 int left,
1431 int top,
1432 int flags,
1433 const char *header,
1434 const char *trailer,
1435 const char *name)
1436{
1437 char hostname[256];
1438#ifdef WIN32
1439 char *username;
1440#else
1441 struct passwd *pswd;
1442#endif
1443 long clock;
1444 int lm, bm; /* left (bottom) margin */
1445
1446 /* calculate margins */
1447 if (orientation==PORTRAIT) {
1448 lm = (left > 0)? left : ((PAPER_WIDTH85*30 - scale * iw) / 2);
1449 bm = (top > 0)? (PAPER_LENGTH11*300 - top - scale * ih)
1450 : ((PAPER_LENGTH11*300 - scale * ih) / 2);
1451 } else { /* orientation == LANDSCAPE */
1452 lm = (top > 0)? (PAPER_WIDTH85*30 - top - scale * ih)
1453 : ((PAPER_WIDTH85*30 - scale * ih) / 2);
1454 bm = (left > 0)? (PAPER_LENGTH11*300 - left - scale * iw)
1455 : ((PAPER_LENGTH11*300 - scale * iw) / 2);
1456 }
1457 printf ("%%!%s\n", COMMENTVERSION"PS-Adobe-1.0");
1458 printf ("%%%%BoundingBox: %d %d %d %d\n",
1459 (flags & F_NPOSITION1024) ? points(lm) : 0,
1460 (flags & F_NPOSITION1024) ? points(bm) : 0,
1461 points(iw * scale), points(ih * scale));
1462 (void) XmuGetHostname (hostname, sizeof hostname);
1463#ifdef WIN32
1464 username = getenv("USERNAME");
1465 printf ("%%%%Creator: %s:%s\n", hostname,
1466 username ? username : "unknown");
1467#else
1468 pswd = getpwuid (getuid ());
1469 printf ("%%%%Creator: %s:%s (%s)\n", hostname,
1470 pswd->pw_name, pswd->pw_gecos);
1471#endif
1472 printf ("%%%%Title: %s (%s)\n", infilename,name);
1473 printf ("%%%%CreationDate: %s",
1474 (time (&clock), ctime (&clock)));
1475 printf ("%%%%EndComments\n");
1476
1477 dump_prolog(flags);
1478
1479 if (orientation==PORTRAIT) {
1480 if (header || trailer) {
1481 printf("gsave\n");
1482 printf("/Times-Roman findfont 15 scalefont setfont\n");
1483 /* origin at bottom left corner of image */
1484 printf("%d %d translate\n",points(lm),points(bm));
1485 if (header) {
1486 char *label = escape(header);
1487 printf("%d (%s) stringwidth pop sub 2 div %d moveto\n",
1488 points(iw*scale), label, points(ih*scale) + 10);
1489 printf("(%s) show\n",label);
1490 }
1491 if (trailer) {
1492 char *label = escape(trailer);
1493 printf("%d (%s) stringwidth pop sub 2 div -20 moveto\n",
1494 points(iw*scale), label);
1495 printf("(%s) show\n",label);
1496 }
1497 printf("grestore\n");
1498 }
1499 /* set resolution to device units (300/inch) */
1500 printf("72 300 div dup scale\n");
1501 /* move to lower left corner of image */
1502 if (!(flags & F_NPOSITION1024))
1503 printf("%d %d translate\n",lm,bm);
1504 /* dump the bitmap */
1505 printf("%d %d %d bitdump\n",iw,ih,scale);
1506 } else { /* orientation == LANDSCAPE */
1507 if (header || trailer) {
1508 printf("gsave\n");
1509 printf("/Times-Roman findfont 15 scalefont setfont\n");
1510 /* origin at top left corner of image */
1511 printf("%d %d translate\n",points(lm),points(bm + scale * iw));
1512 /* rotate to print the titles */
1513 printf("-90 rotate\n");
1514 if (header) {
1515 char *label = escape(header);
1516 printf("%d (%s) stringwidth pop sub 2 div %d moveto\n",
1517 points(iw*scale), label, points(ih*scale) + 10);
1518 printf("(%s) show\n",label);
1519 }
1520 if (trailer) {
1521 char *label = escape(trailer);
1522 printf("%d (%s) stringwidth pop sub 2 div -20 moveto\n",
1523 points(iw*scale), label);
1524 printf("(%s) show\n",label);
1525 }
1526 printf("grestore\n");
1527 }
1528 /* set resolution to device units (300/inch) */
1529 printf("72 300 div dup scale\n");
1530 /* move to lower left corner of image */
1531 if (!(flags & F_NPOSITION1024))
1532 printf("%d %d translate\n",lm,bm);
1533 /* dump the bitmap */
1534 printf("%d %d %d bitdump\n",ih,iw,scale);
1535 }
1536}
1537
1538static const
1539char *ps_epilog[] = {
1540 "",
1541 "showpage",
1542 "%%Trailer",
1543 NULL((void*)0)
1544};
1545
1546static
1547void ps_finish(void)
1548{
1549 char **p = (char **)ps_epilog;
1550
1551 while (*p) printf("%s\n",*p++);
1552}
1553
1554static
1555void ln03_output_sixels(
1556 unsigned char (*sixmap)[],
1557 int iw,
1558 int ih,
1559 int nosixopt,
1560 int split,
1561 int scale,
1562 int top_margin,
1563 int left_margin)
1564{
1565 unsigned char *buf;
1566 register unsigned char *bp;
1567 int i;
1568 int j;
1569 register int k;
1570 register unsigned char *c;
1571 register int lastc;
1572 register int count;
1573 char snum[6];
1574 register char *snp;
1575
1576 bp = (unsigned char *)malloc((unsigned)(iw*ih+512));
1577 buf = bp;
1578 count = 0;
1579 lastc = -1;
1580 c = (unsigned char *)sixmap;
1581 split = ih / split; /* number of lines per page */
1582
1583 iw--; /* optimization */
1584 for (i = 0; i < ih; i++) {
1585 for (j = 0; j <= iw; j++) {
1586 if (!nosixopt) {
1587 if (*c == lastc && j < iw) {
1588 count++;
1589 c++;
1590 continue;
1591 }
1592 if (count >= 3) {
1593 bp--;
1594 count++;
1595 *bp++ = '!';
1596 snp = snum;
1597 while (count > 0) {
1598 k = count / 10;
1599 *snp++ = count - (k * 10) + '0';
1600 count = k;
1601 }
1602 while (--snp >= snum) *bp++ = *snp;
1603 *bp++ = (~lastc & 0x3F) + 0x3F;
1604 } else if (count > 0) {
1605 lastc = (~lastc & 0x3F) + 0x3F;
1606 do {
1607 *bp++ = lastc;
1608 } while (--count > 0);
1609 }
1610 }
1611 lastc = *c++;
1612 *bp++ = (~lastc & 0x3F) + 0x3F;
1613 }
1614 *bp++ = '-'; /* New line */
1615 lastc = -1;
1616 if ((i % split) == 0 && i != 0) {
1617 sprintf((char *)bp, LN_ST"\033\\"); bp += sizeof LN_ST"\033\\" - 1;
1618 *bp++ = '\f';
1619 sprintf((char *)bp, LN_VPA"\033[%dd", top_margin + (i * 6 * scale));
1620 bp += strlen((char *)bp);
1621 sprintf((char *)bp, LN_HPA"\033[%d`", left_margin);
1622 bp += strlen((char *)bp);
1623 sprintf((char *)bp, LN_SIXEL_GRAPHICS"\033P%d;%d;%dq", 9, 0, scale);
1624 bp += strlen((char *)bp);
1625 sprintf((char *)bp, "\"1;1"); bp += 4;
1626 }
1627 }
1628
1629 sprintf((char *)bp, LN_ST"\033\\"); bp += sizeof LN_ST"\033\\" - 1;
1630 write(1, (char *)buf, bp-buf);
1631}
1632
1633/*ARGSUSED*/
1634static
1635void la100_output_sixels(
1636 unsigned char (*sixmap)[],
1637 int iw,
1638 int ih,
1639 int nosixopt)
1640{
1641 unsigned char *buf;
1642 register unsigned char *bp;
1643 int i;
1644 register int j, k;
1645 register unsigned char *c;
1646 register int lastc;
1647 register int count;
1648 char snum[6];
1649
1650 bp = (unsigned char *)malloc((unsigned)(iw*ih+512));
1651 buf = bp;
1652 count = 0;
1653 lastc = -1;
1654 c = (unsigned char *)sixmap;
1655
1656 for (i = 0; i < ih; i++) {
1657 for (j = 0; j < iw; j++) {
1658 if (*c == lastc && (j+1) < iw) {
1659 count++;
1660 c++;
1661 continue;
1662 }
1663 if (count >= 2) {
1664 bp -= 2;
1665 count = 2 * (count + 1);
1666 *bp++ = '!';
1667 k = 0;
1668 while (count > 0) {
1669 snum[k++] = (count % 10) + '0';
1670 count /= 10;
1671 }
1672 while (--k >= 0) *bp++ = snum[k];
1673 *bp++ = (~lastc & 0x3F) + 0x3F;
1674 count = 0;
1675 } else if (count > 0) {
1676 lastc = (~lastc & 0x3F) + 0x3F;
1677 do {
1678 *bp++ = lastc;
1679 *bp++ = lastc;
1680 } while (--count > 0);
1681 }
1682 lastc = (~*c & 0x3F) + 0x3F;
1683 *bp++ = lastc;
1684 *bp++ = lastc;
1685 lastc = *c++;
1686 }
1687 *bp++ = '-'; /* New line */
1688 lastc = -1;
1689 }
1690
1691 sprintf((char *)bp, LN_ST"\033\\"); bp += sizeof LN_ST"\033\\" - 1;
1692 *bp++ = '\f';
1693 write(1, (char *)buf, bp-buf);
1694}
1695
1696#define LINELEN72 72 /* number of CHARS (bytes*2) per line of bitmap output */
1697
1698static
1699void ps_output_bits(
1700 int iw,
1701 int ih,
1702 int flags,
1703 enum orientation orientation,
1704 XWDFileHeader *win,
1705 const char *data)
1706{
1707 unsigned long swaptest = 1;
1708 int iwb = win->bytes_per_line;
1709 register int i;
1710 int bytes;
1711 unsigned char *buffer = (unsigned char *)data;
1712 register int ocount=0;
1713 static char hex[] = "0123456789abcdef";
1714
1715 if (orientation == LANDSCAPE) {
1716 /* read in and rotate the entire image */
1717 /* The Postscript language has a rotate operator, but using it
1718 * seem to make printing (at least on the Apple Laserwriter
1719 * take about 10 times as long (40 minutes for a 1024x864 full-screen
1720 * dump)! Therefore, we rotate the image here.
1721 */
1722 int ocol = ih;
1723 int owidth = (ih+31)/32; /* width of rotated image, in bytes */
1724 int oheight = (iw+31)/32; /* height of rotated image, in scanlines */
1725 register char *p, *q;
1726 char *obuf;
1727 unsigned char *ibuf;
1728 owidth *= 4;
1729 oheight *= 32;
1730
1731 /* Allocate buffer for the entire rotated image (output).
1732 * Owidth and Oheight are rounded up to a multiple of 32 bits,
1733 * to avoid special cases at the boundaries
1734 */
1735 obuf = malloc((unsigned)(owidth*oheight));
1736 if (obuf==NULL((void*)0)) {
1737 fprintf(stderrstderr,"xpr: cannot allocate %d bytes\n",owidth*oheight);
1738 exit(1);
1739 }
1740 bzero(obuf,owidth*oheight)memset(obuf,0,owidth*oheight);
1741
1742 ibuf = (unsigned char *)malloc((unsigned)(iwb + 3));
1743 for (i=0;i<ih;i++) {
1744 memmove((char *)ibuf, (char *)buffer, iwb);
1745 buffer += iwb;
1746 if (!(*(char *) &swaptest))
1747 _swaplong((char *)ibuf,(long)iwb);
1748 ps_bitrot(ibuf,iw,--ocol,owidth,obuf);
1749 }
1750 if (!(*(char *) &swaptest))
1751 _swaplong(obuf,(long)(iw*owidth));
1752 q = &obuf[iw*owidth];
1753 bytes = (ih+7)/8;
1754 for (p=obuf;p<q;p+=owidth)
1755 ocount = ps_putbuf((unsigned char *)p,bytes,ocount,flags&F_COMPACT128);
1756 }
1757 else {
1758 for (i=0;i<ih;i++) {
1759 ocount = ps_putbuf(buffer,(iw+7)/8,ocount,flags&F_COMPACT128);
1760 buffer += iwb;
1761 }
1762 }
1763 if (flags & F_COMPACT128) {
1764 if (ocount) {
1765 /* pad to an integral number of lines */
1766 while (ocount++ < LINELEN72)
1767 /* for debugging, pad with a "random" value */
1768 putchar(hex[ocount&15]);
1769 putchar('\n');
1770 }
1771 }
1772}
1773
1774static const
1775unsigned char _reverse_byte[0x100] = {
1776 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1777 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1778 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1779 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1780 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1781 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1782 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1783 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1784 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1785 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1786 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1787 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1788 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1789 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1790 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1791 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1792 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1793 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1794 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1795 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1796 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1797 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1798 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1799 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1800 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1801 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1802 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1803 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1804 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1805 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1806 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1807 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1808};
1809
1810void _invbits (
1811 register unsigned char *b,
1812 register long n)
1813{
1814 do {
1815 *b = ~*b;
1816 b++;
1817 } while (--n > 0);
1818
1819}
1820
1821/* copied from lib/X/XPutImage.c */
1822
1823void _swapbits (
1824 register unsigned char *b,
1825 register long n)
1826{
1827 do {
1828 *b = _reverse_byte[*b];
1829 b++;
1830 } while (--n > 0);
1831
1832}
1833
1834void _swapshort (
1835 register char *bp,
1836 register long n)
1837{
1838 register char c;
1839 register char *ep = bp + n;
1840 do {
1841 c = *bp;
1842 *bp = *(bp + 1);
1843 bp++;
1844 *bp = c;
1845 bp++;
1846 }
1847 while (bp < ep);
1848}
1849
1850void _swaplong (
1851 register char *bp,
1852 register long n)
1853{
1854 register char c;
1855 register char *ep = bp + n;
1856 register char *sp;
1857 do {
1858 sp = bp + 3;
1859 c = *sp;
1860 *sp = *bp;
1861 *bp++ = c;
1862 sp = bp + 1;
1863 c = *sp;
1864 *sp = *bp;
1865 *bp++ = c;
1866 bp += 2;
1867 }
1868 while (bp < ep);
1869}
1870
1871/* Dump some bytes in hex, with bits in each byte reversed
1872 * Ocount is number of chacters that have been written to the current
1873 * output line. It's new value is returned as the result of the function.
1874 * Ocount is ignored (and the return value is meaningless) if compact==0.
1875 */
1876static
1877int ps_putbuf(
1878 register unsigned char *s, /* buffer to dump */
1879 register int n, /* number of BITS to dump */
1880 register int ocount, /* position on output line for next char */
1881 int compact) /* if non-zero, do compaction (see below) */
1882{
1883 register int ffcount = 0;
1884 static char hex[] = "0123456789abcdef";
1885#define PUT(c){ putchar(c); if (++ocount>=72) { putchar('\n'); ocount=0;
}}
{ putchar(c); if (++ocount>=LINELEN72) \
1886 { putchar('\n'); ocount=0; }}
1887
1888 if (compact) {
1889 /* The following loop puts out the bits of the image in hex,
1890 * compressing runs of white space (represented by one bits)
1891 * according the the following simple algorithm: A run of n
1892 * 'ff' bytes (i.e., bytes with value 255--all ones), where
1893 * 1<=n<=255, is represented by a single 'ff' byte followed by a
1894 * byte containing n.
1895 * On a typical dump of a full screen pretty much covered by
1896 * black-on-white text windows, this compression decreased the
1897 * size of the file from 223 Kbytes to 63 Kbytes.
1898 * Of course, another factor of two could be saved by sending
1899 * the bytes 'as is' rather than in hex, using some sort of
1900 * escape convention to avoid problems with control characters.
1901 * Another popular encoding is to pack three bytes into 4 'sixels'
1902 * as in the LN03, etc, but I'm too lazy to write the necessary
1903 * PostScript code to unpack fancier representations.
1904 */
1905 while (n--) {
1906 if (*s == 0xff) {
1907 if (++ffcount == 255) {
1908 PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
; PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
;
1909 PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
; PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
;
1910 ffcount = 0;
1911 }
1912 }
1913 else {
1914 if (ffcount) {
1915 PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
; PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
;
1916 PUT(hex[ffcount >> 4]){ putchar(hex[ffcount >> 4]); if (++ocount>=72) { putchar
('\n'); ocount=0; }}
;
1917 PUT(hex[ffcount & 0xf]){ putchar(hex[ffcount & 0xf]); if (++ocount>=72) { putchar
('\n'); ocount=0; }}
;
1918 ffcount = 0;
1919 }
1920 PUT(hex1[*s]){ putchar(hex1[*s]); if (++ocount>=72) { putchar('\n'); ocount
=0; }}
;
1921 PUT(hex2[*s]){ putchar(hex2[*s]); if (++ocount>=72) { putchar('\n'); ocount
=0; }}
;
1922 }
1923 s++;
1924 }
1925 if (ffcount) {
1926 PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
; PUT('f'){ putchar('f'); if (++ocount>=72) { putchar('\n'); ocount=
0; }}
;
1927 PUT(hex[ffcount >> 4]){ putchar(hex[ffcount >> 4]); if (++ocount>=72) { putchar
('\n'); ocount=0; }}
;
1928 PUT(hex[ffcount & 0xf]){ putchar(hex[ffcount & 0xf]); if (++ocount>=72) { putchar
('\n'); ocount=0; }}
;
1929 ffcount = 0;
Value stored to 'ffcount' is never read
1930 }
1931 }
1932 else { /* no compaction: just dump the image in hex (bits reversed) */
1933 while (n--) {
1934 putchar(hex1[*s]);
1935 putchar(hex2[*s++]);
1936 }
1937 putchar('\n');
1938 }
1939 return ocount;
1940}
1941
1942static
1943void ps_bitrot(
1944 unsigned char *s,
1945 register int n,
1946 int col,
1947 register int owidth,
1948 char *obuf)
1949/* s points to a chunk of memory and n is its width in bits.
1950 * The algorithm is, roughly,
1951 * for (i=0;i<n;i++) {
1952 * OR the ith bit of s into the ith row of the
1953 * (col)th column of obuf
1954 * }
1955 * Assume VAX bit and byte ordering for s:
1956 * The ith bit of s is s[j]&(1<<k) where i=8*j+k.
1957 * It can also be retrieved as t[j]&(1<<k), where t=(int*)s and i=32*j+k.
1958 * Also assume VAX bit and byte ordering for each row of obuf.
1959 * Ps_putbuf() takes care of converting to Motorola 68000 byte and bit
1960 * ordering. The following code is very carefully tuned to yield a very
1961 * tight loop on the VAX, since it easily dominates the entire running
1962 * time of this program. In particular, iwordp is declared last, since
1963 * there aren't enough registers, and iwordp is referenced only once
1964 * every 32 times through the loop.
1965 */
1966{
1967 register int mask = 1<<(col%32);
1968 register int iword; /* current input word (*iwordp) */
1969 register int b = 0; /* number of bits in iword left to examine */
1970 register char *opos = obuf + (col/32)*4;
1971 /* pointer to word of obuf to receive next output bit */
1972 register int *iwordp = (int *) s; /* pointer to next word of s */
1973
1974 while (--n>=0) {
1975 if (--b < 0) {
1976 iword = *iwordp++;
1977 b = 31;
1978 }
1979 if (iword & 1) {
1980 *(int *)opos |= mask;
1981 }
1982 opos += owidth;
1983 iword >>= 1;
1984 }
1985}
1986
1987/* fullread() is the same as read(), except that it guarantees to
1988 read all the bytes requested. */
1989
1990static
1991void fullread (
1992 int file,
1993 char *data,
1994 int nbytes)
1995{
1996 int bytes_read;
1997 while ((bytes_read = read(file, data, nbytes)) != nbytes) {
1998 if (bytes_read < 0) {
1999 perror ("error while reading standard input");
2000 return;
2001 }
2002 else if (bytes_read == 0) {
2003 fprintf (stderrstderr, "xpr: premature end of file\n");
2004 return;
2005 }
2006 nbytes -= bytes_read;
2007 data += bytes_read;
2008 }
2009}