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