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