]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/rastertohp.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / filter / rastertohp.c
CommitLineData
ef416fc2 1/*
f2d18633 2 * "$Id$"
ef416fc2 3 *
7e86f2f6 4 * Hewlett-Packard Page Control Language filter for CUPS.
ef416fc2 5 *
7e86f2f6
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
ef416fc2 8 *
7e86f2f6
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
7e86f2f6 15 * This file is subject to the Apple OS-Developed Software exception.
ef416fc2 16 */
17
18/*
19 * Include necessary headers...
20 */
21
22#include <cups/cups.h>
aaf19ab0 23#include <cups/ppd.h>
71e16022
MS
24#include <cups/string-private.h>
25#include <cups/language-private.h>
ac884b6a 26#include <cups/raster.h>
ef416fc2 27#include <unistd.h>
28#include <fcntl.h>
29#include <signal.h>
30
31
32/*
33 * Globals...
34 */
35
36unsigned char *Planes[4], /* Output buffers */
37 *CompBuffer, /* Compression buffer */
38 *BitBuffer; /* Buffer for output bits */
7e86f2f6 39unsigned NumPlanes, /* Number of color planes */
ef416fc2 40 ColorBits, /* Number of bits per color */
7e86f2f6
MS
41 Feed; /* Number of lines to skip */
42int Duplex, /* Current duplex mode */
839a51c8
MS
43 Page, /* Current page number */
44 Canceled; /* Has the current job been canceled? */
ef416fc2 45
46
47/*
48 * Prototypes...
49 */
50
51void Setup(void);
839a51c8 52void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
ef416fc2 53void EndPage(void);
54void Shutdown(void);
55
56void CancelJob(int sig);
7e86f2f6 57void CompressData(unsigned char *line, unsigned length, unsigned plane, unsigned type);
839a51c8 58void OutputLine(cups_page_header2_t *header);
ef416fc2 59
60
61/*
62 * 'Setup()' - Prepare the printer for printing.
63 */
64
65void
66Setup(void)
67{
68 /*
69 * Send a PCL reset sequence.
70 */
71
72 putchar(0x1b);
73 putchar('E');
74}
75
76
77/*
78 * 'StartPage()' - Start a page of graphics.
79 */
80
81void
82StartPage(ppd_file_t *ppd, /* I - PPD file */
839a51c8 83 cups_page_header2_t *header) /* I - Page header */
ef416fc2 84{
7e86f2f6 85 unsigned plane; /* Looping var */
ef416fc2 86
87
ef416fc2 88 /*
89 * Show page device dictionary...
90 */
91
92 fprintf(stderr, "DEBUG: StartPage...\n");
93 fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
94 fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
95 fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
96 fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
97
98 fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
99 fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
100 fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
101 fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
102 fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
103 fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
104 header->HWResolution[1]);
105 fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
106 header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
107 header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
108 fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
109 fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
110 fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
111 fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
112 header->Margins[1]);
113 fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
114 fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
115 fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
116 fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
117 fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
118 fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
119 fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
120 fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
121 fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
122 header->PageSize[1]);
123 fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
124 fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
125 fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
126 fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
127 fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
128 fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
129 fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
130 fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
131 fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
132 fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
133 fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
134 fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
135
136 /*
137 * Setup printer/job attributes...
138 */
139
140 Duplex = header->Duplex;
141 ColorBits = header->cupsBitsPerColor;
142
143 if ((!Duplex || (Page & 1)) && header->MediaPosition)
144 printf("\033&l%dH", /* Set media position */
145 header->MediaPosition);
146
147 if (Duplex && ppd && ppd->model_number == 2)
148 {
149 /*
150 * Handle duplexing on new DeskJet printers...
151 */
152
153 printf("\033&l-2H"); /* Load media */
154
155 if (Page & 1)
156 printf("\033&l2S"); /* Set duplex mode */
157 }
158
159 if (!Duplex || (Page & 1) || (ppd && ppd->model_number == 2))
160 {
161 /*
162 * Set the media size...
163 */
164
165 printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
166 printf("\033&l0O"); /* Set portrait orientation */
167
168 switch (header->PageSize[1])
169 {
170 case 540 : /* Monarch Envelope */
171 printf("\033&l80A"); /* Set page size */
172 break;
173
ee571f26
MS
174 case 595 : /* A5 */
175 printf("\033&l25A"); /* Set page size */
176 break;
177
ef416fc2 178 case 624 : /* DL Envelope */
179 printf("\033&l90A"); /* Set page size */
180 break;
181
182 case 649 : /* C5 Envelope */
183 printf("\033&l91A"); /* Set page size */
184 break;
185
186 case 684 : /* COM-10 Envelope */
187 printf("\033&l81A"); /* Set page size */
188 break;
189
190 case 709 : /* B5 Envelope */
191 printf("\033&l100A"); /* Set page size */
192 break;
193
194 case 756 : /* Executive */
195 printf("\033&l1A"); /* Set page size */
196 break;
197
198 case 792 : /* Letter */
199 printf("\033&l2A"); /* Set page size */
200 break;
201
202 case 842 : /* A4 */
203 printf("\033&l26A"); /* Set page size */
204 break;
205
206 case 1008 : /* Legal */
207 printf("\033&l3A"); /* Set page size */
208 break;
209
210 case 1191 : /* A3 */
211 printf("\033&l27A"); /* Set page size */
212 break;
213
214 case 1224 : /* Tabloid */
215 printf("\033&l6A"); /* Set page size */
216 break;
217 }
218
219 printf("\033&l%dP", /* Set page length */
220 header->PageSize[1] / 12);
221 printf("\033&l0E"); /* Set top margin to 0 */
222 }
223
224 if (!Duplex || (Page & 1))
225 {
226 /*
227 * Set other job options...
228 */
229
230 printf("\033&l%dX", header->NumCopies); /* Set number copies */
231
232 if (header->cupsMediaType &&
233 (!ppd || ppd->model_number != 2 || header->HWResolution[0] == 600))
234 printf("\033&l%dM", /* Set media type */
235 header->cupsMediaType);
236
237 if (!ppd || ppd->model_number != 2)
238 {
238c3832 239 int mode = Duplex ? 1 + header->Tumble != 0 : 0;
ef416fc2 240
238c3832 241 printf("\033&l%dS", mode); /* Set duplex mode */
ef416fc2 242 printf("\033&l0L"); /* Turn off perforation skip */
243 }
244 }
245 else if (!ppd || ppd->model_number != 2)
246 printf("\033&a2G"); /* Set back side */
247
248 /*
249 * Set graphics mode...
250 */
251
91c84a35 252 if (ppd && ppd->model_number == 2)
ef416fc2 253 {
254 /*
255 * Figure out the number of color planes...
256 */
257
258 if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
259 NumPlanes = 4;
260 else
261 NumPlanes = 1;
262
263 /*
264 * Set the resolution and top-of-form...
265 */
266
267 printf("\033&u%dD", header->HWResolution[0]);
268 /* Resolution */
269 printf("\033&l0e0L"); /* Reset top and don't skip */
270 printf("\033*p0Y\033*p0X"); /* Set top of form */
271
272 /*
273 * Send 26-byte configure image data command with horizontal and
274 * vertical resolutions as well as a color count...
275 */
276
277 printf("\033*g26W");
278 putchar(2); /* Format 2 */
7e86f2f6 279 putchar((int)NumPlanes); /* Output planes */
ef416fc2 280
7e86f2f6
MS
281 putchar((int)(header->HWResolution[0] >> 8));/* Black resolution */
282 putchar((int)header->HWResolution[0]);
283 putchar((int)(header->HWResolution[1] >> 8));
284 putchar((int)header->HWResolution[1]);
ef416fc2 285 putchar(0);
286 putchar(1 << ColorBits); /* # of black levels */
287
7e86f2f6
MS
288 putchar((int)(header->HWResolution[0] >> 8));/* Cyan resolution */
289 putchar((int)header->HWResolution[0]);
290 putchar((int)(header->HWResolution[1] >> 8));
291 putchar((int)header->HWResolution[1]);
ef416fc2 292 putchar(0);
293 putchar(1 << ColorBits); /* # of cyan levels */
294
7e86f2f6
MS
295 putchar((int)(header->HWResolution[0] >> 8));/* Magenta resolution */
296 putchar((int)header->HWResolution[0]);
297 putchar((int)(header->HWResolution[1] >> 8));
298 putchar((int)header->HWResolution[1]);
ef416fc2 299 putchar(0);
300 putchar(1 << ColorBits); /* # of magenta levels */
301
7e86f2f6
MS
302 putchar((int)(header->HWResolution[0] >> 8));/* Yellow resolution */
303 putchar((int)header->HWResolution[0]);
304 putchar((int)(header->HWResolution[1] >> 8));
305 putchar((int)header->HWResolution[1]);
ef416fc2 306 putchar(0);
307 putchar(1 << ColorBits); /* # of yellow levels */
308
309 printf("\033&l0H"); /* Set media position */
310 }
311 else
312 {
7e86f2f6 313 printf("\033*t%uR", header->HWResolution[0]);
ef416fc2 314 /* Set resolution */
315
316 if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
317 {
318 NumPlanes = 4;
319 printf("\033*r-4U"); /* Set KCMY graphics */
320 }
321 else if (header->cupsColorSpace == CUPS_CSPACE_CMY)
322 {
323 NumPlanes = 3;
324 printf("\033*r-3U"); /* Set CMY graphics */
325 }
326 else
327 NumPlanes = 1; /* Black&white graphics */
328
329 /*
330 * Set size and position of graphics...
331 */
332
7e86f2f6
MS
333 printf("\033*r%uS", header->cupsWidth); /* Set width */
334 printf("\033*r%uT", header->cupsHeight); /* Set height */
ef416fc2 335
336 printf("\033&a0H"); /* Set horizontal position */
337
338 if (ppd)
339 printf("\033&a%.0fV", /* Set vertical position */
340 10.0 * (ppd->sizes[0].length - ppd->sizes[0].top));
341 else
342 printf("\033&a0V"); /* Set top-of-page */
343 }
344
345 printf("\033*r1A"); /* Start graphics */
346
347 if (header->cupsCompression)
7e86f2f6 348 printf("\033*b%uM", /* Set compression */
ef416fc2 349 header->cupsCompression);
350
351 Feed = 0; /* No blank lines yet */
352
353 /*
354 * Allocate memory for a line of graphics...
355 */
356
91c84a35
MS
357 if ((Planes[0] = malloc(header->cupsBytesPerLine)) == NULL)
358 {
4d301e69 359 fputs("ERROR: Unable to allocate memory\n", stderr);
91c84a35
MS
360 exit(1);
361 }
362
ef416fc2 363 for (plane = 1; plane < NumPlanes; plane ++)
364 Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes;
365
366 if (ColorBits > 1)
367 BitBuffer = malloc(ColorBits * ((header->cupsWidth + 7) / 8));
368 else
369 BitBuffer = NULL;
370
371 if (header->cupsCompression)
372 CompBuffer = malloc(header->cupsBytesPerLine * 2);
373 else
374 CompBuffer = NULL;
375}
376
377
378/*
379 * 'EndPage()' - Finish a page of graphics.
380 */
381
382void
383EndPage(void)
384{
ef416fc2 385 /*
386 * Eject the current page...
387 */
388
389 if (NumPlanes > 1)
390 {
391 printf("\033*rC"); /* End color GFX */
392
393 if (!(Duplex && (Page & 1)))
394 printf("\033&l0H"); /* Eject current page */
395 }
396 else
397 {
398 printf("\033*r0B"); /* End GFX */
399
400 if (!(Duplex && (Page & 1)))
401 printf("\014"); /* Eject current page */
402 }
403
404 fflush(stdout);
405
ef416fc2 406 /*
407 * Free memory...
408 */
409
410 free(Planes[0]);
411
412 if (BitBuffer)
413 free(BitBuffer);
414
415 if (CompBuffer)
416 free(CompBuffer);
417}
418
419
420/*
421 * 'Shutdown()' - Shutdown the printer.
422 */
423
424void
425Shutdown(void)
426{
427 /*
428 * Send a PCL reset sequence.
429 */
430
431 putchar(0x1b);
432 putchar('E');
433}
434
435
436/*
437 * 'CancelJob()' - Cancel the current job...
438 */
439
440void
441CancelJob(int sig) /* I - Signal */
442{
ef416fc2 443 (void)sig;
444
839a51c8 445 Canceled = 1;
ef416fc2 446}
447
448
449/*
450 * 'CompressData()' - Compress a line of graphics.
451 */
452
453void
454CompressData(unsigned char *line, /* I - Data to compress */
7e86f2f6
MS
455 unsigned length, /* I - Number of bytes */
456 unsigned plane, /* I - Color plane */
457 unsigned type) /* I - Type of compression */
ef416fc2 458{
459 unsigned char *line_ptr, /* Current byte pointer */
460 *line_end, /* End-of-line byte pointer */
461 *comp_ptr, /* Pointer into compression buffer */
462 *start; /* Start of compression sequence */
7e86f2f6 463 unsigned count; /* Count of bytes for output */
ef416fc2 464
465
466 switch (type)
467 {
468 default :
469 /*
470 * Do no compression...
471 */
472
473 line_ptr = line;
474 line_end = line + length;
475 break;
476
477 case 1 :
478 /*
479 * Do run-length encoding...
480 */
481
482 line_end = line + length;
483 for (line_ptr = line, comp_ptr = CompBuffer;
484 line_ptr < line_end;
485 comp_ptr += 2, line_ptr += count)
486 {
487 for (count = 1;
488 (line_ptr + count) < line_end &&
489 line_ptr[0] == line_ptr[count] &&
490 count < 256;
491 count ++);
492
7e86f2f6 493 comp_ptr[0] = (unsigned char)(count - 1);
ef416fc2 494 comp_ptr[1] = line_ptr[0];
495 }
496
497 line_ptr = CompBuffer;
498 line_end = comp_ptr;
499 break;
500
501 case 2 :
502 /*
503 * Do TIFF pack-bits encoding...
504 */
505
506 line_ptr = line;
507 line_end = line + length;
508 comp_ptr = CompBuffer;
509
510 while (line_ptr < line_end)
511 {
512 if ((line_ptr + 1) >= line_end)
513 {
514 /*
515 * Single byte on the end...
516 */
517
518 *comp_ptr++ = 0x00;
519 *comp_ptr++ = *line_ptr++;
520 }
521 else if (line_ptr[0] == line_ptr[1])
522 {
523 /*
524 * Repeated sequence...
525 */
526
527 line_ptr ++;
528 count = 2;
529
530 while (line_ptr < (line_end - 1) &&
531 line_ptr[0] == line_ptr[1] &&
532 count < 127)
533 {
534 line_ptr ++;
535 count ++;
536 }
537
7e86f2f6 538 *comp_ptr++ = (unsigned char)(257 - count);
ef416fc2 539 *comp_ptr++ = *line_ptr++;
540 }
541 else
542 {
543 /*
544 * Non-repeated sequence...
545 */
546
547 start = line_ptr;
548 line_ptr ++;
549 count = 1;
550
551 while (line_ptr < (line_end - 1) &&
552 line_ptr[0] != line_ptr[1] &&
553 count < 127)
554 {
555 line_ptr ++;
556 count ++;
557 }
558
7e86f2f6 559 *comp_ptr++ = (unsigned char)(count - 1);
ef416fc2 560
561 memcpy(comp_ptr, start, count);
562 comp_ptr += count;
563 }
564 }
565
566 line_ptr = CompBuffer;
567 line_end = comp_ptr;
568 break;
569 }
570
571 /*
572 * Set the length of the data and write a raster plane...
573 */
574
575 printf("\033*b%d%c", (int)(line_end - line_ptr), plane);
7e86f2f6 576 fwrite(line_ptr, (size_t)(line_end - line_ptr), 1, stdout);
ef416fc2 577}
578
579
580/*
581 * 'OutputLine()' - Output a line of graphics.
582 */
583
584void
839a51c8 585OutputLine(cups_page_header2_t *header) /* I - Page header */
ef416fc2 586{
7e86f2f6 587 unsigned plane, /* Current plane */
ef416fc2 588 bytes, /* Bytes to write */
589 count; /* Bytes to convert */
590 unsigned char bit, /* Current plane data */
591 bit0, /* Current low bit data */
592 bit1, /* Current high bit data */
593 *plane_ptr, /* Pointer into Planes */
594 *bit_ptr; /* Pointer into BitBuffer */
595
596
597 /*
598 * Output whitespace as needed...
599 */
600
601 if (Feed > 0)
602 {
603 printf("\033*b%dY", Feed);
604 Feed = 0;
605 }
606
607 /*
608 * Write bitmap data as needed...
609 */
610
611 bytes = (header->cupsWidth + 7) / 8;
612
613 for (plane = 0; plane < NumPlanes; plane ++)
614 if (ColorBits == 1)
615 {
616 /*
617 * Send bits as-is...
618 */
619
620 CompressData(Planes[plane], bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
621 header->cupsCompression);
622 }
623 else
624 {
625 /*
626 * Separate low and high bit data into separate buffers.
627 */
628
629 for (count = header->cupsBytesPerLine / NumPlanes,
630 plane_ptr = Planes[plane], bit_ptr = BitBuffer;
631 count > 0;
632 count -= 2, plane_ptr += 2, bit_ptr ++)
633 {
634 bit = plane_ptr[0];
635
7e86f2f6
MS
636 bit0 = (unsigned char)(((bit & 64) << 1) | ((bit & 16) << 2) | ((bit & 4) << 3) | ((bit & 1) << 4));
637 bit1 = (unsigned char)((bit & 128) | ((bit & 32) << 1) | ((bit & 8) << 2) | ((bit & 2) << 3));
ef416fc2 638
639 if (count > 1)
640 {
641 bit = plane_ptr[1];
642
7e86f2f6
MS
643 bit0 |= (unsigned char)((bit & 1) | ((bit & 4) >> 1) | ((bit & 16) >> 2) | ((bit & 64) >> 3));
644 bit1 |= (unsigned char)(((bit & 2) >> 1) | ((bit & 8) >> 2) | ((bit & 32) >> 3) | ((bit & 128) >> 4));
ef416fc2 645 }
646
647 bit_ptr[0] = bit0;
648 bit_ptr[bytes] = bit1;
649 }
650
651 /*
652 * Send low and high bits...
653 */
654
655 CompressData(BitBuffer, bytes, 'V', header->cupsCompression);
656 CompressData(BitBuffer + bytes, bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
657 header->cupsCompression);
658 }
659
660 fflush(stdout);
661}
662
663
664/*
665 * 'main()' - Main entry and processing of driver.
666 */
667
839a51c8
MS
668int /* O - Exit status */
669main(int argc, /* I - Number of command-line arguments */
670 char *argv[]) /* I - Command-line arguments */
ef416fc2 671{
839a51c8
MS
672 int fd; /* File descriptor */
673 cups_raster_t *ras; /* Raster stream for printing */
674 cups_page_header2_t header; /* Page header from file */
7e86f2f6 675 unsigned y; /* Current line */
839a51c8
MS
676 ppd_file_t *ppd; /* PPD file */
677#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
678 struct sigaction action; /* Actions for POSIX signals */
679#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
ef416fc2 680
681
682 /*
683 * Make sure status messages are not buffered...
684 */
685
686 setbuf(stderr, NULL);
687
688 /*
689 * Check command-line...
690 */
691
692 if (argc < 6 || argc > 7)
693 {
694 /*
695 * We don't have the correct number of arguments; write an error message
696 * and return.
697 */
698
0837b7e8
MS
699 _cupsLangPrintFilter(stderr, "ERROR",
700 _("%s job-id user title copies options [file]"),
701 "rastertohp");
ef416fc2 702 return (1);
703 }
704
705 /*
706 * Open the page stream...
707 */
708
709 if (argc == 7)
710 {
711 if ((fd = open(argv[6], O_RDONLY)) == -1)
712 {
0837b7e8 713 _cupsLangPrintError("ERROR", _("Unable to open raster file"));
ef416fc2 714 sleep(1);
715 return (1);
716 }
717 }
718 else
719 fd = 0;
720
721 ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
722
839a51c8
MS
723 /*
724 * Register a signal handler to eject the current page if the
725 * job is cancelled.
726 */
727
728 Canceled = 0;
729
730#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
731 sigset(SIGTERM, CancelJob);
732#elif defined(HAVE_SIGACTION)
733 memset(&action, 0, sizeof(action));
734
735 sigemptyset(&action.sa_mask);
736 action.sa_handler = CancelJob;
737 sigaction(SIGTERM, &action, NULL);
738#else
739 signal(SIGTERM, CancelJob);
740#endif /* HAVE_SIGSET */
741
ef416fc2 742 /*
743 * Initialize the print device...
744 */
745
746 ppd = ppdOpenFile(getenv("PPD"));
c7017ecc
MS
747 if (!ppd)
748 {
749 ppd_status_t status; /* PPD error */
750 int linenum; /* Line number */
751
0837b7e8
MS
752 _cupsLangPrintFilter(stderr, "ERROR",
753 _("The PPD file could not be opened."));
c7017ecc
MS
754
755 status = ppdLastError(&linenum);
756
757 fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
758
759 return (1);
760 }
ef416fc2 761
762 Setup();
763
764 /*
765 * Process pages as needed...
766 */
767
768 Page = 0;
769
839a51c8 770 while (cupsRasterReadHeader2(ras, &header))
ef416fc2 771 {
772 /*
773 * Write a status message with the page number and number of copies.
774 */
775
839a51c8
MS
776 if (Canceled)
777 break;
778
ef416fc2 779 Page ++;
780
781 fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
0837b7e8 782 _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), Page);
ef416fc2 783
784 /*
785 * Start the page...
786 */
787
788 StartPage(ppd, &header);
789
790 /*
791 * Loop for each line on the page...
792 */
793
794 for (y = 0; y < header.cupsHeight; y ++)
795 {
796 /*
797 * Let the user know how far we have progressed...
798 */
799
839a51c8
MS
800 if (Canceled)
801 break;
802
ef416fc2 803 if ((y & 127) == 0)
0837b7e8
MS
804 {
805 _cupsLangPrintFilter(stderr, "INFO",
7e86f2f6 806 _("Printing page %d, %u%% complete."),
0837b7e8 807 Page, 100 * y / header.cupsHeight);
7e86f2f6 808 fprintf(stderr, "ATTR: job-media-progress=%u\n",
0837b7e8
MS
809 100 * y / header.cupsHeight);
810 }
ef416fc2 811
812 /*
813 * Read a line of graphics...
814 */
815
816 if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1)
817 break;
818
819 /*
820 * See if the line is blank; if not, write it to the printer...
821 */
822
823 if (Planes[0][0] ||
824 memcmp(Planes[0], Planes[0] + 1, header.cupsBytesPerLine - 1))
825 OutputLine(&header);
826 else
827 Feed ++;
828 }
829
830 /*
831 * Eject the page...
832 */
833
0837b7e8
MS
834 _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), Page);
835
ef416fc2 836 EndPage();
839a51c8
MS
837
838 if (Canceled)
839 break;
ef416fc2 840 }
841
842 /*
843 * Shutdown the printer...
844 */
845
846 Shutdown();
847
848 if (ppd)
849 ppdClose(ppd);
850
851 /*
852 * Close the raster stream...
853 */
854
855 cupsRasterClose(ras);
856 if (fd != 0)
857 close(fd);
858
859 /*
860 * If no pages were printed, send an error message...
861 */
862
863 if (Page == 0)
f0ab5bff 864 {
0837b7e8 865 _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found."));
f0ab5bff
MS
866 return (1);
867 }
ef416fc2 868 else
f0ab5bff 869 return (0);
ef416fc2 870}
871
872
873/*
f2d18633 874 * End of "$Id$".
ef416fc2 875 */