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