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