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