]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/imagetops.c
Merge changes from 1.1 tree.
[thirdparty/cups.git] / filter / imagetops.c
CommitLineData
516ba4c9 1/*
b5cb0608 2 * "$Id: imagetops.c,v 1.36.2.1 2001/05/13 18:38:18 mike Exp $"
516ba4c9 3 *
ed19bd98 4 * Image file to PostScript filter for the Common UNIX Printing System (CUPS).
516ba4c9 5 *
d2935a0f 6 * Copyright 1993-2001 by Easy Software Products.
516ba4c9 7 *
ed19bd98 8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
516ba4c9 14 *
ed19bd98 15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
af526a52 19 *
ed19bd98 20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
d850a9e1 23 *
ed19bd98 24 * Contents:
516ba4c9 25 *
ed19bd98 26 * main() - Main entry...
27 * ps_hex() - Print binary data as a series of hexadecimal numbers.
28 * ps_ascii85() - Print binary data as a series of base-85 numbers.
516ba4c9 29 */
30
31/*
32 * Include necessary headers...
33 */
34
ed19bd98 35#include "common.h"
516ba4c9 36#include "image.h"
ed19bd98 37#include <math.h>
516ba4c9 38
39
40/*
41 * Globals...
42 */
43
ed19bd98 44int Flip = 0, /* Flip/mirror pages */
c5da5726 45 XPosition = 0, /* Horizontal position on page */
46 YPosition = 0, /* Vertical position on page */
ed19bd98 47 Collate = 0, /* Collate copies? */
48 Copies = 1; /* Number of copies */
516ba4c9 49
50
51/*
52 * Local functions...
53 */
54
b5cb0608 55static void ps_hex(ib_t *, int, int);
ed19bd98 56static void ps_ascii85(ib_t *, int, int);
516ba4c9 57
58
59/*
60 * 'main()' - Main entry...
61 */
62
ed19bd98 63int /* O - Exit status */
516ba4c9 64main(int argc, /* I - Number of command-line arguments */
65 char *argv[]) /* I - Command-line arguments */
66{
ed19bd98 67 image_t *img; /* Image to print */
68 float xprint, /* Printable area */
69 yprint,
70 xinches, /* Total size in inches */
71 yinches;
72 float xsize, /* Total size in points */
48c4ffef 73 ysize,
74 xsize2,
75 ysize2;
332197a2 76 float aspect; /* Aspect ratio */
ed19bd98 77 int xpages, /* # x pages */
78 ypages, /* # y pages */
79 xpage, /* Current x page */
80 ypage, /* Current y page */
81 page; /* Current page number */
82 int x0, y0, /* Corners of the page in image coords */
83 x1, y1;
84 ib_t *row; /* Current row */
85 int y; /* Current Y coordinate in image */
86 int colorspace; /* Output colorspace */
87 int out_offset, /* Offset into output buffer */
88 out_length; /* Length of output buffer */
89 ppd_file_t *ppd; /* PPD file */
b5cb0608 90 ppd_choice_t *choice; /* PPD option choice */
ed19bd98 91 int num_options; /* Number of print options */
92 cups_option_t *options; /* Print options */
568d2c2f 93 const char *val; /* Option value */
ed19bd98 94 int slowcollate; /* Collate copies the slow way */
95 float g; /* Gamma correction value */
96 float b; /* Brightness factor */
97 float zoom; /* Zoom facter */
332197a2 98 int xppi, yppi; /* Pixels-per-inch */
ed19bd98 99 int hue, sat; /* Hue and saturation adjustment */
19ec0c2c 100 int realcopies; /* Real copies being printed */
c5da5726 101 float left, top; /* Left and top of image */
7ce9aa3d 102 char filename[1024]; /* Name of file to print */
b5cb0608 103 time_t curtime; /* Current time */
104 struct tm *curtm; /* Current date */
105 char curdate[255]; /* Current date string */
ed19bd98 106
107
7ce9aa3d 108 /*
cc787dc1 109 * Make sure status messages are not buffered...
110 */
111
112 setbuf(stderr, NULL);
113
114 /*
115 * Check command-line...
7ce9aa3d 116 */
117
118 if (argc < 6 || argc > 7)
ed19bd98 119 {
7ce9aa3d 120 fputs("ERROR: imagetops job-id user title copies options [file]\n", stderr);
ed19bd98 121 return (1);
122 }
516ba4c9 123
7ce9aa3d 124 fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
125 argv[3], argv[4], argv[5], argv[6] ? argv[6] : "(null)");
126
127 /*
128 * Copy stdin as needed...
129 */
130
131 if (argc == 6)
132 {
1b5bf964 133 int fd; /* File to write to */
7ce9aa3d 134 char buffer[8192]; /* Buffer to read into */
135 int bytes; /* # of bytes to read */
136
137
1b5bf964 138 if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
7ce9aa3d 139 {
140 perror("ERROR: Unable to copy image file");
141 return (1);
142 }
143
1b5bf964 144 fprintf(stderr, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
7ce9aa3d 145 filename);
146
147 while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
1b5bf964 148 write(fd, buffer, bytes);
149
150 close(fd);
7ce9aa3d 151 }
152 else
153 {
154 strncpy(filename, argv[6], sizeof(filename) - 1);
155 filename[sizeof(filename) - 1] = '\0';
156 }
157
516ba4c9 158 /*
ed19bd98 159 * Process command-line options and write the prolog...
516ba4c9 160 */
161
ed19bd98 162 zoom = 0.0;
332197a2 163 xppi = 0;
164 yppi = 0;
ed19bd98 165 hue = 0;
166 sat = 100;
f0d2f1a4 167 g = 1.0;
ed19bd98 168 b = 1.0;
516ba4c9 169
ae818f4d 170 Copies = atoi(argv[4]);
171
ed19bd98 172 options = NULL;
173 num_options = cupsParseOptions(argv[5], 0, &options);
516ba4c9 174
4e989042 175 ppd = SetCommonOptions(num_options, options, 1);
516ba4c9 176
ed19bd98 177 if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
516ba4c9 178 {
ed19bd98 179 /*
180 * This IPP attribute is unnecessarily complicated...
181 *
182 * single-document, separate-documents-collated-copies, and
183 * single-document-new-sheet all require collated copies.
184 *
3e41e580 185 * separate-documents-uncollated-copies allows for uncollated copies.
ed19bd98 186 */
516ba4c9 187
3e41e580 188 Collate = strcasecmp(val, "separate-documents-uncollated-copies") != 0;
ed19bd98 189 }
516ba4c9 190
ed19bd98 191 if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
a7b3e92e 192 strcasecmp(val, "True") == 0)
ed19bd98 193 Collate = 1;
516ba4c9 194
ed19bd98 195 if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
196 g = atoi(val) * 0.001f;
516ba4c9 197
ed19bd98 198 if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
199 b = atoi(val) * 0.01f;
516ba4c9 200
ed19bd98 201 if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
202 zoom = atoi(val) * 0.01;
516ba4c9 203
ed19bd98 204 if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
332197a2 205 if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
206 yppi = xppi;
516ba4c9 207
c5da5726 208 if ((val = cupsGetOption("position", num_options, options)) != NULL)
209 {
210 if (strcasecmp(val, "center") == 0)
211 {
212 XPosition = 0;
213 YPosition = 0;
214 }
215 else if (strcasecmp(val, "top") == 0)
216 {
217 XPosition = 0;
218 YPosition = 1;
219 }
220 else if (strcasecmp(val, "left") == 0)
221 {
222 XPosition = -1;
223 YPosition = 0;
224 }
225 else if (strcasecmp(val, "right") == 0)
226 {
227 XPosition = 1;
228 YPosition = 0;
229 }
230 else if (strcasecmp(val, "top-left") == 0)
231 {
232 XPosition = -1;
233 YPosition = 1;
234 }
235 else if (strcasecmp(val, "top-right") == 0)
236 {
237 XPosition = 1;
238 YPosition = 1;
239 }
240 else if (strcasecmp(val, "bottom") == 0)
241 {
242 XPosition = 0;
243 YPosition = -1;
244 }
245 else if (strcasecmp(val, "bottom-left") == 0)
246 {
247 XPosition = -1;
248 YPosition = -1;
249 }
250 else if (strcasecmp(val, "bottom-right") == 0)
251 {
252 XPosition = 1;
253 YPosition = -1;
254 }
255 }
256
ed19bd98 257 if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
258 sat = atoi(val);
259
260 if ((val = cupsGetOption("hue", num_options, options)) != NULL)
261 hue = atoi(val);
516ba4c9 262
263 /*
264 * Open the input image to print...
265 */
266
ed19bd98 267 colorspace = ColorDevice ? IMAGE_RGB : IMAGE_WHITE;
516ba4c9 268
7ce9aa3d 269 img = ImageOpen(filename, colorspace, IMAGE_WHITE, sat, hue, NULL);
270
271 if (argc == 6)
272 unlink(filename);
273
274 if (img == NULL)
ed19bd98 275 {
276 fputs("ERROR: Unable to open image file for printing!\n", stderr);
277 ppdClose(ppd);
278 return (1);
279 }
516ba4c9 280
ed19bd98 281 colorspace = img->colorspace;
516ba4c9 282
283 /*
284 * Scale as necessary...
285 */
286
48c4ffef 287 xprint = (PageRight - PageLeft) / 72.0;
288 yprint = (PageTop - PageBottom) / 72.0;
289
332197a2 290 if (zoom == 0.0 && xppi == 0)
291 {
292 xppi = img->xppi;
293 yppi = img->yppi;
294 }
295
296 if (yppi == 0)
297 yppi = xppi;
298
299 if (xppi > 0)
516ba4c9 300 {
301 /*
302 * Scale the image as neccesary to match the desired pixels-per-inch.
303 */
304
332197a2 305 xinches = (float)img->xsize / (float)xppi;
306 yinches = (float)img->ysize / (float)yppi;
48c4ffef 307
b16dd9cb 308 if (cupsGetOption("orientation", num_options, options) == NULL &&
309 cupsGetOption("landscape", num_options, options) == NULL)
48c4ffef 310 {
311 /*
b16dd9cb 312 * Rotate the image if it will fit landscape but not portrait...
48c4ffef 313 */
314
b16dd9cb 315 if ((xinches > xprint || yinches > yprint) &&
316 xinches <= yprint && yinches <= xprint)
317 {
318 /*
319 * Rotate the image as needed...
320 */
321
322 Orientation = (Orientation + 1) & 3;
323 xsize = yprint;
324 yprint = xprint;
325 xprint = xsize;
326
327 xsize = PageLeft;
328 PageLeft = PageBottom;
329 PageBottom = PageWidth - PageRight;
330 PageRight = PageTop;
331 PageTop = PageLength - xsize;
332
333 xsize = PageWidth;
334 PageWidth = PageLength;
335 PageLength = xsize;
336 }
48c4ffef 337 }
516ba4c9 338 }
339 else
340 {
341 /*
342 * Scale percentage of page size...
343 */
344
332197a2 345 aspect = (float)img->yppi / (float)img->xppi;
346
347 fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
348 img->xppi, img->yppi, aspect);
349
ed19bd98 350 xsize = xprint * zoom;
332197a2 351 ysize = xsize * img->ysize / img->xsize / aspect;
0169953d 352
ed19bd98 353 if (ysize > (yprint * zoom))
516ba4c9 354 {
ed19bd98 355 ysize = yprint * zoom;
332197a2 356 xsize = ysize * img->xsize * aspect / img->ysize;
516ba4c9 357 }
0169953d 358
48c4ffef 359 xsize2 = yprint * zoom;
332197a2 360 ysize2 = xsize2 * img->ysize / img->xsize / aspect;
48c4ffef 361
362 if (ysize2 > (xprint * zoom))
363 {
364 ysize2 = xprint * zoom;
332197a2 365 xsize2 = ysize2 * img->xsize * aspect / img->ysize;
48c4ffef 366 }
367
332197a2 368 fprintf(stderr, "DEBUG: xsize = %.0f, ysize = %.0f\n", xsize, ysize);
369 fprintf(stderr, "DEBUG: xsize2 = %.0f, ysize2 = %.0f\n", xsize2, ysize2);
370
b16dd9cb 371 if (cupsGetOption("orientation", num_options, options) == NULL &&
372 cupsGetOption("landscape", num_options, options) == NULL)
48c4ffef 373 {
374 /*
b16dd9cb 375 * Choose the rotation with the largest area, but prefer
376 * portrait if they are equal...
48c4ffef 377 */
378
b16dd9cb 379 if ((xsize * ysize) < (xsize2 * xsize2))
380 {
381 /*
382 * Do landscape orientation...
383 */
384
385 Orientation = 1;
386 xinches = xsize2;
387 yinches = ysize2;
388 xprint = (PageTop - PageBottom) / 72.0;
389 yprint = (PageRight - PageLeft) / 72.0;
390
391 xsize = PageLeft;
392 PageLeft = PageBottom;
393 PageBottom = PageWidth - PageRight;
394 PageRight = PageTop;
395 PageTop = PageLength - xsize;
396
397 xsize = PageWidth;
398 PageWidth = PageLength;
399 PageLength = xsize;
400 }
401 else
402 {
403 /*
404 * Do portrait orientation...
405 */
406
407 Orientation = 0;
408 xinches = xsize;
409 yinches = ysize;
410 }
411 }
412 else if (Orientation & 1)
413 {
48c4ffef 414 xinches = xsize2;
415 yinches = ysize2;
416 xprint = (PageTop - PageBottom) / 72.0;
417 yprint = (PageRight - PageLeft) / 72.0;
418
419 xsize = PageLeft;
420 PageLeft = PageBottom;
421 PageBottom = PageWidth - PageRight;
422 PageRight = PageTop;
423 PageTop = PageLength - xsize;
424
425 xsize = PageWidth;
426 PageWidth = PageLength;
427 PageLength = xsize;
428 }
b6ea8f29 429 else
430 {
431 xinches = xsize;
432 yinches = ysize;
433 xprint = (PageRight - PageLeft) / 72.0;
434 yprint = (PageTop - PageBottom) / 72.0;
435 }
ed19bd98 436 }
516ba4c9 437
b5cb0608 438 /*
439 * Compute the number of pages to print and the size of the image on each
440 * page...
441 */
442
ed19bd98 443 xpages = ceil(xinches / xprint);
444 ypages = ceil(yinches / yprint);
0169953d 445
b5cb0608 446 xprint = xinches / xpages;
447 yprint = yinches / ypages;
448
449 /*
450 * Update the page size for custom sizes...
451 */
452
453 if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
454 strcasecmp(choice->choice, "Custom") == 0)
455 {
456 float width, /* New width in points */
457 length; /* New length in points */
458 char s[255]; /* New custom page size... */
459
460
461 if (Orientation & 1)
462 {
463 width = yprint * 72.0;
464 length = xprint * 72.0;
465 }
466 else
467 {
468 width = xprint * 72.0;
469 length = yprint * 72.0;
470 }
471
472 /*
473 * Add margins to page size...
474 */
475
476 width += ppd->custom_margins[0] + ppd->custom_margins[2];
477 length += ppd->custom_margins[1] + ppd->custom_margins[3];
478
479 /*
480 * Enforce minimums...
481 */
482
483 if (width < ppd->custom_min[0])
484 width = ppd->custom_min[0];
485
486 if (length < ppd->custom_min[1])
487 length = ppd->custom_min[1];
488
489 /*
490 * Set the new custom size...
491 */
492
493 sprintf(s, "Custom.%.0fx%.0f", width, length);
494 ppdMarkOption(ppd, "PageSize", s);
495
496 /*
497 * Update page variables...
498 */
499
500 PageWidth = width;
501 PageLength = length;
502 PageLeft = ppd->custom_margins[0];
503 PageRight = width - ppd->custom_margins[2];
504 PageBottom = ppd->custom_margins[1];
505 PageTop = length - ppd->custom_margins[3];
506
507 UpdatePageVars();
508 }
509
ed19bd98 510 /*
511 * See if we need to collate, and if so how we need to do it...
512 */
516ba4c9 513
ed19bd98 514 if (xpages == 1 && ypages == 1)
515 Collate = 0;
516ba4c9 516
ed19bd98 517 slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
516ba4c9 518
b5cb0608 519 if (Copies > 1 && !slowcollate)
520 {
521 realcopies = Copies;
522 Copies = 1;
523 }
524 else
525 realcopies = 1;
526
ed19bd98 527 /*
528 * Write any "exit server" options that have been selected...
529 */
516ba4c9 530
ed19bd98 531 ppdEmit(ppd, stdout, PPD_ORDER_EXIT);
516ba4c9 532
ed19bd98 533 /*
534 * Write any JCL commands that are needed to print PostScript code...
535 */
536
ee6a18b5 537 ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]);
516ba4c9 538
539 /*
ed19bd98 540 * Start sending the document with any commands needed...
516ba4c9 541 */
542
b5cb0608 543 curtime = time(NULL);
544 curtm = localtime(&curtime);
545
546 puts("%!PS-Adobe-3.0");
547 printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom,
548 PageRight, PageTop);
549 printf("%%%%LanguageLevel: %d\n", LanguageLevel);
550 printf("%%%%Pages: %d\n", xpages * ypages * Copies);
551 puts("%%DocumentData: Clean7Bit");
552 puts("%%DocumentNeededResources: font Helvetica-Bold");
553 puts("%%Creator: imagetops/" CUPS_SVERSION);
554 strftime(curdate, sizeof(curdate), CUPS_STRFTIME_FORMAT, curtm);
555 printf("%%%%CreationDate: %s\n", curdate);
556 printf("%%%%Title: %s\n", argv[3]);
557 printf("%%%%For: %s\n", argv[2]);
558 if (Orientation & 1)
559 puts("%%Orientation: Landscape");
560 puts("%%EndComments");
561 puts("%%BeginProlog");
ed19bd98 562
37b19c12 563 if (ppd != NULL && ppd->patches != NULL)
564 puts(ppd->patches);
565
ed19bd98 566 ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT);
567 ppdEmit(ppd, stdout, PPD_ORDER_ANY);
568 ppdEmit(ppd, stdout, PPD_ORDER_PROLOG);
516ba4c9 569
ed19bd98 570 if (g != 1.0 || b != 1.0)
37b19c12 571 printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
572 "ifelse %.3f mul } bind settransfer\n", g, b);
ed19bd98 573
d11458ff 574 WriteLabelProlog(cupsGetOption("page-label", num_options, options));
575
b5cb0608 576 if (realcopies > 1)
516ba4c9 577 {
83f08393 578 if (ppd == NULL || ppd->language_level == 1)
b5cb0608 579 printf("/#copies %d def\n", realcopies);
83f08393 580 else
b5cb0608 581 printf("<</NumCopies %d>>setpagedevice\n", realcopies);
ed19bd98 582 }
b5cb0608 583
584 puts("%%EndProlog");
516ba4c9 585
586 /*
587 * Output the pages...
588 */
589
b5cb0608 590 row = malloc(img->xsize * abs(colorspace) + 3);
0169953d 591
ed19bd98 592 for (page = 1; Copies > 0; Copies --)
593 for (xpage = 0; xpage < xpages; xpage ++)
594 for (ypage = 0; ypage < ypages; ypage ++, page ++)
595 {
b5cb0608 596 if (ppd && ppd->num_filters == 0)
597 fprintf(stderr, "PAGE: %d %d\n", page, realcopies);
598
599 fprintf(stderr, "INFO: Printing page %d...\n", page);
600
601 printf("%%%%Page: %d %d\n", page, page);
516ba4c9 602
ed19bd98 603 ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
516ba4c9 604
ed19bd98 605 puts("gsave");
516ba4c9 606
ed19bd98 607 if (Flip)
608 printf("%.0f 0 translate -1 1 scale\n", PageWidth);
609
610 switch (Orientation)
611 {
612 case 1 : /* Landscape */
613 printf("%.0f 0 translate 90 rotate\n", PageLength);
614 break;
615 case 2 : /* Reverse Portrait */
616 printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
617 break;
618 case 3 : /* Reverse Landscape */
619 printf("0 %.0f translate -90 rotate\n", PageWidth);
620 break;
621 }
516ba4c9 622
5398375f 623 x0 = img->xsize * xpage / xpages;
624 x1 = img->xsize * (xpage + 1) / xpages - 1;
625 y0 = img->ysize * ypage / ypages;
626 y1 = img->ysize * (ypage + 1) / ypages - 1;
516ba4c9 627
c5da5726 628 switch (XPosition)
629 {
630 case -1 :
631 left = PageLeft;
632 break;
b6ea8f29 633 default :
c5da5726 634 left = (PageWidth - xprint * 72.0) * 0.5;
635 break;
636 case 1 :
637 left = PageRight - xprint * 72.0;
638 break;
639 }
640
641 switch (YPosition)
642 {
643 case -1 :
644 top = PageBottom + 72.0 * yprint;
645 break;
b6ea8f29 646 default :
c5da5726 647 top = (PageLength + yprint * 72.0) * 0.5;
648 break;
649 case 1 :
650 top = PageTop;
651 break;
652 }
653
654 printf("%.1f %.1f translate\n", left, top);
655
ed19bd98 656 printf("%.3f %.3f scale\n\n",
657 xprint * 72.0 / (x1 - x0 + 1),
658 yprint * 72.0 / (y1 - y0 + 1));
516ba4c9 659
ed19bd98 660 if (LanguageLevel == 1)
af526a52 661 {
ed19bd98 662 printf("/picture %d string def\n", (x1 - x0 + 1) * abs(colorspace));
663 printf("%d %d 8[1 0 0 -1 0 1]", (x1 - x0 + 1), (y1 - y0 + 1));
664
665 if (colorspace == IMAGE_WHITE)
666 puts("{currentfile picture readhexstring pop} image");
af526a52 667 else
ed19bd98 668 puts("{currentfile picture readhexstring pop} false 3 colorimage");
669
670 for (y = y0; y <= y1; y ++)
671 {
672 ImageGetRow(img, x0, y, x1 - x0 + 1, row);
b5cb0608 673 ps_hex(row, (x1 - x0 + 1) * abs(colorspace), y == y1);
ed19bd98 674 }
af526a52 675 }
676 else
677 {
ed19bd98 678 if (colorspace == IMAGE_WHITE)
679 puts("/DeviceGray setcolorspace");
af526a52 680 else
ed19bd98 681 puts("/DeviceRGB setcolorspace");
af526a52 682
ed19bd98 683 printf("<<"
684 "/ImageType 1"
685 "/Width %d"
686 "/Height %d"
687 "/BitsPerComponent 8",
688 x1 - x0 + 1, y1 - y0 + 1);
af526a52 689
ed19bd98 690 if (colorspace == IMAGE_WHITE)
691 fputs("/Decode[0 1]", stdout);
692 else
693 fputs("/Decode[0 1 0 1 0 1]", stdout);
af526a52 694
ed19bd98 695 fputs("/DataSource currentfile /ASCII85Decode filter", stdout);
af526a52 696
ed19bd98 697 if (((x1 - x0 + 1) / xprint) < 100.0)
698 fputs("/Interpolate true", stdout);
5398375f 699
ed19bd98 700 puts("/ImageMatrix[1 0 0 -1 0 1]>>image");
af526a52 701
ed19bd98 702 for (y = y0, out_offset = 0; y <= y1; y ++)
703 {
704 ImageGetRow(img, x0, y, x1 - x0 + 1, row + out_offset);
af526a52 705
ed19bd98 706 out_length = (x1 - x0 + 1) * abs(colorspace) + out_offset;
707 out_offset = out_length & 3;
516ba4c9 708
ed19bd98 709 ps_ascii85(row, out_length, y == y1);
516ba4c9 710
ed19bd98 711 if (out_offset > 0)
712 memcpy(row, row + out_length - out_offset, out_offset);
713 }
714 }
516ba4c9 715
ed19bd98 716 puts("grestore");
d11458ff 717 WriteLabels();
ed19bd98 718 puts("showpage");
719 }
516ba4c9 720
b5cb0608 721 puts("%%EOF");
722
ed19bd98 723 /*
724 * End the job with the appropriate JCL command or CTRL-D otherwise.
725 */
516ba4c9 726
ed19bd98 727 if (ppd != NULL && ppd->jcl_end)
6853ae56 728 fputs(ppd->jcl_end, stdout);
ed19bd98 729 else
730 putchar(0x04);
516ba4c9 731
ed19bd98 732 /*
733 * Close files...
734 */
516ba4c9 735
736 ImageClose(img);
ed19bd98 737 ppdClose(ppd);
516ba4c9 738
ed19bd98 739 return (0);
516ba4c9 740}
741
742
743/*
744 * 'ps_hex()' - Print binary data as a series of hexadecimal numbers.
745 */
746
747static void
b5cb0608 748ps_hex(ib_t *data, /* I - Data to print */
749 int length, /* I - Number of bytes to print */
750 int last_line) /* I - Last line of raster data? */
516ba4c9 751{
b5cb0608 752 static int col = 0; /* Current column */
516ba4c9 753 static char *hex = "0123456789ABCDEF";
b5cb0608 754 /* Hex digits */
516ba4c9 755
756
757 while (length > 0)
758 {
759 /*
ed19bd98 760 * Put the hex chars out to the file; note that we don't use printf()
516ba4c9 761 * for speed reasons...
762 */
763
ed19bd98 764 putchar(hex[*data >> 4]);
765 putchar(hex[*data & 15]);
516ba4c9 766
767 data ++;
768 length --;
af526a52 769
b5cb0608 770 col += 2;
771 if (col > 78)
772 {
ed19bd98 773 putchar('\n');
b5cb0608 774 col = 0;
775 }
ed19bd98 776 }
516ba4c9 777
b5cb0608 778 if (last_line && col)
779 {
780 putchar('\n');
781 col = 0;
782 }
516ba4c9 783}
784
785
786/*
787 * 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
788 */
789
790static void
ed19bd98 791ps_ascii85(ib_t *data, /* I - Data to print */
516ba4c9 792 int length, /* I - Number of bytes to print */
793 int last_line) /* I - Last line of raster data? */
794{
795 unsigned b; /* Binary data word */
796 unsigned char c[5]; /* ASCII85 encoded chars */
b5cb0608 797 static int col = 0; /* Current column */
516ba4c9 798
799
516ba4c9 800 while (length > 3)
801 {
802 b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
803
804 if (b == 0)
b5cb0608 805 {
ed19bd98 806 putchar('z');
b5cb0608 807 col ++;
808 }
516ba4c9 809 else
810 {
811 c[4] = (b % 85) + '!';
812 b /= 85;
813 c[3] = (b % 85) + '!';
814 b /= 85;
815 c[2] = (b % 85) + '!';
816 b /= 85;
817 c[1] = (b % 85) + '!';
818 b /= 85;
819 c[0] = b + '!';
820
ed19bd98 821 fwrite(c, 5, 1, stdout);
b5cb0608 822 col += 5;
ed19bd98 823 }
516ba4c9 824
825 data += 4;
826 length -= 4;
b5cb0608 827
828 if (col >= 75)
829 {
830 putchar('\n');
831 col = 0;
832 }
ed19bd98 833 }
516ba4c9 834
835 if (last_line)
836 {
837 if (length > 0)
838 {
4364903a 839 memset(data + length, 0, 4 - length);
840 b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
516ba4c9 841
842 c[4] = (b % 85) + '!';
843 b /= 85;
844 c[3] = (b % 85) + '!';
845 b /= 85;
846 c[2] = (b % 85) + '!';
847 b /= 85;
848 c[1] = (b % 85) + '!';
849 b /= 85;
850 c[0] = b + '!';
851
ed19bd98 852 fwrite(c, length + 1, 1, stdout);
853 }
516ba4c9 854
ed19bd98 855 puts("~>");
b5cb0608 856 col = 0;
516ba4c9 857 }
516ba4c9 858}
859
860
861/*
b5cb0608 862 * End of "$Id: imagetops.c,v 1.36.2.1 2001/05/13 18:38:18 mike Exp $".
516ba4c9 863 */