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