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