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