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