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