]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/rastertoepson.c
Merge changes from CUPS 1.4svn-r7696.
[thirdparty/cups.git] / filter / rastertoepson.c
1 /*
2 * "$Id: rastertoepson.c 7450 2008-04-14 19:39:02Z mike $"
3 *
4 * EPSON ESC/P and ESC/P2 filter for the Common UNIX Printing System
5 * (CUPS).
6 *
7 * Copyright 2007-2008 by Apple Inc.
8 * Copyright 1993-2007 by Easy Software Products.
9 *
10 * These coded instructions, statements, and computer programs are the
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/".
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 * 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>
34 #include <cups/ppd.h>
35 #include <cups/string.h>
36 #include <cups/i18n.h>
37 #include <cups/raster.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <signal.h>
42
43
44 /*
45 * Model numbers...
46 */
47
48 #define EPSON_9PIN 0
49 #define EPSON_24PIN 1
50 #define EPSON_COLOR 2
51 #define EPSON_PHOTO 3
52 #define EPSON_ICOLOR 4
53 #define EPSON_IPHOTO 5
54
55
56 /*
57 * Macros...
58 */
59
60 #define pwrite(s,n) fwrite((s), 1, (n), stdout)
61
62
63 /*
64 * Globals...
65 */
66
67 unsigned char *Planes[6], /* Output buffers */
68 *CompBuffer, /* Compression buffer */
69 *LineBuffers[2]; /* Line bitmap buffers */
70 int Model, /* Model number */
71 NumPlanes, /* Number of color planes */
72 Feed, /* Number of lines to skip */
73 EjectPage; /* Eject the page when done? */
74 int DotBit, /* Bit in buffers */
75 DotBytes, /* # bytes in a dot column */
76 DotColumns, /* # columns in 1/60 inch */
77 LineCount, /* # of lines processed */
78 EvenOffset, /* Offset into 'even' buffers */
79 OddOffset, /* Offset into 'odd' buffers */
80 Shingling, /* Shingle output? */
81 Canceled; /* Has the current job been canceled? */
82
83
84 /*
85 * Prototypes...
86 */
87
88 void Setup(void);
89 void StartPage(const ppd_file_t *ppd, const cups_page_header2_t *header);
90 void EndPage(const cups_page_header2_t *header);
91 void Shutdown(void);
92
93 void CancelJob(int sig);
94 void CompressData(const unsigned char *line, int length, int plane,
95 int type, int xstep, int ystep);
96 void OutputLine(const cups_page_header2_t *header);
97 void OutputRows(const cups_page_header2_t *header, int row);
98
99
100 /*
101 * 'Setup()' - Prepare the printer for printing.
102 */
103
104 void
105 Setup(void)
106 {
107 const char *device_uri; /* The device for the printer... */
108
109
110 /*
111 * EPSON USB printers need an additional command issued at the
112 * beginning of each job to exit from "packet" mode...
113 */
114
115 if ((device_uri = getenv("DEVICE_URI")) != NULL &&
116 strncmp(device_uri, "usb:", 4) == 0 && Model >= EPSON_ICOLOR)
117 pwrite("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29);
118 }
119
120
121 /*
122 * 'StartPage()' - Start a page of graphics.
123 */
124
125 void
126 StartPage(const ppd_file_t *ppd, /* I - PPD file */
127 const cups_page_header2_t *header) /* I - Page header */
128 {
129 int n, t; /* Numbers */
130 int plane; /* Looping var */
131
132
133 /*
134 * Send a reset sequence.
135 */
136
137 if (ppd && ppd->nickname && strstr(ppd->nickname, "OKIDATA") != NULL)
138 printf("\033{A"); /* Set EPSON emulation mode */
139
140 printf("\033@");
141
142 /*
143 * See which type of printer we are using...
144 */
145
146 EjectPage = header->Margins[0] || header->Margins[1];
147
148 switch (Model)
149 {
150 case EPSON_9PIN :
151 case EPSON_24PIN :
152 printf("\033P\022"); /* Set 10 CPI */
153
154 if (header->HWResolution[0] == 360 || header->HWResolution[0] == 240)
155 {
156 printf("\033x1"); /* LQ printing */
157 printf("\033U1"); /* Unidirectional */
158 }
159 else
160 {
161 printf("\033x0"); /* Draft printing */
162 printf("\033U0"); /* Bidirectional */
163 }
164
165 printf("\033l%c\033Q%c", 0, /* Side margins */
166 (int)(10.0 * header->PageSize[0] / 72.0 + 0.5));
167 printf("\033C%c%c", 0, /* Page length */
168 (int)(header->PageSize[1] / 72.0 + 0.5));
169 printf("\033N%c", 0); /* Bottom margin */
170 printf("\033O"); /* No perforation skip */
171
172 /*
173 * Setup various buffer limits...
174 */
175
176 DotBytes = header->cupsRowCount / 8;
177 DotColumns = header->HWResolution[0] / 60;
178 Shingling = 0;
179
180 if (Model == EPSON_9PIN)
181 printf("\033\063\030"); /* Set line feed */
182 else
183 switch (header->HWResolution[0])
184 {
185 case 60:
186 case 120 :
187 case 240 :
188 printf("\033\063\030"); /* Set line feed */
189 break;
190
191 case 180 :
192 case 360 :
193 Shingling = 1;
194
195 if (header->HWResolution[1] == 180)
196 printf("\033\063\010");/* Set line feed */
197 else
198 printf("\033+\010"); /* Set line feed */
199 break;
200 }
201 break;
202
203 default :
204 /*
205 * Set graphics mode...
206 */
207
208 pwrite("\033(G\001\000\001", 6); /* Graphics mode */
209
210 /*
211 * Set the media size...
212 */
213
214 if (Model < EPSON_ICOLOR)
215 {
216 pwrite("\033(U\001\000", 5); /* Resolution/units */
217 putchar(3600 / header->HWResolution[1]);
218 }
219 else
220 {
221 pwrite("\033(U\005\000", 5);
222 putchar(1440 / header->HWResolution[1]);
223 putchar(1440 / header->HWResolution[1]);
224 putchar(1440 / header->HWResolution[0]);
225 putchar(0xa0); /* n/1440ths... */
226 putchar(0x05);
227 }
228
229 n = header->PageSize[1] * header->HWResolution[1] / 72.0;
230
231 pwrite("\033(C\002\000", 5); /* Page length */
232 putchar(n);
233 putchar(n >> 8);
234
235 if (ppd)
236 t = (ppd->sizes[1].length - ppd->sizes[1].top) *
237 header->HWResolution[1] / 72.0;
238 else
239 t = 0;
240
241 pwrite("\033(c\004\000", 5); /* Top & bottom margins */
242 putchar(t);
243 putchar(t >> 8);
244 putchar(n);
245 putchar(n >> 8);
246
247 if (header->HWResolution[1] == 720)
248 {
249 pwrite("\033(i\001\000\001", 6); /* Microweave */
250 pwrite("\033(e\002\000\000\001", 7); /* Small dots */
251 }
252
253 pwrite("\033(V\002\000\000\000", 7); /* Set absolute position 0 */
254
255 DotBytes = 0;
256 DotColumns = 0;
257 Shingling = 0;
258 break;
259 }
260
261 /*
262 * Set other stuff...
263 */
264
265 if (header->cupsColorSpace == CUPS_CSPACE_CMY)
266 NumPlanes = 3;
267 else if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
268 NumPlanes = 4;
269 else if (header->cupsColorSpace == CUPS_CSPACE_KCMYcm)
270 NumPlanes = 6;
271 else
272 NumPlanes = 1;
273
274 Feed = 0; /* No blank lines yet */
275
276 /*
277 * Allocate memory for a line/row of graphics...
278 */
279
280 if ((Planes[0] = malloc(header->cupsBytesPerLine)) == NULL)
281 {
282 fputs("ERROR: Unable to allocate memory!\n", stderr);
283 exit(1);
284 }
285
286 for (plane = 1; plane < NumPlanes; plane ++)
287 Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes;
288
289 if (header->cupsCompression || DotBytes)
290 {
291 if ((CompBuffer = calloc(2, header->cupsWidth)) == NULL)
292 {
293 fputs("ERROR: Unable to allocate memory!\n", stderr);
294 exit(1);
295 }
296 }
297 else
298 CompBuffer = NULL;
299
300 if (DotBytes)
301 {
302 if ((LineBuffers[0] = calloc(DotBytes,
303 header->cupsWidth * (Shingling + 1))) == NULL)
304 {
305 fputs("ERROR: Unable to allocate memory!\n", stderr);
306 exit(1);
307 }
308
309 LineBuffers[1] = LineBuffers[0] + DotBytes * header->cupsWidth;
310 DotBit = 128;
311 LineCount = 0;
312 EvenOffset = 0;
313 OddOffset = 0;
314 }
315 }
316
317
318 /*
319 * 'EndPage()' - Finish a page of graphics.
320 */
321
322 void
323 EndPage(const cups_page_header2_t *header) /* I - Page header */
324 {
325 if (DotBytes && header)
326 {
327 /*
328 * Flush remaining graphics as needed...
329 */
330
331 if (!Shingling)
332 {
333 if (DotBit < 128 || EvenOffset)
334 OutputRows(header, 0);
335 }
336 else if (OddOffset > EvenOffset)
337 {
338 OutputRows(header, 1);
339 OutputRows(header, 0);
340 }
341 else
342 {
343 OutputRows(header, 0);
344 OutputRows(header, 1);
345 }
346 }
347
348 /*
349 * Eject the current page...
350 */
351
352 if (EjectPage)
353 putchar(12); /* Form feed */
354 fflush(stdout);
355
356 /*
357 * Free memory...
358 */
359
360 free(Planes[0]);
361
362 if (CompBuffer)
363 free(CompBuffer);
364
365 if (DotBytes)
366 free(LineBuffers[0]);
367 }
368
369
370 /*
371 * 'Shutdown()' - Shutdown the printer.
372 */
373
374 void
375 Shutdown(void)
376 {
377 /*
378 * Send a reset sequence.
379 */
380
381 printf("\033@");
382 }
383
384
385 /*
386 * 'CancelJob()' - Cancel the current job...
387 */
388
389 void
390 CancelJob(int sig) /* I - Signal */
391 {
392 (void)sig;
393
394 Canceled = 1;
395 }
396
397
398 /*
399 * 'CompressData()' - Compress a line of graphics.
400 */
401
402 void
403 CompressData(const unsigned char *line, /* I - Data to compress */
404 int length,/* I - Number of bytes */
405 int plane, /* I - Color plane */
406 int type, /* I - Type of compression */
407 int xstep, /* I - X resolution */
408 int ystep) /* I - Y resolution */
409 {
410 const unsigned char *line_ptr, /* Current byte pointer */
411 *line_end, /* End-of-line byte pointer */
412 *start; /* Start of compression sequence */
413 unsigned char *comp_ptr, /* Pointer into compression buffer */
414 temp; /* Current byte */
415 int count; /* Count of bytes for output */
416 static int ctable[6] = { 0, 2, 1, 4, 18, 17 };
417 /* KCMYcm color values */
418
419
420 /*
421 * Setup pointers...
422 */
423
424 line_ptr = line;
425 line_end = line + length;
426
427 /*
428 * Do depletion for 720 DPI printing...
429 */
430
431 if (ystep == 5)
432 {
433 for (comp_ptr = (unsigned char *)line; comp_ptr < line_end;)
434 {
435 /*
436 * Grab the current byte...
437 */
438
439 temp = *comp_ptr;
440
441 /*
442 * Check adjacent bits...
443 */
444
445 if ((temp & 0xc0) == 0xc0)
446 temp &= 0xbf;
447 if ((temp & 0x60) == 0x60)
448 temp &= 0xdf;
449 if ((temp & 0x30) == 0x30)
450 temp &= 0xef;
451 if ((temp & 0x18) == 0x18)
452 temp &= 0xf7;
453 if ((temp & 0x0c) == 0x0c)
454 temp &= 0xfb;
455 if ((temp & 0x06) == 0x06)
456 temp &= 0xfd;
457 if ((temp & 0x03) == 0x03)
458 temp &= 0xfe;
459
460 *comp_ptr++ = temp;
461
462 /*
463 * Check the last bit in the current byte and the first bit in the
464 * next byte...
465 */
466
467 if ((temp & 0x01) && comp_ptr < line_end && *comp_ptr & 0x80)
468 *comp_ptr &= 0x7f;
469 }
470 }
471
472 switch (type)
473 {
474 case 0 :
475 /*
476 * Do no compression...
477 */
478 break;
479
480 case 1 :
481 /*
482 * Do TIFF pack-bits encoding...
483 */
484
485 comp_ptr = CompBuffer;
486
487 while (line_ptr < line_end)
488 {
489 if ((line_ptr + 1) >= line_end)
490 {
491 /*
492 * Single byte on the end...
493 */
494
495 *comp_ptr++ = 0x00;
496 *comp_ptr++ = *line_ptr++;
497 }
498 else if (line_ptr[0] == line_ptr[1])
499 {
500 /*
501 * Repeated sequence...
502 */
503
504 line_ptr ++;
505 count = 2;
506
507 while (line_ptr < (line_end - 1) &&
508 line_ptr[0] == line_ptr[1] &&
509 count < 127)
510 {
511 line_ptr ++;
512 count ++;
513 }
514
515 *comp_ptr++ = 257 - count;
516 *comp_ptr++ = *line_ptr++;
517 }
518 else
519 {
520 /*
521 * Non-repeated sequence...
522 */
523
524 start = line_ptr;
525 line_ptr ++;
526 count = 1;
527
528 while (line_ptr < (line_end - 1) &&
529 line_ptr[0] != line_ptr[1] &&
530 count < 127)
531 {
532 line_ptr ++;
533 count ++;
534 }
535
536 *comp_ptr++ = count - 1;
537
538 memcpy(comp_ptr, start, count);
539 comp_ptr += count;
540 }
541 }
542
543 line_ptr = CompBuffer;
544 line_end = comp_ptr;
545 break;
546 }
547
548 putchar(0x0d); /* Move print head to left margin */
549
550 if (Model < EPSON_ICOLOR)
551 {
552 /*
553 * Do graphics the "old" way...
554 */
555
556 if (NumPlanes > 1)
557 {
558 /*
559 * Set the color...
560 */
561
562 if (plane > 3)
563 printf("\033(r%c%c%c%c", 2, 0, 1, ctable[plane] & 15);
564 /* Set extended color */
565 else if (NumPlanes == 3)
566 printf("\033r%c", ctable[plane + 1]);
567 /* Set color */
568 else
569 printf("\033r%c", ctable[plane]); /* Set color */
570 }
571
572 /*
573 * Send a raster plane...
574 */
575
576 length *= 8;
577 printf("\033."); /* Raster graphics */
578 putchar(type);
579 putchar(ystep);
580 putchar(xstep);
581 putchar(1);
582 putchar(length);
583 putchar(length >> 8);
584 }
585 else
586 {
587 /*
588 * Do graphics the "new" way...
589 */
590
591 printf("\033i");
592 putchar(ctable[plane]);
593 putchar(type);
594 putchar(1);
595 putchar(length & 255);
596 putchar(length >> 8);
597 putchar(1);
598 putchar(0);
599 }
600
601 pwrite(line_ptr, line_end - line_ptr);
602 fflush(stdout);
603 }
604
605
606 /*
607 * 'OutputLine()' - Output a line of graphics.
608 */
609
610 void
611 OutputLine(const cups_page_header2_t *header) /* I - Page header */
612 {
613 if (header->cupsRowCount)
614 {
615 int width;
616 unsigned char *tempptr,
617 *evenptr,
618 *oddptr;
619 register int x;
620 unsigned char bit;
621 const unsigned char *pixel;
622 unsigned char *temp;
623
624
625 /*
626 * Collect bitmap data in the line buffers and write after each buffer.
627 */
628
629 for (x = header->cupsWidth, bit = 128, pixel = Planes[0],
630 temp = CompBuffer;
631 x > 0;
632 x --, temp ++)
633 {
634 if (*pixel & bit)
635 *temp |= DotBit;
636
637 if (bit > 1)
638 bit >>= 1;
639 else
640 {
641 bit = 128;
642 pixel ++;
643 }
644 }
645
646 if (DotBit > 1)
647 DotBit >>= 1;
648 else
649 {
650 /*
651 * Copy the holding buffer to the output buffer, shingling as necessary...
652 */
653
654 if (Shingling && LineCount != 0)
655 {
656 /*
657 * Shingle the output...
658 */
659
660 if (LineCount & 1)
661 {
662 evenptr = LineBuffers[1] + OddOffset;
663 oddptr = LineBuffers[0] + EvenOffset + DotBytes;
664 }
665 else
666 {
667 evenptr = LineBuffers[0] + EvenOffset;
668 oddptr = LineBuffers[1] + OddOffset + DotBytes;
669 }
670
671 for (width = header->cupsWidth, tempptr = CompBuffer;
672 width > 0;
673 width -= 2, tempptr += 2, oddptr += DotBytes * 2,
674 evenptr += DotBytes * 2)
675 {
676 evenptr[0] = tempptr[0];
677 oddptr[0] = tempptr[1];
678 }
679 }
680 else
681 {
682 /*
683 * Don't shingle the output...
684 */
685
686 for (width = header->cupsWidth, tempptr = CompBuffer,
687 evenptr = LineBuffers[0] + EvenOffset;
688 width > 0;
689 width --, tempptr ++, evenptr += DotBytes)
690 *evenptr = tempptr[0];
691 }
692
693 if (Shingling && LineCount != 0)
694 {
695 EvenOffset ++;
696 OddOffset ++;
697
698 if (EvenOffset == DotBytes)
699 {
700 EvenOffset = 0;
701 OutputRows(header, 0);
702 }
703
704 if (OddOffset == DotBytes)
705 {
706 OddOffset = 0;
707 OutputRows(header, 1);
708 }
709 }
710 else
711 {
712 EvenOffset ++;
713
714 if (EvenOffset == DotBytes)
715 {
716 EvenOffset = 0;
717 OutputRows(header, 0);
718 }
719 }
720
721 DotBit = 128;
722 LineCount ++;
723
724 memset(CompBuffer, 0, header->cupsWidth);
725 }
726 }
727 else
728 {
729 int plane; /* Current plane */
730 int bytes; /* Bytes per plane */
731 int xstep, ystep; /* X & Y resolutions */
732
733
734 /*
735 * Write a single line of bitmap data as needed...
736 */
737
738 xstep = 3600 / header->HWResolution[0];
739 ystep = 3600 / header->HWResolution[1];
740 bytes = header->cupsBytesPerLine / NumPlanes;
741
742 for (plane = 0; plane < NumPlanes; plane ++)
743 {
744 /*
745 * Skip blank data...
746 */
747
748 if (!Planes[plane][0] &&
749 memcmp(Planes[plane], Planes[plane] + 1, bytes - 1) == 0)
750 continue;
751
752 /*
753 * Output whitespace as needed...
754 */
755
756 if (Feed > 0)
757 {
758 pwrite("\033(v\002\000", 5); /* Relative vertical position */
759 putchar(Feed);
760 putchar(Feed >> 8);
761
762 Feed = 0;
763 }
764
765 CompressData(Planes[plane], bytes, plane, header->cupsCompression, xstep,
766 ystep);
767 }
768
769 Feed ++;
770 }
771 }
772
773
774 /*
775 * 'OutputRows()' - Output 8, 24, or 48 rows.
776 */
777
778 void
779 OutputRows(const cups_page_header2_t *header, /* I - Page image header */
780 int row) /* I - Row number (0 or 1) */
781 {
782 unsigned i, n; /* Looping vars */
783 int dot_count, /* Number of bytes to print */
784 dot_min; /* Minimum number of bytes */
785 unsigned char *dot_ptr, /* Pointer to print data */
786 *ptr; /* Current data */
787
788
789 dot_min = DotBytes * DotColumns;
790
791 if (LineBuffers[row][0] != 0 ||
792 memcmp(LineBuffers[row], LineBuffers[row] + 1,
793 header->cupsWidth * DotBytes - 1))
794 {
795 /*
796 * Skip leading space...
797 */
798
799 i = 0;
800 dot_count = header->cupsWidth * DotBytes;
801 dot_ptr = LineBuffers[row];
802
803 while (dot_count >= dot_min && dot_ptr[0] == 0 &&
804 memcmp(dot_ptr, dot_ptr + 1, dot_min - 1) == 0)
805 {
806 i ++;
807 dot_ptr += dot_min;
808 dot_count -= dot_min;
809 }
810
811 /*
812 * Skip trailing space...
813 */
814
815 while (dot_count >= dot_min && dot_ptr[dot_count - dot_min] == 0 &&
816 memcmp(dot_ptr + dot_count - dot_min,
817 dot_ptr + dot_count - dot_min + 1, dot_min - 1) == 0)
818 dot_count -= dot_min;
819
820 /*
821 * Position print head for printing...
822 */
823
824 if (i == 0)
825 putchar('\r');
826 else
827 {
828 putchar(0x1b);
829 putchar('$');
830 putchar(i & 255);
831 putchar(i >> 8);
832 }
833
834 /*
835 * Start bitmap graphics for this line...
836 */
837
838 printf("\033*"); /* Select bit image */
839 switch (header->HWResolution[0])
840 {
841 case 60 : /* 60x60/72 DPI gfx */
842 putchar(0);
843 break;
844 case 120 : /* 120x60/72 DPI gfx */
845 putchar(1);
846 break;
847 case 180 : /* 180 DPI gfx */
848 putchar(39);
849 break;
850 case 240 : /* 240x72 DPI gfx */
851 putchar(3);
852 break;
853 case 360 : /* 360x180/360 DPI gfx */
854 if (header->HWResolution[1] == 180)
855 {
856 if (Shingling && LineCount != 0)
857 putchar(40); /* 360x180 fast */
858 else
859 putchar(41); /* 360x180 slow */
860 }
861 else
862 {
863 if (Shingling && LineCount != 0)
864 putchar(72); /* 360x360 fast */
865 else
866 putchar(73); /* 360x360 slow */
867 }
868 break;
869 }
870
871 n = (unsigned)dot_count / DotBytes;
872 putchar(n & 255);
873 putchar(n / 256);
874
875 /*
876 * Write the graphics data...
877 */
878
879 if (header->HWResolution[0] == 120 ||
880 header->HWResolution[0] == 240)
881 {
882 /*
883 * Need to interleave the dots to avoid hosing the print head...
884 */
885
886 for (n = dot_count / 2, ptr = dot_ptr; n > 0; n --, ptr += 2)
887 {
888 putchar(*ptr);
889 putchar(0);
890 }
891
892 /*
893 * Move the head back and print the odd bytes...
894 */
895
896 if (i == 0)
897 putchar('\r');
898 else
899 {
900 putchar(0x1b);
901 putchar('$');
902 putchar(i & 255);
903 putchar(i >> 8);
904 }
905
906 if (header->HWResolution[0] == 120)
907 printf("\033*\001"); /* Select bit image */
908 else
909 printf("\033*\003"); /* Select bit image */
910
911 n = (unsigned)dot_count / DotBytes;
912 putchar(n & 255);
913 putchar(n / 256);
914
915 for (n = dot_count / 2, ptr = dot_ptr + 1; n > 0; n --, ptr += 2)
916 {
917 putchar(0);
918 putchar(*ptr);
919 }
920 }
921 else
922 pwrite(dot_ptr, dot_count);
923 }
924
925 /*
926 * Feed the paper...
927 */
928
929 putchar('\n');
930
931 if (Shingling && row == 1)
932 {
933 if (header->HWResolution[1] == 360)
934 printf("\n\n\n\n");
935 else
936 printf("\n");
937 }
938
939 fflush(stdout);
940
941 /*
942 * Clear the buffer...
943 */
944
945 memset(LineBuffers[row], 0, header->cupsWidth * DotBytes);
946 }
947
948
949 /*
950 * 'main()' - Main entry and processing of driver.
951 */
952
953 int /* O - Exit status */
954 main(int argc, /* I - Number of command-line arguments */
955 char *argv[]) /* I - Command-line arguments */
956 {
957 int fd; /* File descriptor */
958 cups_raster_t *ras; /* Raster stream for printing */
959 cups_page_header2_t header; /* Page header from file */
960 ppd_file_t *ppd; /* PPD file */
961 int page; /* Current page */
962 int y; /* Current line */
963 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
964 struct sigaction action; /* Actions for POSIX signals */
965 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
966
967
968 /*
969 * Make sure status messages are not buffered...
970 */
971
972 setbuf(stderr, NULL);
973
974 /*
975 * Check command-line...
976 */
977
978 if (argc < 6 || argc > 7)
979 {
980 /*
981 * We don't have the correct number of arguments; write an error message
982 * and return.
983 */
984
985 fprintf(stderr, _("Usage: %s job-id user title copies options [file]\n"),
986 argv[0]);
987 return (1);
988 }
989
990 /*
991 * Open the page stream...
992 */
993
994 if (argc == 7)
995 {
996 if ((fd = open(argv[6], O_RDONLY)) == -1)
997 {
998 perror("ERROR: Unable to open raster file - ");
999 sleep(1);
1000 return (1);
1001 }
1002 }
1003 else
1004 fd = 0;
1005
1006 ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
1007
1008 /*
1009 * Register a signal handler to eject the current page if the
1010 * job is cancelled.
1011 */
1012
1013 Canceled = 0;
1014
1015 #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
1016 sigset(SIGTERM, CancelJob);
1017 #elif defined(HAVE_SIGACTION)
1018 memset(&action, 0, sizeof(action));
1019
1020 sigemptyset(&action.sa_mask);
1021 action.sa_handler = CancelJob;
1022 sigaction(SIGTERM, &action, NULL);
1023 #else
1024 signal(SIGTERM, CancelJob);
1025 #endif /* HAVE_SIGSET */
1026
1027 /*
1028 * Initialize the print device...
1029 */
1030
1031 ppd = ppdOpenFile(getenv("PPD"));
1032 if (ppd)
1033 Model = ppd->model_number;
1034
1035 Setup();
1036
1037 /*
1038 * Process pages as needed...
1039 */
1040
1041 page = 0;
1042
1043 while (cupsRasterReadHeader2(ras, &header))
1044 {
1045 /*
1046 * Write a status message with the page number and number of copies.
1047 */
1048
1049 if (Canceled)
1050 break;
1051
1052 page ++;
1053
1054 fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
1055
1056 /*
1057 * Start the page...
1058 */
1059
1060 StartPage(ppd, &header);
1061
1062 /*
1063 * Loop for each line on the page...
1064 */
1065
1066 for (y = 0; y < header.cupsHeight; y ++)
1067 {
1068 /*
1069 * Let the user know how far we have progressed...
1070 */
1071
1072 if (Canceled)
1073 break;
1074
1075 if ((y & 127) == 0)
1076 fprintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), page,
1077 100 * y / header.cupsHeight);
1078
1079 /*
1080 * Read a line of graphics...
1081 */
1082
1083 if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1)
1084 break;
1085
1086 /*
1087 * Write it to the printer...
1088 */
1089
1090 OutputLine(&header);
1091 }
1092
1093 /*
1094 * Eject the page...
1095 */
1096
1097 EndPage(&header);
1098
1099 if (Canceled)
1100 break;
1101 }
1102
1103 /*
1104 * Shutdown the printer...
1105 */
1106
1107 Shutdown();
1108
1109 ppdClose(ppd);
1110
1111 /*
1112 * Close the raster stream...
1113 */
1114
1115 cupsRasterClose(ras);
1116 if (fd != 0)
1117 close(fd);
1118
1119 /*
1120 * If no pages were printed, send an error message...
1121 */
1122
1123 if (page == 0)
1124 fputs(_("ERROR: No pages found!\n"), stderr);
1125 else
1126 fputs(_("INFO: Ready to print.\n"), stderr);
1127
1128 return (page == 0);
1129 }
1130
1131
1132 /*
1133 * End of "$Id: rastertoepson.c 7450 2008-04-14 19:39:02Z mike $".
1134 */