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