Bug Summary

File:x2jet.c
Location:line 753, column 21
Description:The left operand of '<<' is a garbage value

Annotated Source Code

1/* $XConsortium: x2jet.c,v 1.6 94/04/17 20:44:03 rws Exp $ */
2
3/* -*-C-*-
4********************************************************************************
5*
6* File: x2jet.c
7* RCS: x2jet.c,v 1.23 89/07/17 12:02:51 lori Exp
8* Description: xpr support for HP LaserJet and PaintJet printers
9* Author: Larry Rupp, HP Graphics Technology Division
10* Created: Fri Jul 15 15:22:26 1988
11* Modified: Thu Sep 15 11:59:34 1988 (Larry Rupp) ler@hpfcler
12* Tue Dec 6 10:04:43 PST 1988 (Marc Ayotte) marca@hp-pcd
13* Language: C
14* Package: N/A
15* Status: Released to MIT
16*
17* (c) Copyright 1988, Hewlett-Packard Company.
18*
19********************************************************************************
20*/
21
22
23
24
25
26/********************************************************
27
28Copyright (c) 1988 by Hewlett-Packard Company
29
30Permission to use, copy, modify, and distribute this software
31and its documentation for any purpose and without fee is hereby
32granted, provided that the above copyright notice appear in all
33copies and that both that copyright notice and this permission
34notice appear in supporting documentation, and that
35Hewlett-Packard not be used in advertising or publicity
36pertaining to distribution of the software without specific, written
37prior permission.
38
39********************************************************/
40/*
41
42Copyright (c) 1988 X Consortium
43
44Permission is hereby granted, free of charge, to any person obtaining
45a copy of this software and associated documentation files (the
46"Software"), to deal in the Software without restriction, including
47without limitation the rights to use, copy, modify, merge, publish,
48distribute, sublicense, and/or sell copies of the Software, and to
49permit persons to whom the Software is furnished to do so, subject to
50the following conditions:
51
52The above copyright notice and this permission notice shall be included
53in all copies or substantial portions of the Software.
54
55THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
56OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
59OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
60ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
61OTHER DEALINGS IN THE SOFTWARE.
62
63Except as contained in this notice, the name of the X Consortium shall
64not be used in advertising or otherwise to promote the sale, use or
65other dealings in this Software without prior written authorization
66from the X Consortium.
67
68*/
69
70
71#include <stdio.h>
72#include <stdarg.h>
73#include <X11/Xlib.h>
74#include <X11/XWDFile.h>
75#include <X11/Xfuncproto.h>
76
77#include "xpr.h"
78
79#ifdef NLS16
80#ifndef NLS
81#define NLS
82#endif
83#endif
84
85#ifndef NLS
86#define catgets(i, sn,mn,s)(s) (s)
87#else /* NLS */
88#define NL_SETN 2 /* set number */
89#include <nl_types.h>
90
91extern nl_catd nlmsg_fd;
92
93#endif /* NLS */
94
95#ifndef TRUE1
96# define FALSE0 0
97# define TRUE1 1
98#endif
99
100/* default printable page area (inches) */
101#define STDWIDTH8.0 8.0
102#define STDHEIGHT10.5 10.5
103
104/* header & trailer character cell size (centipoints) */
105#define CHARWIDTH720 720
106#define CHARHEIGHT1200 1200
107
108#define XWDHEADERSIZE(sizeof(XWDFileHeader)) (sizeof(XWDFileHeader))
109#define XCOLORSIZE(sizeof(XColor)) (sizeof(XColor))
110
111
112typedef struct { long width, height; } Area;
113typedef struct { long x, y; } Location;
114
115
116static Area limit; /* image clip limits (dots) */
117static Area page; /* printable page size (centipoints) */
118
119static Location headerloc; /* centipoint location of header string */
120static Location trailerloc; /* centipoint location of trailer string */
121static Location imageloc; /* centipoint location of image */
122
123static int headerlimit; /* number of chars which will printed for */
124static int trailerlimit; /* the image's header/trailer strings */
125
126static XWDFileHeader xwd_header;
127
128static XColor *xwd_colors;
129
130static char *xwd_image;
131
132static unsigned long Z_pixel_mask;
133
134static int true_scale;
135
136typedef struct {
137 unsigned long Rmask, Gmask, Bmask;
138 int Rshift, Gshift, Bshift;
139} RGBshiftmask;
140
141/* Local prototypes */
142static void set_image_limits ( int scale, int density, enum orientation orient, Area print_area);
143static void set_header_trailer_limits (char *header, char *trailer, long printwidth);
144static void set_print_locations ( int scale, int density, int top, int left, const char *header, const char *trailer, enum orientation orient, int position_on_page);
145static int scale_raster (
146 int density,
147 enum orientation orient,
148 Area print_area);
149static void scale_and_orient_image (
150 int *scale, int *density,
151 int width, int height, int left, int top, /* in 300ths of an inch */
152 const char *header, const char *trailer,
153 enum orientation *orient,
154 int position_on_page,
155 enum device device);
156static void setup_RGBshiftmask (RGBshiftmask *sm, unsigned long rmask, unsigned long gmask, unsigned long bmask);
157static void swap_black_and_white (void);
158static void reset_color_mapping (void);
159static void prepare_color_mapping (
160 int invert, int paintjet,
161 unsigned int cutoff,
162 FILE *out);
163static
164void select_grey (int level, int *r, int *g, int *b);
165static int load_printer_color (
166 long index,
167 int nearmatch,
168 enum device device);
169static int lookup_color_index (long i);
170static void select_printer_color (
171 long index,
172 int *red, int *green, int *blue,
173 long *compositeRGB,
174 enum device device);
175static int color_already_in_printer (long compositeRGB, long *pindex);
176static int program_new_printer_color (
177 int red, int green, int blue,
178 long compositeRGB,
179 long *pindex);
180static long composite_diff (long x, long y);
181static long find_nearest_programmed_color (long compositeRGB);
182static void add_index_to_chain (
183 long cindex,
184 long pindex);
185static int load_printer_color_DT (
186 long index,
187 int nearmatch,
188 enum device device);
189static int load_line_colors (
190 long *line,
191 int length, int nearmatch,
192 enum device device);
193static void download_colors (
194 long *line,
195 int length,
196 enum device device);
197static void validate_visual(void);
198static void read_xwd_data (FILE *in);
199static void write_image_prefix (
200 FILE *out,
201 int scale, int density,
202 const char *header,
203 enum device device,
204 int position_on_page, int initial_formfeed,
205 enum orientation orient,
206 float gamma,
207 int render,
208 int slide);
209static void write_image_suffix (
210 FILE *out,
211 const char *trailer,
212 int position_on_page,
213 int slide, int render,
214 enum device device);
215static unsigned long Z_image_pixel (int x, int y);
216static unsigned long XY_image_pixel (int x, int y);
217static void direct_by_pixel(
218 FILE *out,
219 long *line,
220 int length,
221 enum device device);
222static void index_by_pixel(
223 FILE *out,
224 long *line,
225 int length);
226static void write_raster_line (
227 FILE *out,
228 int scale,
229 enum device device,
230 long *line,
231 int length);
232static void write_portrait_Z_image (
233 FILE *out,
234 int scale,
235 enum device device);
236static void write_landscape_Z_image (
237 FILE *out,
238 int scale,
239 enum device device);
240static void write_portrait_XY_image (
241 FILE *out,
242 int scale,
243 enum device device);
244static void write_landscape_XY_image (
245 FILE *out,
246 int scale,
247 enum device device);
248static void write_Z_image (
249 FILE *out,
250 int scale,
251 enum orientation orient,
252 enum device device);
253static void write_XY_image (
254 FILE *out,
255 int scale,
256 enum orientation orient,
257 enum device device);
258static void write_image (
259 FILE *out,
260 int scale,
261 enum orientation orient,
262 enum device device);
263static void fatal_err (const char *s, ...)
264 _X_NORETURN__attribute((noreturn)) _X_ATTRIBUTE_PRINTF(1,2)__attribute__((__format__(__printf__,1,2)));
265
266
267/* Computes the centipoint width of one printer dot. */
268#define dot_centipoints(s,d)((7200.0 * (s)) / (d)) ((7200.0 * (s)) / (d))
269
270static
271void set_image_limits (
272 int scale, int density,
273 enum orientation orient,
274 Area print_area)
275{
276 Area print_dots;
277 double dotsize;
278
279 /* Set dotsize to the centipoint width of one printer dot. */
280 dotsize = dot_centipoints(scale, density)((7200.0 * (scale)) / (density));
281
282 if (orient == PORTRAIT) {
283 print_dots.width = print_area.width / dotsize;
284 print_dots.height = print_area.height / dotsize;
285 } else {
286 print_dots.height = print_area.width / dotsize;
287 print_dots.width = print_area.height / dotsize;
288 }
289
290 limit.width = (print_dots.width < xwd_header.pixmap_width)
291 ? print_dots.width : xwd_header.pixmap_width;
292 limit.height = (print_dots.height < xwd_header.pixmap_height)
293 ? print_dots.height : xwd_header.pixmap_height;
294
295 if ((limit.width != xwd_header.pixmap_width)
296 || (limit.height != xwd_header.pixmap_height))
297 fprintf(stderrstderr,(catgets(nlmsg_fd,NL_SETN,1, "%s: Warning: %d x %d image clipped to %ld x %ld.\n")("%s: Warning: %d x %d image clipped to %ld x %ld.\n")),
298 progname,
299 xwd_header.pixmap_width, xwd_header.pixmap_height,
300 limit.width, limit.height);
301}
302
303
304static
305void set_header_trailer_limits (char *header, char *trailer, long printwidth)
306{
307 /* Determine the number of header and trailer characters
308 * that will fit into the available printing area.
309 */
310 headerlimit = header ? (((strlen(header) * CHARWIDTH720) <= printwidth)
311 ? strlen(header) : (printwidth / CHARWIDTH720))
312 : 0;
313 if (header && headerlimit != strlen(header)) {
314 fprintf(stderrstderr,(catgets(nlmsg_fd,NL_SETN,2,("%s: Warning: Header string clipped to %d characters.\n")
315 "%s: Warning: Header string clipped to %d characters.\n")("%s: Warning: Header string clipped to %d characters.\n")),
316 progname, headerlimit);
317 header[headerlimit] = '\0';
318 }
319
320 trailerlimit = trailer ? (((strlen(trailer) * CHARWIDTH720) <= printwidth)
321 ? strlen(trailer) : (printwidth / CHARWIDTH720))
322 : 0;
323 if (trailer && trailerlimit != strlen(trailer)) {
324 fprintf(stderrstderr,(catgets(nlmsg_fd,NL_SETN,3,("%s: Warning: Trailer string clipped to %d characters.\n")
325 "%s: Warning: Trailer string clipped to %d characters.\n")("%s: Warning: Trailer string clipped to %d characters.\n")),
326 progname, trailerlimit);
327 trailer[headerlimit] = '\0';
328 }
329}
330
331
332static
333void set_print_locations (
334 int scale, int density,
335 int top, int left,
336 const char *header, const char *trailer,
337 enum orientation orient,
338 int position_on_page)
339{
340 Area image;
341 double dotsize;
342
343 /* Set dotsize to the centipoint width of one printer dot. */
344 dotsize = dot_centipoints(scale, density)((7200.0 * (scale)) / (density));
345
346 /* Compute the centipoint size of the clipped image area. */
347 if (orient == PORTRAIT) {
348 image.width = limit.width * dotsize;
349 image.height = limit.height * dotsize;
350 } else {
351 image.height = limit.width * dotsize;
352 image.width = limit.height * dotsize;
353 }
354
355 if (position_on_page) {
356 /* set vertical positions */
357 imageloc.y = (top >= 0)
358 ? top * 24 + ((header) ? CHARHEIGHT1200 : 0)
359 : ((page.height - ((header) ? CHARHEIGHT1200 : 0)
360 - image.height - ((trailer) ? CHARHEIGHT1200 : 0)) / 2)
361 + ((header) ? CHARHEIGHT1200 : 0);
362 headerloc.y = imageloc.y - CHARHEIGHT1200 / 4;
363 trailerloc.y = imageloc.y + image.height + (3 * CHARHEIGHT1200) / 4;
364
365 /* set horizontal positions */
366 if (left >= 0)
367 headerloc.x = imageloc.x = trailerloc.x = left * 24;
368 else {
369 headerloc.x = (page.width - headerlimit * CHARWIDTH720) / 2;
370 imageloc.x = (page.width - image.width) / 2;
371 trailerloc.x = (page.width - trailerlimit * CHARWIDTH720) / 2;
372 }
373 }
374}
375
376
377static
378int scale_raster (
379 int density,
380 enum orientation orient,
381 Area print_area)
382{
383 Area image;
384 int h_scale, v_scale;
385
386 /* Set the image dimensions to the number of centipoints that would be
387 * required for printing at the selected density.
388 */
389 if (orient == PORTRAIT) {
390 image.width = xwd_header.pixmap_width * 7200 / density;
391 image.height = xwd_header.pixmap_height * 7200 / density;
392 } else {
393 image.height = xwd_header.pixmap_width * 7200 / density;
394 image.width = xwd_header.pixmap_height * 7200 / density;
395 }
396
397 /* Calculate the maximum image multiplier along
398 * the horizontal and vertical dimensions.
399 */
400 h_scale = print_area.width / image.width;
401 v_scale = print_area.height / image.height;
402
403 /* If the image can be expanded, return the lesser of the horizontal and
404 * vertical multipliers. Otherwise, the image will not completely fit
405 * the available print area, so just return 1 as the expansion factor.
406 */
407 return (((h_scale > 0) && (v_scale > 0))
408 ? ((h_scale<v_scale) ? h_scale : v_scale)
409 : 1);
410}
411
412
413static
414void scale_and_orient_image (
415 int *scale, int *density,
416 int width, int height, int left, int top, /* in 300ths of an inch */
417 const char *header, const char *trailer,
418 enum orientation *orient,
419 int position_on_page,
420 enum device device)
421{
422 Area usable;
423
424 /* Determine printable area expressed in centipoints. There are 7200
425 * centipoints to the inch. The width and height parameters passed in
426 * are expressed in 300ths of an inch, therefore a 24x conversion factor
427 * is used on the parameter values. The default page dimensions STDWIDTH
428 * and STDHEIGHT are expressed in inches so must be multiplied by 7200
429 * to convert to centipoints.
430 */
431 page.width = (width >= 0) ? width * 24 : STDWIDTH8.0 * 7200;
432 page.height = (height >= 0) ? height * 24 : STDHEIGHT10.5 * 7200;
433
434 /* Paintjet Xl has a mechanical form feed, not a strip feed. It has
435 * a slop of about 1/4 to 1/2 of an inch at the top and bottom.
436 * deduct it from the page height.
437 */
438 if (device == PJETXL)
439 page.height = page.height - 7200;
440
441 /* Determine the area usable for the image. This area will be smaller
442 * than the total printable area if margins or header/trailer strings
443 * have been specified. Margins, like width and height discussed above,
444 * are expressed in 300ths of an inch and must be converted to centipoints.
445 * Header and trailer strings each reduce the available image height
446 * by 1/6 inch, or 1200 centipoints (aka CHARHEIGHT).
447 */
448 usable.width = page.width - ((left > 0) ? (left * 24) : 0);
449 usable.height = page.height - ((top > 0) ? (top * 24) : 0)
450 - ((header) ? CHARHEIGHT1200 : 0)
451 - ((trailer) ? CHARHEIGHT1200 : 0);
452
453 /* Quit here if there is no usable image space. */
454 if ((usable.width <= 0) || (usable.height <= 0)) {
455 fatal_err((catgets(nlmsg_fd,NL_SETN,4,("No space available on page for image.")
456 "No space available on page for image.")("No space available on page for image.")));
457 }
458
459 /* Determine image orientation. The orientation will only be changed if
460 * it was not specified by a command line option. Portrait mode will be
461 * used if either the usable printing area or the image area are square.
462 * Portrait mode will also be used if the long dimensions of the usable
463 * printing area and the image area match, otherwise landscape mode is
464 * used. Portrait mode really means "don't rotate" and landscape mode
465 * means "rotate".
466 */
467 if (*orient == UNSPECIFIED) {
468 if ((usable.width == usable.height)
469 || (xwd_header.pixmap_width == xwd_header.pixmap_height))
470 *orient = PORTRAIT;
471 else
472 *orient = ((usable.width < usable.height)
473 == (xwd_header.pixmap_width < xwd_header.pixmap_height))
474 ? PORTRAIT : LANDSCAPE;
475 }
476
477 /* Set the dots-per-inch print density if it was not specified */
478 if (*density <= 0) {
479 switch(device) {
480 case LJET: *density = 300;
481 break;
482 case PJET: *density = 90;
483 break;
484 case PJETXL:
485 default: *density = 180;
486 break;
487 }
488 }
489
490 /* Fit image to available area if scale was not specified */
491 if (*scale <= 0)
492 *scale = scale_raster(*density, *orient, usable);
493
494 /* Determine image clipping limits */
495 set_image_limits(*scale, *density, *orient, usable);
496
497 /* Determine header/trailer string length clipping */
498 set_header_trailer_limits((char *)header, (char *)trailer, usable.width);
499
500 /* Calculate locations for page layout */
501 set_print_locations(*scale, *density, top, left,
502 header, trailer, *orient, position_on_page);
503
504}
505
506
507static unsigned short fullintensity;
508
509#define BLACK1 1
510#define WHITE0 0
511#define EMPTY-1 -1
512#define MAX_PJ_COLOR16 16
513
514#define RGBmatch(r,g,b,i)(r == i) && (g == i) && (b == i) (r == i) && (g == i) && (b == i)
515
516
517/* Colormap array is used to map from the Xcolor array (xwd_colors) index
518 * numbers into a pjcolor index number. This style of mapping is done when
519 * interpreting non-Direct/TrueColor visual types.
520 */
521static long *colormap;
522
523
524/* Pjcolor array is used to hold the scaled RGB triple values
525 * programmed into the printer.
526 */
527static long pjcolor[MAX_PJ_COLOR16];
528
529
530static int color_warning_given = FALSE0;
531
532
533/* Global visual type indicator, used to select color interpretation method. */
534static char Direct_or_TrueColor;
535
536
537/* Color index element definition, these are linked into a circular list
538 * for interpretation of DirectColor or TrueColor visual types.
539 */
540typedef struct colorindex {
541 long index;
542 long pjcolor_index;
543 struct colorindex *next;
544} COLORINDEX;
545
546
547/* Global data for color interpretation. This structure serves as a home
548 * for the color index lists (only used when processing DirectColor or
549 * TrueColor visual types). It also holds color processing switches and a
550 * pointer to the output file to reduce parameter passing overhead.
551 */
552static struct {
553 int PaintJet;
554 int Invert;
555 unsigned int CutOff;
556 FILE *OutFile;
557 COLORINDEX *indexchain, *freechain;
558 RGBshiftmask sm;
559} color;
560
561
562static
563void setup_RGBshiftmask (
564 RGBshiftmask *sm,
565 unsigned long rmask, unsigned long gmask, unsigned long bmask)
566{
567 sm->Rmask = rmask; sm->Gmask = gmask; sm->Bmask = bmask;
568 sm->Rshift = 0; sm->Gshift = 0; sm->Bshift = 0;
569
570 if (!rmask)
571 fatal_err((catgets(nlmsg_fd,NL_SETN,5, "red mask for visual is zero.")("red mask for visual is zero.")));
572 if (!gmask)
573 fatal_err((catgets(nlmsg_fd,NL_SETN,6, "green mask for visual is zero.")("green mask for visual is zero.")));
574 if (!bmask)
575 fatal_err((catgets(nlmsg_fd,NL_SETN,7, "blue mask for visual is zero.")("blue mask for visual is zero.")));
576
577 for (; !(rmask & 1); sm->Rshift++)
578 rmask >>= 1;
579 for (; !(gmask & 1); sm->Gshift++)
580 gmask >>= 1;
581 for (; !(bmask & 1); sm->Bshift++)
582 bmask >>= 1;
583}
584
585
586static
587void swap_black_and_white (void)
588{
589 /* Reverse black and white in the Xcolor structure array. */
590
591 XColor *color;
592 int n;
593
594 for (n=xwd_header.ncolors, color=xwd_colors; n>0; n--, color++)
595 if (RGBmatch((color->red & fullintensity), (color->green & fullintensity),((color->red & fullintensity) == fullintensity) &&
((color->green & fullintensity) == fullintensity) &&
((color->blue & fullintensity) == fullintensity)
596 (color->blue & fullintensity), fullintensity)((color->red & fullintensity) == fullintensity) &&
((color->green & fullintensity) == fullintensity) &&
((color->blue & fullintensity) == fullintensity)
)
597 color->red = color->green = color->blue = 0;
598 else if (RGBmatch(color->red, color->green, color->blue, 0)(color->red == 0) && (color->green == 0) &&
(color->blue == 0)
)
599 color->red = color->green = color->blue = fullintensity;
600}
601
602
603static
604void reset_color_mapping (void)
605{
606 int n;
607 long *cmap;
608 COLORINDEX *splice;
609
610 for (n=0; n<MAX_PJ_COLOR16; n++)
611 pjcolor[n] = EMPTY-1;
612
613 if (!color.PaintJet) {
614 /* preload for monochrome output */
615 pjcolor[0] = WHITE0;
616 pjcolor[1] = BLACK1;
617 }
618
619 if (Direct_or_TrueColor) {
620 /* move color index chain cells onto the free list */
621 if (color.indexchain != NULL((void*)0)) {
622 splice = color.indexchain->next;
623 color.indexchain->next = color.freechain;
624 color.freechain = splice;
625 color.indexchain = NULL((void*)0);
626 }
627 } else if (color.PaintJet)
628 for (n=xwd_header.ncolors, cmap=colormap; n>0; n--, cmap++)
629 *cmap = EMPTY-1;
630}
631
632
633#define Intensity(r,g,b)((r) * 0.30 + (g) * 0.59 + (b) * 0.11) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
634
635static
636void prepare_color_mapping (
637 int invert, int paintjet,
638 unsigned int cutoff,
639 FILE *out)
640{
641 int n;
642 long *cmap;
643 XColor *xcolor;
644
645 for (n = xwd_header.bits_per_rgb, fullintensity = 0; n > 0; n--)
646 fullintensity = (fullintensity << 1) | 1;
647 for (n = sizeof(short) * 8 - xwd_header.bits_per_rgb; n > 0; n--)
648 fullintensity = (fullintensity << 1);
649
650 Direct_or_TrueColor = (xwd_header.visual_class == DirectColor5
651 || xwd_header.visual_class == TrueColor4);
652 color.PaintJet = paintjet;
653 color.Invert = invert;
654 color.CutOff = cutoff;
655 color.OutFile = out;
656 color.indexchain = NULL((void*)0);
657 color.freechain = NULL((void*)0);
658
659 if (Direct_or_TrueColor)
660 setup_RGBshiftmask(&color.sm, xwd_header.red_mask,
661 xwd_header.green_mask, xwd_header.blue_mask);
662 else {
663 if (!(colormap = (long *) malloc(xwd_header.ncolors * sizeof(long))))
664 fatal_err((catgets(nlmsg_fd,NL_SETN,24,("Could not allocate memory for X-to-printer colormap.")
665 "Could not allocate memory for X-to-printer colormap.")("Could not allocate memory for X-to-printer colormap.")));
666
667 /* For PaintJet, color map assignment will be done one line at a time.
668 * So for now just interchange the Xcolor structure's black and white
669 * if the -rv command line option was specified.
670 */
671 if (paintjet && invert)
672 swap_black_and_white();
673
674 /* For LaserJet, map each color to black or white based upon the
675 * combined intensity of the RGB components. Note that the normal
676 * non-reversed (-rv) LaserJet mapping will represent light areas
677 * of the screen as black on the paper.
678 */
679 if (!paintjet)
680 for (n=xwd_header.ncolors, xcolor=xwd_colors, cmap=colormap; n>0;
681 n--, xcolor++, cmap++)
682 *cmap = (Intensity(xcolor->red, xcolor->green, xcolor->blue)((xcolor->red) * 0.30 + (xcolor->green) * 0.59 + (xcolor
->blue) * 0.11)
< cutoff)
683 ? (invert ? BLACK1 : WHITE0)
684 : (invert ? WHITE0 : BLACK1);
685 }
686 reset_color_mapping();
687}
688
689
690/* On a PaintJet printer, the programmable color intensity ranges are:
691 *
692 * red: 4..90 green: 4..88 blue: 6..85
693 *
694 * The following macros map the 0..65535 intensity ranges of X colors
695 * into the PaintJet's ranges.
696 */
697
698#define fixred(x)(x / 762 + 4) (x / 762 + 4)
699#define fixgreen(x)(x / 780 + 4) (x / 780 + 4)
700#define fixblue(x)(x / 829 + 6) (x / 829 + 6)
701
702#define is_grey(r,g,b)((r == g) && (r == b)) ((r == g) && (r == b))
703
704
705static
706void select_grey (int level, int *r, int *g, int *b)
707{
708 /* Forced selection of a grey. This is done since the PaintJet does
709 * not do very well when picking greys, they tend to become pink!
710 */
711 if (level > 66) { /* white */
712 *r = 90; *g = 88; *b = 85;
713 } else if (level > 35) {
714 *r = 43; *g = 43; *b = 45;
715 } else if (level > 21) {
716 *r = 25; *g = 25; *b = 33;
717 } else if (level > 15) {
718 *r = 15; *g = 16; *b = 18;
719 } else if (level > 11) {
720 *r = 14; *g = 14; *b = 18;
721 } else if (level > 6) {
722 *r = 6; *g = 7; *b = 8;
723 } else { /* black */
724 *r = 4; *g = 4; *b = 6;
725 }
726}
727
728
729static
730int load_printer_color (
731 long index,
732 int nearmatch,
733 enum device device) /* for non Direct/TrueColor */
734{
735 int n, red, blue, green, xred, xgreen, xblue;
1
Variable 'red' declared without an initial value
736 long compositeRGB;
737
738 if (colormap[index] != EMPTY-1)
2
Taking false branch
739 /* printer has already been programmed for this color index */
740 return(1); /* "success" */
741 else {
742 xred = xwd_colors[index].red;
743 xgreen = xwd_colors[index].green;
744 xblue = xwd_colors[index].blue;
745 /* determine the scaled RGB PaintJet color values */
746 if (device == PJET) {
3
Assuming 'device' is not equal to PJET
4
Taking false branch
747 red = fixred(xred)(xred / 762 + 4);
748 green = fixgreen(xgreen)(xgreen / 780 + 4);
749 blue = fixblue(xblue)(xblue / 829 + 6);
750 if (is_grey(xred, xgreen, xblue)((xred == xgreen) && (xred == xblue))) /* assist grey selection */
751 select_grey(red, &red, &green, &blue);
752 }
753 compositeRGB = (red << 16) | (green << 8) | blue;
5
The left operand of '<<' is a garbage value
754 /* search for a matching or unused PaintJet mapping entry */
755 for (n=0; n<MAX_PJ_COLOR16; n++) {
756 if (pjcolor[n] == compositeRGB) {
757 /* record mapping for this index */
758 colormap[index] = n;
759 /* return "success" */
760 return(1);
761 } else if (pjcolor[n] == EMPTY-1) {
762 /* download color to printer */
763 fprintf(color.OutFile,"\033*v%dA", red);
764 fprintf(color.OutFile,"\033*v%dB", green);
765 fprintf(color.OutFile,"\033*v%dC", blue);
766 fprintf(color.OutFile,"\033*v%dI", n);
767 /* record that this is now programmed */
768 pjcolor[n] = compositeRGB;
769 colormap[index] = n;
770 /* return "success" */
771 return(1);
772 }
773 }
774 /* unable to find or program this color */
775 if (nearmatch)
776 colormap[index] = find_nearest_programmed_color(compositeRGB);
777 }
778 return(0); /* "failure" */
779}
780
781
782/* Lookup the image color index on the color.indexchain list. If found
783 * return the corresponding printer color index, otherwise -1. The index
784 * chain is a singly linked circular list. Its head pointer is left at
785 * the last cell matched on the theory that this will allow faster lookup
786 * for runs of color.
787 */
788static
789int lookup_color_index (long i)
790{
791 COLORINDEX *start, *current;
792
793 start = current = color.indexchain;
794
795 if (current == NULL((void*)0))
796 return(-1); /* not found */
797
798 do {
799 if (current->index == i) {
800 color.indexchain = current;
801 return(current->pjcolor_index); /* found */
802 }
803 current = current->next;
804 } while (current != start);
805
806 return(-1); /* not found */
807}
808
809
810/* Calculate the individual and composite printer RGB values. (Only the
811 * composite value is set for monochrome output.)
812 */
813static
814void select_printer_color (
815 long index,
816 int *red, int *green, int *blue,
817 long *compositeRGB,
818 enum device device)
819{
820 int xred, xgreen, xblue;
821
822 xred = xwd_colors[((index & color.sm.Rmask) >> color.sm.Rshift)].red;
823 xgreen = xwd_colors[((index & color.sm.Gmask) >> color.sm.Gshift)].green;
824 xblue = xwd_colors[((index & color.sm.Bmask) >> color.sm.Bshift)].blue;
825
826 if (color.PaintJet) {
827 if (color.Invert) {
828 if (RGBmatch((xred & fullintensity), (xgreen & fullintensity),((xred & fullintensity) == fullintensity) && ((xgreen
& fullintensity) == fullintensity) && ((xblue &
fullintensity) == fullintensity)
829 (xblue & fullintensity), fullintensity)((xred & fullintensity) == fullintensity) && ((xgreen
& fullintensity) == fullintensity) && ((xblue &
fullintensity) == fullintensity)
)
830 xred = xgreen = xblue = 0;
831 else if (RGBmatch(xred, xgreen, xblue, 0)(xred == 0) && (xgreen == 0) && (xblue == 0))
832 xred = xgreen = xblue = fullintensity;
833 }
834 /* determine the scaled RGB PaintJet color values */
835 if (device == PJET) {
836 *red = fixred(xred)(xred / 762 + 4);
837 *green = fixgreen(xgreen)(xgreen / 780 + 4);
838 *blue = fixblue(xblue)(xblue / 829 + 6);
839 if (is_grey(xred, xgreen, xblue)((xred == xgreen) && (xred == xblue))) /* assist grey selection */
840 select_grey(*red, red, green, blue);
841 }
842 if (device == PJETXL) {
843 *red = xred >> 8;
844 *green = xgreen >> 8;
845 *blue = xblue >> 8;
846 }
847 *compositeRGB = (*red << 16) | (*green << 8) | *blue;
848 } else /* monochrome */
849 *compositeRGB = (Intensity(xred, xgreen, xblue)((xred) * 0.30 + (xgreen) * 0.59 + (xblue) * 0.11) < color.CutOff)
850 ? (color.Invert ? BLACK1 : WHITE0)
851 : (color.Invert ? WHITE0 : BLACK1);
852}
853
854
855
856/* Search for a color matching the compositeRGB value in the array of
857 * colors already programmed into the printer. Returns 1 if found,
858 * 0 otherwise. The matching array index is returned in pindex.
859 */
860static
861int color_already_in_printer (long compositeRGB, long *pindex)
862{
863 int n;
864
865 for (n=0; n<MAX_PJ_COLOR16; n++)
866 if (pjcolor[n] == EMPTY-1)
867 return(0); /* not found */
868 else if (pjcolor[n] == compositeRGB) {
869 *pindex = n;
870 return(1); /* found */
871 }
872 return(0); /* not found */
873}
874
875
876static
877int program_new_printer_color (
878 int red, int green, int blue,
879 long compositeRGB,
880 long *pindex)
881{
882 int n;
883
884 for (n=0; n<MAX_PJ_COLOR16; n++)
885 if (pjcolor[n] == EMPTY-1) {
886 /* download color to printer */
887 fprintf(color.OutFile,"\033*v%dA", red);
888 fprintf(color.OutFile,"\033*v%dB", green);
889 fprintf(color.OutFile,"\033*v%dC", blue);
890 fprintf(color.OutFile,"\033*v%dI", n);
891 /* record that this is now programmed */
892 pjcolor[n] = compositeRGB;
893 *pindex = n;
894 /* return "success" */
895 return(1);
896 }
897 /* unable to program this color, return "failure" */
898 return(0);
899}
900
901
902static
903long composite_diff (long x, long y)
904{
905 long r = (x >> 16 & 0xFF) - (y >> 16 & 0xFF);
906 long g = (x >> 8 & 0xFF) - (y >> 8 & 0xFF);
907 long b = (x & 0xFF) - (y & 0xFF);
908
909 return(r*r + g*g + b*b);
910}
911
912
913static
914long find_nearest_programmed_color (long compositeRGB)
915{
916 int n, nearest = 0;
917 long neardiff = composite_diff(pjcolor[0], compositeRGB);
918 long diff;
919
920 for (n=1; n<MAX_PJ_COLOR16; n++) {
921 diff = composite_diff(pjcolor[n], compositeRGB);
922 if (diff < neardiff) {
923 neardiff = diff;
924 nearest = n;
925 }
926 }
927 return(nearest);
928}
929
930
931static
932void add_index_to_chain (
933 long cindex,
934 long pindex)
935{
936 COLORINDEX *new;
937
938 /* Get a new cell for the color index chain. Take it from the free list
939 * if possible, otherwise malloc space.
940 */
941 if (color.freechain == NULL((void*)0)) {
942 if (!(new = (COLORINDEX *) malloc(sizeof(COLORINDEX))))
943 fatal_err((catgets(nlmsg_fd,NL_SETN,8,("Could not allocate memory for color translation.")
944 "Could not allocate memory for color translation.")("Could not allocate memory for color translation.")));
945 } else {
946 new = color.freechain;
947 color.freechain = color.freechain->next;
948 }
949
950 /* put index values in the new cell */
951 new->index = cindex;
952 new->pjcolor_index = pindex;
953
954 /* link the new cell into the chain */
955 if (color.indexchain == NULL((void*)0))
956 new->next = new;
957 else {
958 new->next = color.indexchain->next;
959 color.indexchain->next = new;
960 }
961 /* leave head pointer at the new cell */
962 color.indexchain = new;
963}
964
965
966static
967int load_printer_color_DT (
968 long index,
969 int nearmatch,
970 enum device device) /* for Direct/TrueColor */
971{
972 int pjred, pjgreen, pjblue;
973 long compositeRGB;
974 long pindex;
975
976 if (lookup_color_index(index) >= 0)
977 return(1); /* "success" */
978 else {
979 select_printer_color(index, &pjred, &pjgreen, &pjblue, &compositeRGB,
980 device);
981 if (color_already_in_printer(compositeRGB, &pindex)) {
982 add_index_to_chain(index, pindex);
983 return(1); /* success */
984 } else if (program_new_printer_color(pjred, pjgreen, pjblue,
985 compositeRGB, &pindex)) {
986 add_index_to_chain(index, pindex);
987 return(1); /* success */
988 } else if (nearmatch) {
989 add_index_to_chain(index, find_nearest_programmed_color(compositeRGB));
990 return(0); /* failure, sorta... */
991 }
992 }
993 return(0); /* failure */
994}
995
996
997static
998int load_line_colors (
999 long *line,
1000 int length, int nearmatch,
1001 enum device device)
1002{
1003 int result = 1; /* initialized to "success" */
1004
1005 for (; length>0; length--, line++) {
1006 result &= Direct_or_TrueColor
1007 ? load_printer_color_DT(*line, nearmatch, device)
1008 : load_printer_color(*line, nearmatch, device);
1009 if (!(nearmatch || result))
1010 break;
1011 }
1012 return(result);
1013}
1014
1015
1016static
1017void download_colors (
1018 long *line,
1019 int length,
1020 enum device device)
1021{
1022 /* For the first attempt at loading the colors for a line only exact
1023 * color matches are accepted. If this fails, the closest colors are
1024 * accepted on the second attempt.
1025 *
1026 * Note: The first "if" test below bypasses the initial color loading
1027 * attempt for monochrome output (which will only come here for Direct
1028 * or TrueColor mono). This forces reset_color_mapping which is
1029 * necessary to keep the color index chain down to a tolerable length.
1030 */
1031 if (!color.PaintJet || !load_line_colors(line, length, FALSE0, device)) {
1032 reset_color_mapping();
1033 if (!load_line_colors(line, length, TRUE1, device) &&
1034 !color_warning_given) {
1035 fprintf(stderrstderr,(catgets(nlmsg_fd,NL_SETN,9,("%s: Warning: Cannot print all image colors.\n")
1036 "%s: Warning: Cannot print all image colors.\n")("%s: Warning: Cannot print all image colors.\n")),
1037 progname);
1038 color_warning_given = TRUE1;
1039 }
1040 }
1041}
1042
1043
1044static _X_INLINEinline _X_NORETURN__attribute((noreturn))
1045void invalid_depth_for_visual(int depth, const char *name)
1046{
1047 fatal_err(catgets(nlmsg_fd,NL_SETN,25,("%d bit deep %s bitmap not supported.\n")
1048 "%d bit deep %s bitmap not supported.\n")("%d bit deep %s bitmap not supported.\n"),
1049 depth, name);
1050}
1051
1052static
1053void validate_visual(void)
1054{
1055 int depth = xwd_header.pixmap_depth;
1056
1057 switch (xwd_header.visual_class) {
1058 case GrayScale1:
1059 if (depth > 8) invalid_depth_for_visual(depth, "GrayScale"); break;
1060 case StaticGray0:
1061 if (depth > 8) invalid_depth_for_visual(depth, "StaticGray"); break;
1062 case PseudoColor3:
1063 if (depth > 8) invalid_depth_for_visual(depth, "PseudoColor"); break;
1064 case StaticColor2:
1065 if (depth > 8) invalid_depth_for_visual(depth, "StaticColor"); break;
1066 case DirectColor5:
1067 if (depth != 12 && depth != 24)
1068 invalid_depth_for_visual(depth, "DirectColor");
1069 break;
1070 case TrueColor4:
1071 if (depth != 12 && depth != 24)
1072 invalid_depth_for_visual(depth, "TrueColor");
1073 break;
1074 default:
1075 fatal_err((catgets(nlmsg_fd,NL_SETN,26,("visual class #%d not supported.\n")
1076 "visual class #%d not supported.\n")("visual class #%d not supported.\n")),
1077 (int)xwd_header.visual_class);
1078 }
1079}
1080
1081static
1082void read_xwd_data (FILE *in)
1083{
1084# define WINDOW_NAME_ALLOC32 32
1085 unsigned long swaptest = 1;
1086 int window_name_size;
1087 int image_size;
1088 int n;
1089 char window_name [WINDOW_NAME_ALLOC32];
1090
1091 /* Read in XWDFileHeader structure */
1092 if (fread((char*) &xwd_header, 1, XWDHEADERSIZE(sizeof(XWDFileHeader)), in) != XWDHEADERSIZE(sizeof(XWDFileHeader)))
1093 fatal_err((catgets(nlmsg_fd,NL_SETN,10,("Could not read xwd file's header.")
1094 "Could not read xwd file's header.")("Could not read xwd file's header.")));
1095
1096 if (*(char *) &swaptest)
1097 _swaplong((char *) &xwd_header, XWDHEADERSIZE(sizeof(XWDFileHeader)));
1098
1099 validate_visual();
1100
1101 /* Skip over window name */
1102 window_name_size = xwd_header.header_size - XWDHEADERSIZE(sizeof(XWDFileHeader));
1103 while (window_name_size > 0) {
1104 n = window_name_size > WINDOW_NAME_ALLOC32
1105 ? WINDOW_NAME_ALLOC32 : window_name_size;
1106 if (fread(window_name, 1, n, in) != n)
1107 fatal_err((catgets(nlmsg_fd,NL_SETN,11,("Could not read xwd file's window name.")
1108 "Could not read xwd file's window name.")("Could not read xwd file's window name.")));
1109 window_name_size -= n;
1110 }
1111
1112 /* Allocate space for xwd color structures */
1113 if (!(xwd_colors = (XColor*) malloc(sizeof(XColor) * xwd_header.ncolors)))
1114 fatal_err((catgets(nlmsg_fd,NL_SETN,12,("Could not allocate memory for xwdfile color table.")
1115 "Could not allocate memory for xwdfile color table.")("Could not allocate memory for xwdfile color table.")));
1116
1117 /* Read in xwd color structures */
1118 for (n = 0; n < xwd_header.ncolors; n++)
1119 if (fread(&xwd_colors[n], 1, XCOLORSIZE(sizeof(XColor)), in) != XCOLORSIZE(sizeof(XColor)))
1120 fatal_err((catgets(nlmsg_fd,NL_SETN,13,("Could not read xwd file's color table.")
1121 "Could not read xwd file's color table.")("Could not read xwd file's color table.")));
1122
1123 if (*(char *) &swaptest) {
1124 for (n = 0; n < xwd_header.ncolors; n++) {
1125 _swaplong((char *) &xwd_colors[n].pixel, sizeof(long));
1126 _swapshort((char *) &xwd_colors[n].red, 3 * sizeof(short));
1127 }
1128 }
1129
1130 /* Allocate space for xwd image */
1131 if (xwd_header.pixmap_format == ZPixmap2)
1132 image_size = 1;
1133 else if (xwd_header.pixmap_format == XYPixmap1)
1134 image_size = xwd_header.pixmap_depth;
1135 else
1136 fatal_err((catgets(nlmsg_fd,NL_SETN,14,("Image in xwd file is not in Z or XY pixmap format.")
1137 "Image in xwd file is not in Z or XY pixmap format.")("Image in xwd file is not in Z or XY pixmap format.")));
1138 image_size *= xwd_header.bytes_per_line * xwd_header.pixmap_height;
1139 if (!(xwd_image = malloc(image_size)))
1140 fatal_err((catgets(nlmsg_fd,NL_SETN,15,("Could not allocate memory for xwd file's image.")
1141 "Could not allocate memory for xwd file's image.")("Could not allocate memory for xwd file's image.")));
1142
1143 /* Read in xwd image */
1144 if (fread(xwd_image, 1, image_size, in) != image_size)
1145 fatal_err((catgets(nlmsg_fd,NL_SETN,16,("Could not read xwd file's image.")
1146 "Could not read xwd file's image.")("Could not read xwd file's image.")));
1147
1148}
1149
1150
1151static
1152void write_image_prefix (
1153 FILE *out,
1154 int scale, int density,
1155 const char *header,
1156 enum device device,
1157 int position_on_page, int initial_formfeed,
1158 enum orientation orient,
1159 float gamma,
1160 int render,
1161 int slide)
1162{
1163 if (initial_formfeed)
1164 fprintf(out,"\014");
1165
1166 /* Write out header & positioning commands */
1167 if (header) {
1168 if (position_on_page)
1169 fprintf(out,"\033&a%dH\033&a%dV",
1170 /* headerloc x & y are written in decipoints */
1171 (int) headerloc.x / 10, (int) headerloc.y / 10);
1172 fprintf(out,"%s\n", header);
1173 }
1174
1175 /* Prepare printer for raster graphics: */
1176
1177 /* Write image positioning commands */
1178 if (position_on_page)
1179 fprintf(out,"\033&a%dH\033&a%dV",
1180 /* imageloc x & y are written in decipoints */
1181 (int) imageloc.x / 10, (int) imageloc.y / 10);
1182
1183 /* If doing transparencies, tell the printer before raster graphics */
1184 if (slide && device != LJET)
1185 fprintf(out, "\033&k3W");
1186
1187 /* Set printer resolution */
1188 fprintf(out,"\033*t%dR", density);
1189
1190 /*
1191 * do device dependent escape sequences
1192 */
1193 if (device == PJET) {
1194 /* Enable all four "planes" for PaintJet */
1195 fprintf(out,"\033*r4U");
1196
1197 /* Set picture width for PaintJet */
1198 fprintf(out,"\033*r%dS",
1199 (int) (((orient == PORTRAIT) ? limit.width : limit.height)
1200 * scale));
1201 }
1202
1203 /* Enable various options for PaintJet XL */
1204 if (device == PJETXL) {
1205 double dotsize;
1206 int n;
1207
1208 /* Speed up printing by telling that there
1209 * will be no negative positioning
1210 */
1211 fprintf(out, "\033&a1N");
1212
1213 if (gamma > 0.009)
1214 fprintf(out, "\033*t%.2fI", gamma);
1215
1216 if (render > 0)
1217 fprintf(out, "\033*t%dJ", render);
1218
1219 if (Direct_or_TrueColor)
1220 /* Enable direct by pixel for PaintJet XL */
1221 fwrite("\033*v6W\000\003\010\010\010\010", 1, 11, out);
1222 else {
1223 /* Enable index by pixel for PaintJet XL */
1224 fwrite("\033*v6W\000\001\010\010\010\010", 1, 11, out);
1225
1226 /* Program the palette */
1227 for (n = 0; n < xwd_header.ncolors; n++) {
1228 fprintf(out,"\033*v%dA", (xwd_colors[n].red >> 8));
1229 fprintf(out,"\033*v%dB", (xwd_colors[n].green >> 8));
1230 fprintf(out,"\033*v%dC", (xwd_colors[n].blue >> 8));
1231 fprintf(out,"\033*v%dI", n);
1232 }
1233 }
1234
1235 /****************************************
1236 * *
1237 * PaintJet XL will do its own scaling *
1238 * *
1239 * Set picture width for PaintJet XL *
1240 ****************************************/
1241 fprintf(out,"\033*r%dS",
1242 (int) ((orient == PORTRAIT) ? xwd_header.pixmap_width
1243 : xwd_header.pixmap_height));
1244 fprintf(out,"\033*r%dT",
1245 (int) ((orient == PORTRAIT) ? xwd_header.pixmap_height
1246 : xwd_header.pixmap_width));
1247
1248 dotsize = dot_centipoints(scale, density)((7200.0 * (scale)) / (density));
1249
1250 fprintf(out,"\033*t%dH",
1251 (int)(((orient == PORTRAIT) ? xwd_header.pixmap_width
1252 : xwd_header.pixmap_height)
1253 * dotsize / 10));
1254
1255 fprintf(out,"\033*t%dV",
1256 (int)(((orient == PORTRAIT) ? xwd_header.pixmap_height
1257 : xwd_header.pixmap_width)
1258 * dotsize / 10));
1259 }
1260
1261 /* Switch to raster graphics mode */
1262 if (device != PJETXL)
1263 fprintf(out,"\033*r1A");
1264 else
1265 fprintf(out,"\033*r3A");
1266
1267}
1268
1269
1270static
1271void write_image_suffix (
1272 FILE *out,
1273 const char *trailer,
1274 int position_on_page,
1275 int slide, int render,
1276 enum device device)
1277{
1278 /* Exit raster graphics mode */
1279 if (device == PJETXL)
1280 fprintf(out,"\033*rC");
1281 else
1282 fprintf(out,"\033*rB");
1283
1284 /* If doing transparencies, tell it to stop */
1285 if (slide && device != LJET)
1286 fprintf(out, "\033&k1W");
1287
1288 if (device == PJETXL) {
1289 /* If selected a rendering algorithm, tell it to stop */
1290 if (render)
1291 fprintf(out, "\033*t3J");
1292 fprintf(out, "\033&a0N");
1293 }
1294
1295 /* Write out trailer & positioning commands */
1296 if (trailer) {
1297 if (position_on_page)
1298 fprintf(out,"\033&a%dH\033&a%dV",
1299 /* trailerloc x & y are written in decipoints */
1300 (int) trailerloc.x / 10, (int) trailerloc.y / 10);
1301 fprintf(out,"%s\n", trailer);
1302 }
1303}
1304
1305
1306static
1307unsigned long Z_image_pixel (int x, int y)
1308{
1309 int pixel_bytes, offset;
1310 unsigned char *image;
1311 unsigned long pixel;
1312
1313 pixel_bytes = xwd_header.bits_per_pixel >> 3;
1314 offset = ((xwd_header.bits_per_pixel == 4) ? (x / 2)
1315 : ((xwd_header.bits_per_pixel == 1) ? (x / 8)
1316 : (x * pixel_bytes)))
1317 + (y * xwd_header.bytes_per_line);
1318
1319 image = (unsigned char *) &xwd_image[offset];
1320
1321 switch (pixel_bytes) {
1322 case 0: /* pixel per nibble or bit per pixel packing */
1323 if (xwd_header.bits_per_pixel == 1) {
1324 if (xwd_header.byte_order == MSBFirst1)
1325 pixel = *image >> (7 - (x % 8));
1326 else
1327 pixel = *image >> (x % 8);
1328 } else { /* xwd_header.bits_per_pixel == 4 */
1329 if (xwd_header.byte_order == MSBFirst1)
1330 pixel = (x & 1) ? *image : (*image >> 4);
1331 else
1332 pixel = (x & 1) ? (*image >> 4) : *image;
1333 }
1334 break;
1335 case 1:
1336 pixel = *image;
1337 break;
1338 case 2:
1339 pixel = (xwd_header.byte_order == MSBFirst1)
1340 ? ((unsigned long)*image << 8 | *(image + 1))
1341 : (*image | (unsigned long)*(image + 1) << 8);
1342 break;
1343 case 3:
1344 pixel = (xwd_header.byte_order == MSBFirst1)
1345 ? ((unsigned long)*image << 16 |
1346 (unsigned long)*(image + 1) << 8 |
1347 (unsigned long)*(image + 2))
1348 : (*image |
1349 (unsigned long)*(image + 1) << 8 |
1350 (unsigned long)*(image + 2) << 16);
1351 break;
1352 case 4:
1353 pixel = (xwd_header.byte_order == MSBFirst1)
1354 ? ((unsigned long)*image << 24 |
1355 (unsigned long)*(image+1) << 16 |
1356 (unsigned long)*(image+2) << 8 |
1357 *(image+3))
1358 : (*image |
1359 (unsigned long)*(image+1) << 8 |
1360 (unsigned long)*(image+2) << 16 |
1361 (unsigned long)*(image+3) << 24);
1362 break;
1363 default:
1364 pixel = 0;
1365 break;
1366 }
1367 return (pixel & Z_pixel_mask);
1368}
1369
1370
1371static
1372unsigned long XY_image_pixel (int x, int y)
1373{
1374 int plane_start, line_start, bytes_per_bitmap_unit, bitmap_unit_start,
1375 byte_within_bitmap_unit, offset, byte_mask;
1376
1377 plane_start = (xwd_header.pixmap_depth - 1) * xwd_header.pixmap_height
1378 * xwd_header.bytes_per_line;
1379 line_start = xwd_header.bytes_per_line * y;
1380 bytes_per_bitmap_unit = xwd_header.bitmap_unit >> 3;
1381 bitmap_unit_start = (x / xwd_header.bitmap_unit) * bytes_per_bitmap_unit;
1382 byte_within_bitmap_unit = (xwd_header.byte_order == MSBFirst1)
1383 ? (x % xwd_header.bitmap_unit) >> 3
1384 : bytes_per_bitmap_unit - ((x % xwd_header.bitmap_unit) >> 3) - 1;
1385
1386 offset = plane_start + line_start + bitmap_unit_start
1387 + byte_within_bitmap_unit;
1388
1389 byte_mask = (xwd_header.bitmap_bit_order == MSBFirst1)
1390 ? 0x80 >> (x % 8) : 0x01 << (x % 8);
1391
1392 return(xwd_image[offset] & byte_mask ? 1 : 0);
1393}
1394
1395
1396static
1397void direct_by_pixel(
1398 FILE *out,
1399 long *line,
1400 int length,
1401 enum device device)
1402{
1403 int red, green, blue;
1404 long compositeRGB;
1405
1406 fprintf(out, "\033*b%dW", length * 3);
1407 for (; length>0; length--, line++) {
1408 select_printer_color(*line, &red, &green, &blue, &compositeRGB, device);
1409 fprintf(out, "%c%c%c", (char) red, (char) green, (char) blue);
1410 }
1411}
1412
1413
1414static
1415void index_by_pixel(
1416 FILE *out,
1417 long *line,
1418 int length)
1419{
1420 register int n;
1421 long *lp;
1422 char *line_pixels;
1423 register char *lc;
1424
1425 if (!(line_pixels = malloc(length)))
1426 fatal_err((catgets(nlmsg_fd,NL_SETN,17,("Could not allocate raster line memory.")
1427 "Could not allocate raster line memory.")("Could not allocate raster line memory.")));
1428
1429 for (n=0, lc=line_pixels, lp=line; n<length; n++)
1430 *lc++ = (char) *lp++;
1431
1432 fprintf(out, "\033*b%dW", length);
1433 fwrite(line_pixels, 1, length, out);
1434
1435 free(line_pixels);
1436}
1437
1438
1439static
1440void write_raster_line (
1441 FILE *out,
1442 int scale,
1443 enum device device,
1444 long *line,
1445 int length)
1446{
1447 int planes = (device == PJET) ? 4 : 1;
1448 int raster_bytes = (length * scale + 7) / 8;
1449 register int bytebits, n, p, e, bit;
1450 long *lp;
1451 char *line_colors, *raster_line;
1452 register char *lc, *rl, byte = 0;
1453
1454 if (device == PJETXL) {
1455 if (Direct_or_TrueColor)
1456 direct_by_pixel(out, line, length, device);
1457 else
1458 index_by_pixel(out, line, length);
1459 return;
1460 }
1461
1462 if (!(line_colors = malloc(length))
1463 || !(raster_line = malloc(raster_bytes * planes)))
1464 fatal_err((catgets(nlmsg_fd,NL_SETN,17,("Could not allocate raster line memory.")
1465 "Could not allocate raster line memory.")("Could not allocate raster line memory.")));
1466
1467 if (device == PJET || Direct_or_TrueColor)
1468 download_colors(line, length, device);
1469
1470 /* Map the line's colors into output color index numbers */
1471 if (Direct_or_TrueColor)
1472 for (n=0, lc=line_colors, lp=line; n<length; n++)
1473 *lc++ = (char) lookup_color_index(*lp++);
1474 else
1475 for (n=0, lc=line_colors, lp=line; n<length; n++)
1476 *lc++ = (char) colormap[*lp++];
1477
1478 for (p=0; p<planes; p++) {
1479 bytebits = 0;
1480 n = length;
1481 lc = line_colors;
1482 rl = &raster_line[raster_bytes * p];
1483 while (n-- > 0) {
1484 bit = (*lc++ >> p) & 0x01;
1485 e = scale;
1486 while (e--) {
1487 byte = (byte << 1) | bit;
1488 bytebits++;
1489 if (bytebits == 8) {
1490 *rl++ = byte;
1491 bytebits = 0;
1492 }
1493 }
1494 }
1495 if (bytebits)
1496 *rl = byte << (8 - bytebits);
1497 }
1498
1499 e = scale;
1500 while (e--) {
1501 for (p=0; p<planes; p++) {
1502 fprintf(out,"\033*b%d%c", raster_bytes, (p+1 == planes) ? 'W' : 'V');
1503 fwrite(&raster_line[raster_bytes * p], 1, raster_bytes, out);
1504 }
1505 }
1506
1507 free(line_colors);
1508 free(raster_line);
1509}
1510
1511
1512static
1513void write_portrait_Z_image (
1514 FILE *out,
1515 int scale,
1516 enum device device)
1517{
1518 int x, y;
1519 int width = limit.width;
1520 int height = limit.height;
1521 long *line, *lp;
1522
1523 if (!(line = (long *) malloc(width * sizeof(long))))
1524 fatal_err((catgets(nlmsg_fd,NL_SETN,18,("Could not allocate memory for image line buffer.")
1525 "Could not allocate memory for image line buffer.")("Could not allocate memory for image line buffer.")));
1526
1527 for (y=0; y<height; y++) {
1528
1529 for (x=0, lp=line; x<width; x++)
1530 *lp++ = Z_image_pixel(x,y);
1531
1532 write_raster_line(out, scale, device, line, width);
1533 }
1534}
1535
1536
1537static
1538void write_landscape_Z_image (
1539 FILE *out,
1540 int scale,
1541 enum device device)
1542{
1543 int x, y;
1544 int width = limit.height;
1545 int height = limit.width;
1546 long *line, *lp;
1547
1548 if (!(line = (long *) malloc(width * sizeof(long))))
1549 fatal_err((catgets(nlmsg_fd,NL_SETN,19,("Could not allocate memory for image line buffer.")
1550 "Could not allocate memory for image line buffer.")("Could not allocate memory for image line buffer.")));
1551
1552 for (x=0; x<height; x++) {
1553
1554 for (y=width-1, lp=line; y>=0; y--)
1555 *lp++ = Z_image_pixel(x,y);
1556
1557 write_raster_line(out, scale, device, line, width);
1558 }
1559}
1560
1561
1562static
1563void write_portrait_XY_image (
1564 FILE *out,
1565 int scale,
1566 enum device device)
1567{
1568 int x, y;
1569 int width = limit.width;
1570 int height = limit.height;
1571 long *line, *lp;
1572
1573 if (!(line = (long *) malloc(width * sizeof(long))))
1574 fatal_err((catgets(nlmsg_fd,NL_SETN,20,("Could not allocate memory for image line buffer.")
1575 "Could not allocate memory for image line buffer.")("Could not allocate memory for image line buffer.")));
1576
1577 for (y=0; y<height; y++) {
1578
1579 for (x=0, lp=line; x<width; x++)
1580 *lp++ = XY_image_pixel(x,y);
1581
1582 write_raster_line(out, scale, device, line, width);
1583 }
1584}
1585
1586
1587static
1588void write_landscape_XY_image (
1589 FILE *out,
1590 int scale,
1591 enum device device)
1592{
1593 int x, y;
1594 int width = limit.height;
1595 int height = limit.width;
1596 long *line, *lp;
1597
1598 if (!(line = (long *) malloc(width * sizeof(long))))
1599 fatal_err((catgets(nlmsg_fd,NL_SETN,21,("Could not allocate memory for image line buffer.")
1600 "Could not allocate memory for image line buffer.")("Could not allocate memory for image line buffer.")));
1601
1602 for (x=0; x<height; x++) {
1603
1604 for (y=width-1, lp=line; y>=0; y--)
1605 *lp++ = XY_image_pixel(x,y);
1606
1607 write_raster_line(out, scale, device, line, width);
1608 }
1609}
1610
1611
1612static
1613void write_Z_image (
1614 FILE *out,
1615 int scale,
1616 enum orientation orient,
1617 enum device device)
1618{
1619 if (orient == PORTRAIT) {
1620 write_portrait_Z_image(out, scale, device);
1621 } else
1622 write_landscape_Z_image(out, scale, device);
1623}
1624
1625
1626static
1627void write_XY_image (
1628 FILE *out,
1629 int scale,
1630 enum orientation orient,
1631 enum device device)
1632{
1633 if (xwd_header.pixmap_depth > 1)
1634 fatal_err((catgets(nlmsg_fd,NL_SETN,22,("XY format image, multiplane images must be Z format.")
1635 "XY format image, multiplane images must be Z format.")("XY format image, multiplane images must be Z format.")));
1636
1637 if (orient == PORTRAIT) {
1638 write_portrait_XY_image(out, scale, device);
1639 } else
1640 write_landscape_XY_image(out, scale, device);
1641}
1642
1643
1644static
1645void write_image (
1646 FILE *out,
1647 int scale,
1648 enum orientation orient,
1649 enum device device)
1650{
1651 switch (xwd_header.pixmap_format) {
1652 case XYPixmap1:
1653 write_XY_image(out, scale, orient, device); break;
1654 case ZPixmap2:
1655 write_Z_image(out, scale, orient, device); break;
1656 default:
1657 fatal_err((catgets(nlmsg_fd,NL_SETN,23, "image not in XY or Z format.")("image not in XY or Z format.")));
1658 }
1659}
1660
1661
1662void x2jet(
1663 FILE *in, FILE *out,
1664 int scale, int density,
1665 int width, int height, int left, int top, /* in 300ths of an inch */
1666 const char *header, const char *trailer,
1667 enum orientation orient,
1668 int invert, int initial_formfeed, int position_on_page, int slide,
1669 enum device device,
1670 unsigned int cutoff,
1671 float gamma,
1672 int render)
1673{
1674 int paintjet = FALSE0;
1675
1676 true_scale = scale;
1677
1678 if (device != LJET)
1679 paintjet = TRUE1;
1680
1681 read_xwd_data(in);
1682
1683 Z_pixel_mask = ~(0xFFFFFFFFUL << xwd_header.pixmap_depth);
1684
1685 prepare_color_mapping(invert, paintjet, cutoff, out);
1686
1687 scale_and_orient_image(&scale, &density, width, height, left, top,
1688 header, trailer,
1689 &orient, position_on_page, device);
1690
1691 write_image_prefix(out, scale, density, header, device, position_on_page,
1692 initial_formfeed, orient, gamma, render, slide);
1693
1694 write_image(out, scale, orient, device);
1695
1696 write_image_suffix(out, trailer, position_on_page, slide, render, device);
1697
1698 fclose(out);
1699}
1700
1701static
1702void fatal_err (const char *s, ...)
1703{
1704 va_list ap;
1705
1706 fprintf(stderrstderr, "%s: ", progname);
1707 va_start(ap, s)__builtin_va_start(ap, s);
1708 vfprintf(stderrstderr, s, ap);
1709 va_end(ap)__builtin_va_end(ap);
1710 fputc('\n', stderrstderr);
1711 exit(EXIT_FAILURE1);
1712}
1713