1 /*
2 This file is part of GNU Ghostscript.
3
4 GNU Ghostscript is distributed in the hope that it will be useful, but
5 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to
6 anyone for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing. Refer to
8 the GNU General Public License for full details.
9
10 Everyone is granted permission to copy, modify and redistribute GNU
11 Ghostscript, but only under the conditions described in the GNU General
12 Public License. A copy of this license is supposed to have been given to
13 you along with GNU Ghostscript so you can know your rights and
14 responsibilities. It should be in a file named COPYING. Among other
15 things, the copyright notice and this notice must be preserved on all
16 copies.
17
18 Aladdin Enterprises is not affiliated with the Free Software Foundation or
19 the GNU Project. GNU Ghostscript, as distributed by Aladdin Enterprises,
20 does not depend on any other GNU software.
21 */
22
23 /* gdevgdi.c */
24 /* SAMSUNG GDI driver for Ghostscript */
25 #include "gdevprn.h"
26 #include "gdevpcl.h"
27
28 /*
29 * You may select a default resolution of 300 or 600 DPI
30 * in the makefile, or an actual resolution
31 * on the gs command line.
32 *
33 * If the preprocessor symbol A4 is defined, the default paper size is
34 * the European A4 size; otherwise it is the U.S. letter size (8.5"x11").
35 *
36 * To determine the proper "margin" settings for your printer, see the
37 * file align.ps.
38 */
39
40 /* Define the default, maximum resolutions. */
41 #ifdef X_DPI
42 # define X_DPI2 X_DPI
43 #else
44 # define X_DPI 300
45 # define X_DPI2 600
46 #endif
47 #ifdef Y_DPI
48 # define Y_DPI2 Y_DPI
49 #else
50 # define Y_DPI 300
51 # define Y_DPI2 600
52 #endif
53
54 #define GDI_FALSE 0
55 #define GDI_TRUE 1
56 #define GDI_MAX_COUNT 31
57 #define GDI_NO_REPEAT_IDX 0x80000000L
58 #define GDI_DATA_LENGTH 11
59 #define GDI_REPEAT_LENGTH 2
60 #define GDI_BAND_HEIGHT 128
61 #define GDI_MAX_BAND 66
62 /*#define GDI_BAND_WIDTH 4928*/
63 /*#define GDI_BAND_WIDTH_BYTES (((GDI_BAND_WIDTH + 31)/32)*4)*/
64
65 #define GDI_PRE_COMP 2
66 #define GDI_REAL_COMP 0
67
68 #define GDI_COMP_NONE 0
69 #define GDI_COMP_TIFF 3
70 #define GDI_COMP_SCANLINE 4
71 #define GDI_COMP_MODITIFF 6
72 #define GDI_COMP_NOSEND 0x7f
73
74 #define GDI_MARGINS_A4 0.167f, 0.167f, 0.167f, 0.167f
75 #define GDI_MARGINS_LETTER 0.167f, 0.167f, 0.167f, 0.167f
76 /*#define GDI_MARGINS_A4 0.0, 0.0, 0.0, 0.0*/
77 /*#define GDI_MARGINS_LETTER 0.0, 0.0, 0.0, 0.0*/
78
79 /* The number of blank lines that make it worthwhile to reposition */
80 /* the cursor. */
81 #define MIN_SKIP_LINES 7
82
83 /* We round up the LINE_SIZE to a multiple of a unsigned long for faster scanning. */
84 #define W sizeof(word)
85
86 int GDI_BAND_WIDTH[] = {4768, 4928};
87
88 static int gdi_print_page(gx_device_printer *pdev, gp_file *prn_stream);
89 static int gdi_open(gx_device *pdev);
90 static int gdi_close(gx_device *pdev);
91
92 /* The device descriptors */
93 static dev_proc_open_device(gdi_open);
94 static dev_proc_close_device(gdi_close);
95 static dev_proc_print_page(gdi_print_page);
96
97 static gx_device_procs prn_gdi_procs =
98 prn_params_procs(gdi_open, gdev_prn_output_page, gdi_close,
99 gdev_prn_get_params, gdev_prn_put_params);
100
101 gx_device_printer far_data gs_gdi_device =
102 prn_device(prn_gdi_procs, "gdi",
103 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, /* paper size (unit : 10/72 inch size) */
104 X_DPI2, Y_DPI2,
105 0.20, 0.25, 0.25, 0.25, /* margins filled in by gdi_open */
106 1, /* color bit */
107 gdi_print_page);
108
109 gx_device_printer far_data gs_samsunggdi_device =
110 prn_device(prn_gdi_procs, "samsunggdi",
111 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, /* paper size (unit : 10/72 inch size) */
112 X_DPI2, Y_DPI2,
113 0.20, 0.25, 0.25, 0.25, /* margins filled in by gdi_open */
114 1, /* color bit */
115 gdi_print_page);
116
117 static gp_file *WritePJLHeaderData(gx_device_printer *pdev, gp_file *fp);
118 static gp_file *WriteBandHeader(gp_file *fp, unsigned int usBandNo,
119 unsigned char ubCompMode, unsigned int usBandWidth,
120 unsigned int usBandHeight, unsigned long ulBandSize);
121 static gp_file *WriteTrailerData(gp_file *fp);
122 static unsigned long FrameTiffComp(unsigned char *pubDest, unsigned char *pubSrc,
123 unsigned int usTotalLines, unsigned int usBytesPerLine,
124 unsigned char ubMode);
125 static unsigned int FrameTiff_Comp(unsigned char *lpSrcBuf, unsigned char *lpTgtBuf,
126 unsigned int nSrcBytes);
127 static unsigned int PreTiffComp(unsigned char *lpSrcBuf, unsigned int nSrcBytes);
128 static long bmp2run(unsigned char *out_buf, unsigned char *in_buf, unsigned int sizeY, unsigned int sizeX, unsigned char ubMode);
129
130 #define ppdev ((gx_device_printer *)pdev)
131
132 /* Open the printer, adjusting the margins if necessary. */
133 static int
gdi_open(gx_device * pdev)134 gdi_open(gx_device *pdev)
135 { /* Change the margins if necessary. */
136 const float *m = 0;
137 bool move_origin = true;
138
139 static const float m_a4[4] = { GDI_MARGINS_A4 };
140 static const float m_letter[4] = { GDI_MARGINS_LETTER };
141 m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 :
142 m_letter);
143 move_origin = false;
144
145 if ( m != 0 )
146 gx_device_set_margins(pdev, m, move_origin);
147
148 return gdev_prn_open(pdev);
149 }
150
151 /* gdi_close is only here to eject odd numbered pages in duplex mode. */
152 static int
gdi_close(gx_device * pdev)153 gdi_close(gx_device *pdev)
154 {
155 if ( ppdev->Duplex_set >= 0 && ppdev->Duplex )
156 {
157 int code = gdev_prn_open_printer(pdev, 1);
158 if (code >= 0)
159 gp_fputs("\033&l0H", ppdev->file) ;
160 }
161 return gdev_prn_close(pdev);
162 }
163
164 #undef ppdev
165
166 /* ------ Internal routines ------ */
167
168 /* Samsung SmartGDI series compresses, and it needs a special sequence to */
169 /* allow it to specify coordinates at 600 dpi. */
170 /* It too needs its coordinate system translated slightly. */
171
172 static int
gdi_print_page(gx_device_printer * pdev,gp_file * prn_stream)173 gdi_print_page(gx_device_printer *pdev, gp_file *prn_stream)
174 {
175 int band_width_bytes;
176 int band_height;
177 int code=0, i, j, y, num_rows=0, band_num=0;
178 int dots_per_inch = (int)pdev->y_pixels_per_inch;
179 int raster = gx_device_raster((gx_device *)pdev, true);
180 int real_line_width;
181 long ul_band_size, ul_comp_size;
182 /* long ul_tiff_size, ul_min_size; */
183 byte *ibp=NULL, *obp=NULL, *tmp=NULL;
184 byte paper_type=0, compression_type;
185
186 switch (gdev_pcl_paper_size((gx_device*)pdev))
187 {
188 case PAPER_SIZE_A4 : paper_type = 0;
189 break;
190 case PAPER_SIZE_LETTER : paper_type = 1;
191 break;
192 case PAPER_SIZE_LEGAL : paper_type = 1;
193 break;
194 default:
195 paper_type = 1;
196 break;
197 }
198 if (dots_per_inch == 600) { /* 600dpi */
199 band_width_bytes = (GDI_BAND_WIDTH[paper_type]+31)/32*4;
200 band_height = GDI_BAND_HEIGHT;
201 } else { /* 300dpi */
202 band_width_bytes = (GDI_BAND_WIDTH[paper_type]+31)/32*4/2;
203 band_height = GDI_BAND_HEIGHT*2;
204 }
205
206 ul_band_size = band_width_bytes * band_height;
207 ibp = (byte *)gs_malloc(pdev->memory->non_gc_memory, ul_band_size, 1, "gdi_print_page");
208 obp = (byte *)gs_malloc(pdev->memory->non_gc_memory, ul_band_size*13/10, 1, "gdi_print_page");
209 tmp = (byte *)gs_malloc(pdev->memory->non_gc_memory, raster, 1, "gdi_print_page");
210
211 if (!ibp) return_error(gs_error_VMerror);
212 if (!obp) return_error(gs_error_VMerror);
213 if (!tmp) return_error(gs_error_VMerror);
214
215 if (ibp ==0 || obp == 0) return_error(gs_error_VMerror);
216
217 /* Header Output */
218 prn_stream = WritePJLHeaderData(pdev, prn_stream);
219 num_rows = dev_print_scan_lines(pdev);
220 band_num = (num_rows + band_height -1)/band_height;
221
222 if (raster > band_width_bytes)
223 real_line_width = band_width_bytes;
224 else
225 real_line_width = raster;
226
227 /* Real Data Output */
228 y = 0;
229 for (i=0; i< band_num; i++) {
230 memset(ibp, 0x00, ul_band_size);
231 memset(obp, 0x00, ul_band_size*13/10);
232 for (j=0; j<band_height; j++) {
233 memset(tmp, 0x00, raster);
234 /*code = gdev_prn_copy_scan_lines(pdev, i*band_height+j, */
235 if (y == num_rows) break;
236 code = gdev_prn_copy_scan_lines(pdev, y++,
237 (byte*)tmp, raster);
238 if (code < 0) break;
239 memcpy(ibp+j*band_width_bytes, tmp, real_line_width);
240 }
241
242 if ( i>= GDI_MAX_BAND) continue;
243
244 /* Write Band Data
245 Because of Scanline compression, extract Scanline compression mode */
246 /*ul_tiff_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/
247 /*ul_scan_size = (unsigned long)bmp2run(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/
248 /*ul_min_size = (ul_scan_size > ul_tiff_size) ? ul_tiff_size : ul_scan_size;*/
249 /* ul_min_size = ul_tiff_size; */
250 compression_type = GDI_COMP_MODITIFF;
251 /*compression_type = (ul_scan_size > ul_tiff_size) ? GDI_COMP_MODITIFF : GDI_COMP_SCANLINE;*/
252 switch (compression_type) {
253 case GDI_COMP_MODITIFF:
254 #define FUDGE_BIG_BANDS
255 #ifndef FUDGE_BIG_BANDS
256 ul_comp_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
257 #else
258 {
259 /* Very ugly. The printer will hose if the compressed
260 band size is over 65536, so we "fudge" the data in
261 this case repeatedly until we get what we want.
262
263 The fudge algorithm is simple, this is kinda-sorta
264 RLE, so we just round groups of bits in groups of
265 2, then 3, then 4, etc until the thing works. */
266 #define MAXBAND 0xffff
267 #define ASSERT(x)
268 int fudge=0;
269 byte *use_band=ibp;
270 do {
271 ul_comp_size = FrameTiffComp(obp, use_band,
272 band_height, band_width_bytes,
273 GDI_REAL_COMP);
274 if (ul_comp_size > MAXBAND-8) {
275 int f;
276 if (!fudge) {
277 ASSERT(use_band == ibp);
278 use_band = (byte*)gs_malloc(pdev->memory->non_gc_memory, ul_band_size, 1, "gdi_print_page/fudge");
279 fudge=1;
280 }
281 memcpy(use_band, ibp, ul_band_size);
282 fudge++;
283 ASSERT(fudge>=2);
284 {
285 #define FUDGE2(x) ( (((((x)>>6)&0x3)?3:0)<<6) \
286 | (((((x)>>4)&0x3)?3:0)<<4) \
287 | (((((x)>>2)&0x3)?3:0)<<2) \
288 | (((((x)>>0)&0x3)?3:0)) )
289 #define FUDGE4(x) ( (((((x)>>4)&0xf)?0xf:0)<<4) \
290 | (((((x)>>0)&0xf)?0xf:0)) )
291 #define FUDGE8(x) ( (((((x)>>0)&0xff)?0xf:0)) )
292 #define FUDGE(fudge, x) ( (fudge == 2 ? FUDGE2(x) \
293 : fudge == 3 ? FUDGE4(x) \
294 : fudge == 4 ? FUDGE8(x) \
295 : 0 ) )
296
297 for(f=0;f<ul_band_size; f++) {
298 use_band[f] = FUDGE(fudge, ibp[f]);
299 }
300 }
301 }
302 } while (ul_comp_size > MAXBAND-8);
303 if (fudge > 1) {
304 ASSERT(use_band != ibp);
305 gs_free(pdev->memory->non_gc_memory, use_band, ul_band_size, 1, "gdi_print_page/fudge");
306 /*dprintf2("smartgdi: band %d fudge factor is %d\n", i, fudge);*/
307 }
308 }
309 #endif
310 break;
311 case GDI_COMP_SCANLINE:
312 ul_comp_size = bmp2run(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
313 break;
314 default:
315 ul_comp_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
316 compression_type = GDI_COMP_MODITIFF;
317 break;
318 }
319
320 prn_stream = WriteBandHeader(prn_stream, i, compression_type, (band_width_bytes * 8),
321 band_height, ul_comp_size);
322 /*dprintf2(prn_stream, "[%d] band, size : %d\n", i, ul_tiff_size);*/
323 gp_fwrite(obp, ul_comp_size, 1, prn_stream);
324 }
325
326 /* Trailer Output */
327 WriteTrailerData(prn_stream);
328 gs_free(pdev->memory->non_gc_memory, ibp, ul_band_size, 1, "gdi_line_buffer");
329 gs_free(pdev->memory->non_gc_memory, obp, ul_band_size*13/10, 1, "gdi_line_buffer");
330 gs_free(pdev->memory->non_gc_memory, tmp, raster, 1, "gdi_line_buffer");
331 return code;
332 }
333
WritePJLHeaderData(gx_device_printer * pdev,gp_file * fp)334 gp_file *WritePJLHeaderData(gx_device_printer *pdev, gp_file *fp)
335 {
336 unsigned long ulSize;
337 char buffer[300];
338 int dots_per_inch = (int)pdev->y_pixels_per_inch;
339
340 strcpy(buffer, "\033%-12345X");
341
342 /* Paper Type*/
343 strcat(buffer, "@PJL SET PAPERTYPE = NORMAL ON\015\012");
344 /*Density*/
345 strcat(buffer, "@PJL SET DENSITY = 1\015\012");
346 /* Toner Save*/
347 strcat(buffer, "@PJL SET TONERSAVE = OFF\015\012");
348 /* Enter Language SMART*/
349 strcat(buffer, "@PJL ENTER LANGUAGE = SMART\015\012");
350 /* JobStart*/
351 strcat(buffer, "$PJL JOB START\015\012");
352
353 /* Resolution*/
354 if (dots_per_inch == 600)
355 strcat(buffer, "$PJL RESOLUTION = 600\015\012");
356 else
357 strcat(buffer, "$PJL RESOLUTION = 300\015\012");
358
359 /* Copies*/
360 strcat(buffer, "$PJL COPIES = 1\015\012");
361 /* Paper Size*/
362 switch (gdev_pcl_paper_size((gx_device*)pdev))
363 {
364 case PAPER_SIZE_A4:
365 strcat(buffer, "$PJL PAGE A4 AUTO\015\012");
366 break;
367 case PAPER_SIZE_LETTER:
368 strcat(buffer, "$PJL PAGE LETTER AUTO\015\012");
369 break;
370 case PAPER_SIZE_LEGAL:
371 strcat(buffer, "$PJL PAGE LEGAL AUTO\015\012");
372 break;
373 default:
374 strcat(buffer, "$PJL PAGE LETTER AUTO\015\012");
375 break;
376 }
377 /* bitmap start*/
378 strcat(buffer, "$PJL BITMAP START\015\012");
379 /* write buffer to file.*/
380 ulSize = strlen(buffer);
381 gp_fwrite(buffer, 1, ulSize, fp );
382 return(fp);
383 } /* WritePJLHeaderData() */
384
WriteBandHeader(gp_file * fp,unsigned int usBandNo,unsigned char ubCompMode,unsigned int usBandWidth,unsigned int usBandHeight,unsigned long ulBandSize)385 gp_file *WriteBandHeader
386 (
387 gp_file *fp,
388 unsigned int usBandNo,
389 unsigned char ubCompMode,
390 unsigned int usBandWidth,
391 unsigned int usBandHeight,
392 unsigned long ulBandSize
393 )
394 {
395 unsigned char ubLeft=0;
396 unsigned int i = 0;
397 unsigned char buf[50];
398
399 memset(buf, 0x00, 50);
400
401 ulBandSize += 8;
402
403 /* bandsize*/
404 buf[i++] = (unsigned char)((ulBandSize >> 24) & 0xff);
405 buf[i++] = (unsigned char)((ulBandSize >> 16) & 0xff);
406 buf[i++] = (unsigned char)((ulBandSize >> 8) & 0xff);
407 buf[i++] = (unsigned char)(ulBandSize & 0xff);
408
409 /* id */
410 buf[i++] = (unsigned char)((usBandNo >> 8) & 0xff);
411 buf[i++] = (unsigned char)(usBandNo & 0xff);
412
413 /* compress mode */
414 buf[i++] = (unsigned char)(ubCompMode & 0xff);
415
416 /* ubLeft */
417 buf[i++] = (unsigned char)(ubLeft & 0xff);
418
419 /* height*/
420 buf[i++] = (unsigned char)((usBandHeight >> 8) & 0xff);
421 buf[i++] = (unsigned char)(usBandHeight & 0xff);
422
423 /* width */
424 buf[i++] = (unsigned char)((usBandWidth >> 8) & 0xff);
425 buf[i++] = (unsigned char)(usBandWidth & 0xff);
426
427 gp_fwrite(buf, 1, i, fp);
428 return(fp);
429 } /* end of WriteBandHeader()*/
430
WriteTrailerData(gp_file * fp)431 gp_file *WriteTrailerData(gp_file *fp)
432 {
433 unsigned long ulSize;
434 unsigned long buffer[200];
435
436 memset((char*)buffer, 0x00, 200);
437 strcpy((char*)buffer, "$PJL PRINT 4\015\012");
438 strcat((char*)buffer, "$PJL EOJ\015\012");
439 strcat((char*)buffer, "$PJL SYNC\015\012");
440 strcat((char*)buffer, "$PJL RELEASE 0 2047\015\012");
441 strcat((char*)buffer, "$PJL GARBAGE\015\012");
442 strcat((char*)buffer, "\033%-12345X\015\012");
443
444 ulSize = strlen((char*)buffer);
445 gp_fwrite(buffer, 1, ulSize, fp);
446
447 return(fp);
448 } /* WriteTrailerData()*/
449
FrameTiffComp(unsigned char * pubDest,unsigned char * pubSrc,unsigned int usTotalLines,unsigned int usBytesPerLine,unsigned char ubMode)450 unsigned long FrameTiffComp(unsigned char *pubDest,
451 unsigned char *pubSrc,
452 unsigned int usTotalLines,
453 unsigned int usBytesPerLine,
454 unsigned char ubMode)
455 {
456 unsigned char *TgtPtr, *SrcPtr;
457 unsigned int usLineSize;
458 unsigned long ulret;
459 unsigned int i;
460
461 SrcPtr = pubSrc;
462 TgtPtr = pubDest;
463 ulret = 0;
464
465 for (i = 0; i < usTotalLines; i++)
466 {
467 if (!(ubMode & 0x02))
468 {
469 usLineSize = FrameTiff_Comp(SrcPtr, TgtPtr, usBytesPerLine);
470 }
471 else
472 {
473 usLineSize = PreTiffComp(SrcPtr, usBytesPerLine);
474 }
475 SrcPtr += usBytesPerLine;
476 TgtPtr += usLineSize;
477 ulret += usLineSize;
478 }
479
480 if (!(ubMode & 0x02))
481 {
482 switch (ulret%4)
483 {
484 case 1:
485 *TgtPtr++ = 0x00;
486 ulret++;
487 /* Fall through. */
488 case 2:
489 *TgtPtr++ = 0x00;
490 ulret++;
491 /* Fall through. */
492 case 3:
493 *TgtPtr++ = 0x00;
494 ulret++;
495 /* Fall through. */
496 default:
497 break;
498 }
499 }
500 else
501 {
502 switch (ulret%4)
503 {
504 case 1:
505 ulret++;
506 /* Fall through. */
507 case 2:
508 ulret++;
509 /* Fall through. */
510 case 3:
511 ulret++;
512 /* Fall through. */
513 default:
514 break;
515 }
516 }
517 return(ulret);
518 } /* FrameTiffComp()*/
519
FrameTiff_Comp(unsigned char * lpSrcBuf,unsigned char * lpTgtBuf,unsigned int nSrcBytes)520 unsigned int FrameTiff_Comp(unsigned char *lpSrcBuf, unsigned char *lpTgtBuf, unsigned int nSrcBytes)
521 {
522 unsigned int usret;
523 unsigned int usCount, usEndCnt;
524 unsigned int usControl;
525 unsigned int usCnt;
526 unsigned char ubFirst, ubSecond, ubMisCnt;
527 unsigned char *pubDst, *pubSrc, *pubOrg;
528
529 pubDst = lpTgtBuf;
530 pubSrc = lpSrcBuf;
531 usCount = nSrcBytes;
532 while(1)
533 {
534 if(!usCount)
535 {
536 break; /* exit while(1) loop */
537 }
538 else if (usCount == 1)
539 {
540 *pubDst++ = 0x00;
541 *pubDst++ = *pubSrc++;
542 break;
543 }
544
545 pubOrg = pubSrc;
546 ubFirst = *pubSrc++;
547 ubSecond = *pubSrc++;
548
549 if(ubFirst == ubSecond) /* case of data match */
550 {
551 #if 0
552 /* This code causes coverity problems, and has no affect. */
553 usEndCnt = usCount;
554 if (usCount > 16384)
555 {
556 usEndCnt = 16384;
557 }
558 #endif
559 usEndCnt = usCount - 2;
560 while (usEndCnt--)
561 {
562 if (ubFirst != *pubSrc++)
563 {
564 pubSrc--;
565 break;
566 }
567 } /* of while */
568
569 /* Save compressed data */
570 usCnt = (unsigned int) (pubSrc - pubOrg);
571 usCount -= usCnt;
572 usCnt -=2;
573 if (usCnt >= 64)
574 {
575 /* save control code code 1100 0000 0000 0000 | usCnt */
576 usCnt = (~usCnt & 0x3fff) | 0xc000;
577 *pubDst++ = (unsigned char)((usCnt & 0xff00) >> 8);
578 *pubDst++ = (unsigned char)(usCnt & 0x00ff);
579 *pubDst++ = ubFirst;
580 }
581 else
582 {
583 /* save control code 0100 0000 | (unsigned char)(usCnt) */
584 usCnt = (~usCnt & 0x7f);
585 *pubDst++ = (unsigned char)usCnt;
586 *pubDst++ = ubFirst;
587 }
588 } /* of if (ubFirst == ubSecond) */
589
590 else /* case of data mismatch */
591 {
592 ubMisCnt = 0;
593 if (usCount > 2)
594 {
595 #if 0
596 /* This code causes coverity problems, and has no affect. */
597 usEndCnt = usCount;
598 if (usCount > 16384)
599 {
600 usEndCnt = 16384;
601 }
602 #endif
603 usEndCnt = usCount - 2;
604 /* usEndCnt = usCount - 2; original*/
605 /* 19990824 by LSM : for end file while (usEndCnt--)*/
606 while (usEndCnt--)
607 {
608 /* read next data */
609 ubFirst = ubSecond;
610 ubSecond = *pubSrc++; /* read 3rd Data*/
611 if (ubFirst == ubSecond)
612 {
613 if (usEndCnt <= 1)
614 {
615 ubMisCnt = 2;
616 break;
617 }
618 else
619 {
620 ubSecond = *pubSrc++; /* read 4th Data*/
621 usEndCnt--;
622 if (ubFirst == ubSecond)
623 {
624 ubMisCnt = 3;
625 break;
626 }
627 }
628 }
629 } /* of while */
630 } /* of if (usCount > 2) */
631 /* save data */
632 usControl = (unsigned int) (pubSrc - pubOrg);
633 usControl -= (unsigned int) ubMisCnt;
634 if (usControl > usCount)
635 {
636 usCount = usControl;
637 }
638 usCount -= usControl;
639 usCnt = usControl - 1;
640 if ( usCnt >= 64)
641 {
642 /* save control code 1000 0000 0000 0000 | usCnt */
643 usCnt = ((usCnt & 0xbfff) | 0x8000);
644 *pubDst++ = (unsigned char)((usCnt & 0xff00) >> 8);
645 *pubDst++ = (unsigned char)(usCnt & 0x00ff);
646 }
647 else
648 {
649 /* save control code 0000 0000 | (BYTE)usCnt */
650 /* and invert it */
651 *pubDst++ = (unsigned char)(usCnt & 0x003f);
652 }
653 pubSrc = pubOrg;
654 while (usControl--)
655 {
656 *pubDst++ = *pubSrc++;
657 } /* of while */
658 } /* of else */
659 } /* of while(1) */
660
661 usret = (unsigned int) (pubDst - lpTgtBuf);
662 return (usret);
663 }
664
PreTiffComp(unsigned char * lpSrcBuf,unsigned int nSrcBytes)665 unsigned int PreTiffComp(unsigned char *lpSrcBuf, unsigned int nSrcBytes)
666 {
667 unsigned int usret =0;
668 unsigned int usCount, usEndCnt;
669 unsigned int usControl;
670 unsigned int usCnt;
671 unsigned char ubFirst, ubSecond, ubMisCnt;
672 unsigned char *pubSrc, *pubOrg;
673
674 pubSrc = lpSrcBuf;
675 usCount = nSrcBytes;
676 while(1)
677 {
678 if(!usCount)
679 {
680 break; /* exit while(1) loop */
681 }
682 else if (usCount == 1)
683 {
684 usret +=2;
685 pubSrc++;
686 break;
687 }
688
689 pubOrg = pubSrc;
690 ubFirst = *pubSrc++;
691 ubSecond = *pubSrc++;
692
693 if(ubFirst == ubSecond) /* case of data match */
694 {
695 #if 0
696 /* This code causes coverity problems, and has no affect. */
697 usEndCnt = usCount;
698 if (usCount > 16384)
699 {
700 usEndCnt = 16384;
701 }
702 #endif
703 usEndCnt = usCount - 2;
704 while (usEndCnt--)
705 {
706 if (ubFirst != *pubSrc++)
707 {
708 pubSrc--;
709 break;
710 }
711 } /* of while */
712
713 /* Save compressed data */
714 usCnt = (unsigned int) (pubSrc - pubOrg);
715 usCount -= usCnt;
716 usCnt -=2;
717 if (usCnt >= 64)
718 {
719 /* save control code code 1100 0000 0000 0000 | usCnt */
720 usret +=3;
721 }
722 else
723 {
724 /* save control code 0100 0000 | (unsigned char)(usCnt) */
725 usret += 2;
726 }
727 } /* of if (ubFirst == ubSecond) */
728
729 else /* case of data mismatch */
730 {
731 ubMisCnt = 0;
732 if (usCount > 2)
733 {
734 #if 0
735 /* This code causes coverity problems, and has no affect. */
736 usEndCnt = usCount;
737 if (usCount > 16384)
738 {
739 usEndCnt = 16384;
740 }
741 /* usEndCnt = usCount - 2;*/
742 #endif
743 usEndCnt = usCount - 2;
744 /* 19990824 by LSM : for Last file while (usEndCnt--)*/
745 while (usEndCnt--)
746 {
747 /* read next data */
748 ubFirst = ubSecond;
749 ubSecond = *pubSrc++; /* read 3rd Data*/
750 if (ubFirst == ubSecond)
751 {
752 if (usEndCnt <= 1)
753 {
754 ubMisCnt = 2;
755 break;
756 }
757 else
758 {
759 ubSecond = *pubSrc++; /* read 4th Data*/
760 usEndCnt--; /* 19990824 by LSM*/
761 if (ubFirst == ubSecond)
762 {
763 ubMisCnt = 3;
764 break;
765 }
766 }
767 }
768 } /* of while */
769 } /* of if (usCount > 2) */
770 /* save data */
771 usControl = (unsigned int) (pubSrc - pubOrg);
772 usControl -= ubMisCnt;
773 /* 19990824 by LSM : for fixing GPF on Photoshop*/
774 if (usControl > usCount)
775 {
776 usControl = usCount;
777 }
778 usCount -= usControl;
779 usCnt = usControl - 1;
780 if ( usCnt >= 64)
781 {
782 /* save control code 1000 0000 0000 0000 | usCnt */
783 usret += 2;
784 }
785 else
786 {
787 /* save control code 0000 0000 | (BYTE)usCnt */
788 /* and invert it */
789 usret++;
790 }
791 pubSrc = pubOrg;
792 while (usControl--)
793 {
794 usret++;
795 pubSrc++;
796 } /* of while */
797 } /* of else */
798 } /* of while(1) */
799 return (usret);
800 }
801
802 typedef struct
803 {
804 unsigned char ubDx;
805 unsigned char ubRl;
806 unsigned char ubLastBit;
807 } sc_tbl;
808
809 static sc_tbl gdi_ScanTbl[256] = {
810 { 8, 0, 0 }, { 7, 1, 1 }, { 6, 1, 0 }, { 6, 2, 1 }, /* 0x00*/
811 { 5, 1, 0 }, { 0, 0, 1 }, { 5, 2, 0 }, { 5, 3, 1 },
812 { 4, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
813 { 4, 2, 0 }, { 0, 0, 1 }, { 4, 3, 0 }, { 4, 4, 1 },
814 { 3, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x10*/
815 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
816 { 3, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
817 { 3, 3, 0 }, { 0, 0, 1 }, { 3, 4, 0 }, { 3, 5, 1 },
818 { 2, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x20*/
819 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
820 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
821 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
822 { 2, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x30*/
823 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
824 { 2, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
825 { 2, 4, 0 }, { 0, 0, 1 }, { 2, 5, 0 }, { 2, 6, 1 },
826 { 1, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x40*/
827 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
828 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
829 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
830 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x50*/
831 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
832 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
833 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
834 { 1, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x60*/
835 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
836 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
837 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
838 { 1, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x70*/
839 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
840 { 1, 4, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
841 { 1, 5, 0 }, { 0, 0, 1 }, { 1, 6, 0 }, { 1, 7, 1 },
842 { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x80*/
843 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
844 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
845 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
846 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x90*/
847 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
848 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
849 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
850 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xa0*/
851 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
852 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
853 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
854 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xb0*/
855 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
856 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
857 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
858 { 0, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xc0*/
859 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
860 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
861 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
862 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xd0*/
863 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
864 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
865 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
866 { 0, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xe0*/
867 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
868 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
869 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
870 { 0, 4, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xf0*/
871 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
872 { 0, 5, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
873 { 0, 6, 0 }, { 0, 0, 1 }, { 0, 7, 0 }, { 0, 8, 1 },
874 };
875
876 static sc_tbl gdi_ScanTbl4[16] = {
877 { 4, 0, 0 }, { 3, 1, 1 }, { 2, 1, 0 }, { 2, 2, 1 }, /* 0x00*/
878 { 1, 1, 0 }, { 0, 0, 1 }, { 1, 2, 0 }, { 1, 3, 1 }, /* 0x04*/
879 { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x08*/
880 { 0, 2, 0 }, { 0, 0, 1 }, { 0, 3, 0 }, { 0, 4, 1 } /* 0x0c*/
881 };
882
883 long SaveScanData( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
884 long UpdateScanSize( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
885 typedef long (*funcptr)( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
886
887 funcptr UpdateScanLine[2] = { SaveScanData, UpdateScanSize };
888
Save6Bytes(unsigned char * out_buf,unsigned short usDy,unsigned short usRl,short sDx,unsigned short usWarp)889 static long Save6Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx, unsigned short usWarp)
890 {
891 unsigned long ultmp_dat;
892 long lWarp, lDis;
893 unsigned short ustmp_dat;
894
895 lWarp = (long)(usWarp << 3);
896 lDis = ((long)usDy * lWarp) + (long)sDx;
897
898 /* 1st, 2nd, 3rd & 4th byte*/
899 ultmp_dat = 0xc0000000ul;
900 if (lDis < 0)
901 {
902 ultmp_dat |= 0x20000000ul;
903 }
904 ultmp_dat |= (lDis & 0x1ffffffful);
905 *out_buf++ = (unsigned char)((ultmp_dat & 0xff000000ul) >> 24);
906 *out_buf++ = (unsigned char)((ultmp_dat & 0xff0000ul) >> 16);
907 *out_buf++ = (unsigned char)((ultmp_dat & 0xff00ul) >> 8);
908 *out_buf++ = (unsigned char)(ultmp_dat & 0xfful);
909
910 /* 5th & 6th byte*/
911 ustmp_dat = 0xc000;
912 ustmp_dat |= (usRl & 0x3fff);
913 *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
914 *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
915
916 return(6);
917 } /* Save6Bytes()*/
918
Save4Bytes(unsigned char * out_buf,unsigned short usDy,unsigned short usRl,short sDx)919 static long Save4Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx)
920 {
921 unsigned short ustmp_dat;
922
923 /* 1st & 2nd byte*/
924 ustmp_dat = 0x8000;
925 if (sDx < 0)
926 {
927 ustmp_dat |= 0x2000;
928 }
929 ustmp_dat |= (sDx & 0x1fff);
930 *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
931 *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
932
933 /* 3rd & 4th byte*/
934 ustmp_dat = 0x8000;
935 ustmp_dat |= ((usDy & 0x03) << 12);
936 ustmp_dat |= (usRl & 0xfff);
937 *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
938 *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
939
940 return(4);
941 } /* end of Save4Bytes()*/
942
Save2Bytes(unsigned char * out_buf,unsigned short usDy,unsigned short usRl,short sDx)943 static long Save2Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx)
944 {
945 unsigned char ubtmp_dat;
946
947 /* 1st byte*/
948 ubtmp_dat = 0x00;
949 if (usDy == 1)
950 {
951 ubtmp_dat |= 0x40;
952 }
953 ubtmp_dat |= (usRl & 0x3f);
954 *out_buf++ = ubtmp_dat;
955
956 /* 2nd byte*/
957 if (sDx < 0)
958 {
959 ubtmp_dat = 0x80;
960 }
961 else
962 {
963 ubtmp_dat = 0x00;
964 }
965 ubtmp_dat |= ((unsigned char)sDx & 0x7f);
966 *out_buf++ = ubtmp_dat;
967 return(2);
968 } /* end of Save2Bytes()*/
969
SaveScanData(unsigned char * out_buf,unsigned short us1Cnt,unsigned short usDy,unsigned short usPosX10,unsigned short usPosX01,unsigned short usWarp)970 long SaveScanData (unsigned char *out_buf,
971 unsigned short us1Cnt,
972 unsigned short usDy,
973 unsigned short usPosX10,
974 unsigned short usPosX01,
975 unsigned short usWarp)
976 {
977 short sDisX;
978 long lRet;
979
980 sDisX = (int)usPosX01 - (int)usPosX10;
981
982 /* 48 bit*/
983 if ( (usDy > 3) || (us1Cnt > 4095) )
984 {
985 Save6Bytes(out_buf, usDy, us1Cnt, sDisX, usWarp);
986 lRet = 6;
987 }
988 /* 32 bit*/
989 else if ( (usDy > 1) || (us1Cnt > 63) || (sDisX > 127) || (sDisX < -128) )
990 {
991 Save4Bytes(out_buf, usDy, us1Cnt, sDisX);
992 lRet = 4;
993 }
994 /* 16 bit*/
995 else
996 {
997 Save2Bytes(out_buf, usDy, us1Cnt, sDisX);
998 lRet = 2;
999 }
1000 return(lRet);
1001 } /* end of SaveScanData()*/
1002
UpdateScanSize(unsigned char * out_buf,unsigned short us1Cnt,unsigned short usDy,unsigned short usPosX10,unsigned short usPosX01,unsigned short usWarp)1003 long UpdateScanSize (unsigned char *out_buf,
1004 unsigned short us1Cnt,
1005 unsigned short usDy,
1006 unsigned short usPosX10,
1007 unsigned short usPosX01,
1008 unsigned short usWarp)
1009 {
1010 short sDisX;
1011 long lRet;
1012
1013 sDisX = usPosX01 - usPosX10;
1014
1015 /* 48 bit*/
1016 if ( (usDy > 3) || (us1Cnt > 4095) )
1017 {
1018 lRet = 6;
1019 }
1020 /* 32 bit*/
1021 else if ( (usDy > 1) || (us1Cnt > 63) || (sDisX > 127) || (sDisX < -128) )
1022 {
1023 lRet = 4;
1024 }
1025 /* 16 bit*/
1026 else
1027 {
1028 lRet = 2;
1029 }
1030 return(lRet);
1031 } /* end of UpdateScanSize() by bglee 19981224*/
1032
GetSimpleScan(unsigned char * out_buf,unsigned char ubSizeMode,unsigned short * us1Count,unsigned short * usDy,unsigned short * usPosX10,unsigned short * usPosX01,unsigned short usBytePos,unsigned char ubCrtByte,unsigned char ubSize,unsigned char ubPreBit,unsigned short usWidth)1033 static long GetSimpleScan(unsigned char *out_buf,
1034 unsigned char ubSizeMode,
1035 unsigned short *us1Count,
1036 unsigned short *usDy,
1037 unsigned short *usPosX10,
1038 unsigned short *usPosX01,
1039 unsigned short usBytePos,
1040 unsigned char ubCrtByte,
1041 unsigned char ubSize,
1042 unsigned char ubPreBit,
1043 unsigned short usWidth)
1044 {
1045 long lScanSize;
1046 unsigned char ubDx, ubRl, ubLastBit;
1047
1048 lScanSize = 0;
1049 if (ubSize == 8)
1050 {
1051 ubDx = gdi_ScanTbl[ubCrtByte].ubDx;
1052 ubRl = gdi_ScanTbl[ubCrtByte].ubRl;
1053 ubLastBit = gdi_ScanTbl[ubCrtByte].ubLastBit;
1054 }
1055 else
1056 {
1057 ubCrtByte &= 0x0f;
1058 ubDx = gdi_ScanTbl4[ubCrtByte].ubDx;
1059 ubRl = gdi_ScanTbl4[ubCrtByte].ubRl;
1060 ubLastBit = gdi_ScanTbl4[ubCrtByte].ubLastBit;
1061 }
1062
1063 /* 1 X 1 X*/
1064 if (ubPreBit)
1065 {
1066 /* 1 0 1 X*/
1067 if (ubDx)
1068 {
1069 lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
1070 *usPosX10 = usBytePos - *us1Count;
1071 *usPosX01 = usBytePos + ubDx;
1072 *us1Count = ubRl;
1073 *usDy = 0;
1074 /* 1 0 1 0*/
1075 if (!ubLastBit)
1076 {
1077 /* 19990330 by bglee*/
1078 out_buf = out_buf + lScanSize;
1079
1080 lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
1081 *usPosX10 = *usPosX01 ;
1082 *us1Count = 0;
1083 }
1084 /* 1 0 1 1*/
1085 }
1086 /* 1 1 1 X*/
1087 else
1088 {
1089 *us1Count += ubRl;
1090 /* 1 1 1 0*/
1091 if (!ubLastBit)
1092 {
1093 lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
1094 *usPosX10 = usBytePos + ubRl - *us1Count;
1095 *us1Count = 0;
1096 *usDy = 0;
1097 }
1098 /* 1 1 1 1*/
1099 }
1100 }
1101 /* 0 X 1 X*/
1102 else
1103 {
1104 /* 0 X 1 X*/
1105 *usPosX01 = usBytePos + ubDx;
1106 *us1Count += ubRl;
1107 /* 0 X 1 0*/
1108 if (!ubLastBit)
1109 {
1110 lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
1111 *usPosX10 = *usPosX01 + ubRl - *us1Count;
1112 *us1Count = 0;
1113 *usDy = 0;
1114 }
1115 /* 0 X 1 1*/
1116 }
1117
1118 return(lScanSize);
1119 } /* end of GetSimpleScan() */
1120
scan_map(unsigned char * in_buf,unsigned char * out_buf,unsigned short usWidth,unsigned short usHeight,unsigned char ubMode)1121 static long scan_map (unsigned char *in_buf,
1122 unsigned char *out_buf,
1123 unsigned short usWidth,
1124 unsigned short usHeight,
1125 unsigned char ubMode)
1126 {
1127 unsigned int i, j, k;
1128 unsigned char ubPreBit, ubCrtByte;/*, ubLastBit;*/
1129 long lScanSize, lTmp;
1130 long lCrtSize;
1131 unsigned short us1Count;
1132 unsigned short usPosX01, usPosX10;
1133 unsigned short usDy, usBytePos;
1134 unsigned char ubRevMode, ubSizeMode;
1135 unsigned char ubTemp;
1136
1137 usDy = 0;
1138 usPosX01 = usPosX10 = 0;
1139 lScanSize = 0;
1140 ubRevMode = ubMode & 0x01;
1141 ubSizeMode = (ubMode & 0x02) >> 1;
1142 for (i = 0; i < usHeight; i++)
1143 {
1144 ubPreBit = 0;
1145 us1Count = 0;
1146 for (j = 0; j < usWidth; j++)
1147 {
1148 ubCrtByte = *in_buf++;
1149 if (ubRevMode)
1150 {
1151 ubCrtByte = ~ubCrtByte;
1152 }
1153
1154 switch (ubCrtByte)
1155 {
1156 case 0x00:
1157 /* 1 0 */
1158 if (ubPreBit)
1159 {
1160 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1161 out_buf = out_buf + lTmp;
1162 lScanSize += lTmp;
1163 usPosX10 = (j << 3) - us1Count; /*by pkb*/
1164 us1Count = 0;
1165 usDy = 0;
1166 }
1167 /* 0 0*/
1168 break;
1169
1170 case 0xff:
1171 /* 1 1*/
1172 if (ubPreBit)
1173 {
1174 us1Count += 8;
1175 }
1176 /* 0 1*/
1177 else
1178 {
1179 us1Count = 8;
1180 usPosX01 = (j << 3);
1181 }
1182 break;
1183
1184 default:
1185 /* X X 1 X*/
1186 if (gdi_ScanTbl[ubCrtByte].ubRl)
1187 {
1188 usBytePos = (j << 3);
1189 lTmp = GetSimpleScan(out_buf, ubSizeMode, &us1Count, &usDy, &usPosX10, &usPosX01, usBytePos, ubCrtByte, 8, ubPreBit, usWidth);
1190 out_buf = out_buf + lTmp;
1191 lScanSize += lTmp;
1192 }
1193 /* complex pattern*/
1194 else
1195 {
1196 for (k = 0; k < 2; k++)
1197 { /*we calculate 4bit*/
1198 ubTemp = (ubCrtByte >> (4 - (k * 4)) ) & 0x0f;
1199 usBytePos = (j << 3) + (k << 2);
1200 switch (ubTemp)
1201 {
1202 case 0x00:
1203 /* 1 0*/
1204 if (ubPreBit)
1205 {
1206 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1207 out_buf = out_buf + lTmp;
1208 lScanSize += lTmp;
1209 usPosX10 = usBytePos - us1Count;
1210 us1Count = 0;
1211 usDy = 0;
1212 }
1213 /* 0 0*/
1214 break;
1215
1216 case 0x0f:
1217 /* 1 1*/
1218 if (ubPreBit)
1219 {
1220 us1Count += 4;
1221 }
1222 /* 0 1*/
1223 else
1224 {
1225 us1Count = 4;
1226 usPosX01 = (j << 3) + (k << 2);
1227 }
1228 break;
1229
1230 case 0x05:
1231 /* 1 0101*/
1232 if (ubPreBit)
1233 {
1234 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1235 out_buf = out_buf + lTmp;
1236 lScanSize += lTmp;
1237
1238 usPosX10 = usBytePos - us1Count;
1239 usDy = 0;
1240 }
1241 /* 0 0101*/
1242 usPosX01 = usBytePos + 1;
1243 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, 1, usDy, usPosX10, usPosX01, usWidth);
1244 out_buf = out_buf + lTmp;
1245 lScanSize += lTmp;
1246
1247 /* next*/
1248 usPosX10 = 0;
1249 usPosX01 = 2;
1250 usDy = 0;
1251 us1Count = 1;
1252 break;
1253
1254 case 0x09:
1255 /* 1 1001*/
1256 if (ubPreBit)
1257 {
1258 us1Count++;
1259 }
1260 /* 0 1001*/
1261 else
1262 {
1263 usPosX01 = usBytePos;
1264 us1Count = 1;
1265 }
1266 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1267 out_buf = out_buf + lTmp;
1268 lScanSize += lTmp;
1269
1270 /* next*/
1271 if (ubPreBit)
1272 {
1273 usPosX10 = usBytePos - us1Count + 1;
1274 usPosX01 = usBytePos + 3;
1275 }
1276 else
1277 {
1278 usPosX10 = 0;
1279 usPosX01 = 3;
1280 }
1281 usDy = 0;
1282 us1Count = 1;
1283 break;
1284
1285 case 0x0a:
1286 /* 1 1010*/
1287 if (ubPreBit)
1288 {
1289 us1Count++;
1290 }
1291 /* 0 1010*/
1292 else
1293 {
1294 us1Count = 1;
1295 usPosX01 = usBytePos;
1296 }
1297 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1298 out_buf = out_buf + lTmp;
1299 lScanSize += lTmp;
1300
1301 /* next*/
1302 usPosX10 = usBytePos - us1Count + 1;
1303 usPosX01 = usBytePos + 2;
1304 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, 1, 0, usPosX10, usPosX01, usWidth);
1305 out_buf = out_buf + lTmp;
1306 lScanSize += lTmp;
1307 /* next*/
1308 usPosX10 = usBytePos + 2;
1309 usDy = 0;
1310 us1Count = 0;
1311 break;
1312
1313 case 0x0b:
1314 /* 1 1011*/
1315 if (ubPreBit)
1316 {
1317 us1Count++;
1318 }
1319 /* 0 1011*/
1320 else
1321 {
1322 us1Count = 1;
1323 usPosX01 = usBytePos;
1324 }
1325 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1326 out_buf = out_buf + lTmp;
1327 lScanSize += lTmp;
1328
1329 /* next*/
1330 if (ubPreBit)
1331 {
1332 usPosX10 = usBytePos - us1Count + 1;
1333 usPosX01 = usBytePos + 2;
1334 }
1335 else
1336 {
1337 usPosX10 = 0;
1338 usPosX01 = 2;
1339 }
1340
1341 usDy = 0;
1342 us1Count = 2;
1343 break;
1344
1345 case 0x0d:
1346 /* 1 1101*/
1347 if (ubPreBit)
1348 {
1349 us1Count += 2;
1350 }
1351 /* 0 1101*/
1352 else
1353 {
1354 us1Count = 2;
1355 usPosX01 = usBytePos;
1356 }
1357 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1358 out_buf = out_buf + lTmp;
1359 lScanSize += lTmp;
1360
1361 /* next*/
1362 if (ubPreBit)
1363 {
1364 usPosX10 = usBytePos - us1Count + 2;
1365 usPosX01 = usBytePos + 3;
1366 }
1367 else
1368 {
1369 usPosX10 = 0;
1370 usPosX01 = 3;
1371 }
1372 usDy = 0;
1373 us1Count = 1;
1374 break;
1375
1376 default:
1377 /* X X 1 X*/
1378 lTmp = GetSimpleScan(out_buf, ubSizeMode, &us1Count, &usDy, &usPosX10, &usPosX01, usBytePos, ubTemp, 4, ubPreBit, usWidth);
1379 out_buf = out_buf + lTmp;
1380 lScanSize += lTmp;
1381 break;
1382 } /* end of switch()*/
1383 ubPreBit = ubTemp & 0x01;
1384 } /* end of k-loop*/
1385 }
1386 break;
1387 } /* end of switch()*/
1388
1389 ubPreBit = ubCrtByte & 0x01;
1390 } /*for usWidth */
1391
1392 if (us1Count)
1393 {
1394 lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
1395 out_buf = out_buf + lTmp;
1396 lScanSize += lTmp;
1397 usPosX10 = (j << 3) - us1Count;
1398
1399 us1Count = 0;
1400 usDy = 0;
1401 usPosX01 = 0;
1402 }
1403 usDy++;
1404
1405 /* check size over*/
1406 if ( (i % 5) == 4 )
1407 {
1408 lCrtSize = (long)((long)usWidth * (long)(i + 1));
1409 if ( lScanSize >= lCrtSize )
1410 {
1411 return(-1);
1412 }
1413 }
1414 } /* for usHeight */
1415 lCrtSize = (long)((long)usWidth * (long)usHeight);
1416 if ( (lScanSize + 4) >= lCrtSize )
1417 {
1418 lScanSize = -1;
1419 }
1420 return(lScanSize);
1421 } /* end of scan_map() */
1422
1423 /*****************************************************************
1424 * H : bmp2run
1425 * I : unsigned char *in_buf - input buffer pointer
1426 * unsigned char *out_buf - output buffer pointer
1427 * unsigned int sizeX - image width by byte
1428 * unsigned int sizeY - image height by scanline
1429 * unsigned char ubMode - bit 0 & 1
1430 * 0 0 - normal compression
1431 * 0 1 - image reverse
1432 * 1 X - you get scanline table size
1433 * O : unsigned long lScanSize - scanline table size
1434 * P : scanline table compression
1435 ****************************************************************/
bmp2run(unsigned char * out_buf,unsigned char * in_buf,unsigned int sizeY,unsigned int sizeX,unsigned char ubMode)1436 long bmp2run(unsigned char *out_buf, unsigned char *in_buf, unsigned int sizeY, unsigned int sizeX, unsigned char ubMode)
1437 {
1438 unsigned char *tmp_buf1, *tmp_buf2;
1439 long scan_size;
1440
1441 /*return(-1);*/ /* 19990323 by bglee - request from SM Lee*/
1442
1443 tmp_buf1 = in_buf;
1444 tmp_buf2 = out_buf;
1445 scan_size = scan_map(tmp_buf1, tmp_buf2, sizeX, sizeY, ubMode);
1446 if (scan_size == -1)
1447 {
1448 return(-1);
1449 }
1450
1451 if ( !(ubMode & 0x02) ) /* real compression */
1452 {
1453 out_buf = tmp_buf2 + scan_size;
1454 *out_buf++ = 0x00;
1455 *out_buf++ = 0x00;
1456 scan_size += 2;
1457 if (scan_size % 4)
1458 {
1459 *out_buf++ = 0x00;
1460 *out_buf++ = 0x00;
1461 scan_size += 2;
1462 }
1463 }
1464 else /* pre-compression*/
1465 {
1466 scan_size += 2;
1467 if (scan_size % 4)
1468 {
1469 scan_size += 2;
1470 }
1471 }
1472 return(scan_size);
1473 }
1474