1 /* Copyright (C) 1998, 1999 Norihito Ohmori.
2 
3    Ghostscript printer driver
4    for Canon LBP and BJ printers (LIPS II+/III/IVc/IV)
5 
6    This software is distributed in the hope that it will be useful, but
7    WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
8    to anyone for the consequences of using it or for whether it serves any
9    particular purpose or works at all, unless he says so in writing.  Refer
10    to the GNU General Public License for full details.
11 
12    Everyone is granted permission to copy, modify and redistribute
13    this software, but only under the conditions described in the GNU
14    General Public License.  A copy of this license is supposed to have been
15    given to you along with this software so you can know your rights and
16    responsibilities.  It should be in a file named COPYING.  Among other
17    things, the copyright notice and this notice must be preserved on all
18    copies.
19  */
20 
21 /*$Id: gdevlips.c $ */
22 /* Common Utility for LIPS driver */
23 
24 #include "gx.h"
25 #include "gdevlips.h"
26 
27 typedef struct {
28     int width;
29     int height;
30     int num_unit;
31 } paper_table;
32 
33 static paper_table lips_paper_table[] =
34 {
35     {842, 1190, 12},		/* A3 */
36     {595, 842, 14},		/* A4 */
37     {597, 842, 14},		/* A4     8.3 inch x 11.7 inch */
38     {421, 595, 16},		/* A5 */
39     {284, 419, 18},		/* PostCard */
40     {729, 1032, 24},		/* JIS B4 */
41     {516, 729, 26},		/* JIS B5 */
42     {363, 516, 28},		/* JIS B6 */
43     {612, 792, 30},		/* Letter */
44     {612, 1008, 32},		/* Legal */
45     {792, 1224, 34},		/* Ledger */
46     {522, 756, 40},		/* Executive */
47     {298, 666, 50},		/* envyou4 */
48     {0, 0, 80},			/* User Size */
49 };
50 
51 int
lips_media_selection(int width,int height)52 lips_media_selection(int width, int height)
53 {
54     int landscape = 0;
55     int tmp;
56     paper_table *pt;
57 
58     if (width > height) {
59 	landscape = 1;
60 	tmp = width;
61 	width = height;
62 	height = tmp;
63     }
64     for (pt = lips_paper_table; pt->num_unit < 80; pt++)
65 /* add by shige 11/06 2003 */
66 #ifdef USE_LIPS_SIZE_ERROR
67 	if(pt->width+LIPS_SIZE_ERROR_VALUE>=width
68 	   && pt->width-LIPS_SIZE_ERROR_VALUE<=width
69 	   && pt->height+LIPS_SIZE_ERROR_VALUE>=height
70 	   && pt->height-LIPS_SIZE_ERROR_VALUE<=height)
71 #else
72 	if (pt->width == width && pt->height == height)
73 #endif
74 	    break;
75 
76     return pt->num_unit + landscape;
77 }
78 
79 private int GetNumSameData(const byte * curPtr, const int maxnum);
80 private int GetNumWrongData(const byte * curPtr, const int maxnum);
81 
82 /* This routine talkes from LipsIVRunLengthEncode in Yoshiharu ITO's patch  */
83 int
lips_packbits_encode(byte * inBuff,byte * outBuff,int Length)84 lips_packbits_encode(byte * inBuff, byte * outBuff, int Length)
85 {
86     int size = 0;
87 
88     while (Length) {
89 	int count;
90 
91 	if (1 < (count = GetNumSameData(inBuff,
92 					Length > 128 ? 128 : Length))) {
93 	    Length -= count;
94 	    size += 2;
95 
96 	    *outBuff++ = -(count - 1);
97 	    *outBuff++ = *inBuff;
98 	    inBuff += count;
99 	} else {
100 	    count = GetNumWrongData(inBuff, Length > 128 ? 128 : Length);
101 	    Length -= count;
102 	    size += count + 1;
103 
104 	    *outBuff++ = count - 1;
105 	    while (count--) {
106 		*outBuff++ = *inBuff++;
107 	    }
108 	}
109     }
110 
111     return (size);
112 }
113 
114 /* LIPS III printer can no use Runlength encode mode
115    but Mode 1-3 Format mode. */
116 /* This routine takes from LipsIIIRunLengthEncode in Yoshiharu ITO's patch  */
117 int
lips_mode3format_encode(byte * inBuff,byte * outBuff,int Length)118 lips_mode3format_encode(byte * inBuff, byte * outBuff, int Length)
119 {
120     int size = 0;
121 
122     while (Length) {
123 	int count;
124 
125 	if (1 < (count = GetNumSameData(inBuff,
126 					Length > 257 ? 257 : Length))) {
127 	    Length -= count;
128 	    size += 3;
129 
130 	    *outBuff++ = *inBuff;
131 	    *outBuff++ = *inBuff;
132 	    *outBuff++ = count - 2;
133 	    inBuff += count;
134 	} else {
135 	    count = GetNumWrongData(inBuff, Length);
136 	    Length -= count;
137 	    size += count;
138 
139 	    while (count--) {
140 		*outBuff++ = *inBuff++;
141 	    }
142 	}
143     }
144 
145     return (size);
146 }
147 
148 private int
GetNumSameData(const byte * curPtr,const int maxnum)149 GetNumSameData(const byte * curPtr, const int maxnum)
150 {
151     int count = 1;
152 
153     if (1 == maxnum) {
154 	return (1);
155     }
156     while (*curPtr == *(curPtr + count) && maxnum > count) {
157 	count++;
158     }
159 
160     return (count);
161 }
162 
163 private int
GetNumWrongData(const byte * curPtr,const int maxnum)164 GetNumWrongData(const byte * curPtr, const int maxnum)
165 {
166     int count = 0;
167 
168     if (1 == maxnum) {
169 	return (1);
170     }
171     while (*(curPtr + count) != *(curPtr + count + 1) && maxnum > count) {
172 	count++;
173     }
174 
175     return (count);
176 }
177 
178 
179 /*
180 
181    This routine takes from gdevlips4-1.1.0.
182 
183  */
184 #define RLECOUNTMAX 0xff	/* 256 times */
185 int
lips_rle_encode(byte * inBuff,byte * outBuff,int Length)186 lips_rle_encode(byte * inBuff, byte * outBuff, int Length)
187 {
188     int i = 0;
189     byte value;
190     int count = 0;
191     byte *ptr = inBuff;
192 
193     value = *ptr;
194     ptr++;
195 
196     while (ptr < inBuff + Length) {
197 	if (*ptr == value) {
198 	    count++;
199 	    if (count > RLECOUNTMAX) {
200 		*outBuff++ = RLECOUNTMAX;
201 		*outBuff++ = value;
202 		i += 2;
203 		count = 0;
204 	    }
205 	} else {
206 	    *outBuff++ = count;
207 	    *outBuff++ = value;
208 	    i += 2;
209 	    count = 0;
210 	    value = *ptr;
211 	}
212 	ptr++;
213     }
214     *outBuff++ = count;
215     *outBuff++ = value;
216     i += 2;
217 
218     return i;
219 }
220