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