summaryrefslogtreecommitdiff
path: root/gs/contrib/gdevgdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/contrib/gdevgdi.c')
-rw-r--r--gs/contrib/gdevgdi.c1462
1 files changed, 1462 insertions, 0 deletions
diff --git a/gs/contrib/gdevgdi.c b/gs/contrib/gdevgdi.c
new file mode 100644
index 000000000..82622d373
--- /dev/null
+++ b/gs/contrib/gdevgdi.c
@@ -0,0 +1,1462 @@
+/*
+ This file is part of GNU Ghostscript.
+
+ GNU Ghostscript is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to
+ anyone for the consequences of using it or for whether it serves any
+ particular purpose or works at all, unless he says so in writing. Refer to
+ the GNU General Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute GNU
+ Ghostscript, but only under the conditions described in the GNU General
+ Public License. A copy of this license is supposed to have been given to
+ you along with GNU Ghostscript so you can know your rights and
+ responsibilities. It should be in a file named COPYING. Among other
+ things, the copyright notice and this notice must be preserved on all
+ copies.
+
+ Aladdin Enterprises is not affiliated with the Free Software Foundation or
+ the GNU Project. GNU Ghostscript, as distributed by Aladdin Enterprises,
+ does not depend on any other GNU software.
+*/
+
+/* gdevgdi.c */
+/* SAMSUNG GDI driver for Ghostscript */
+#include "gdevprn.h"
+#include "gdevpcl.h"
+
+
+/*
+ * You may select a default resolution of 300 or 600 DPI
+ * in the makefile, or an actual resolution
+ * on the gs command line.
+ *
+ * If the preprocessor symbol A4 is defined, the default paper size is
+ * the European A4 size; otherwise it is the U.S. letter size (8.5"x11").
+ *
+ * To determine the proper "margin" settings for your printer, see the
+ * file align.ps.
+ */
+
+/* Define the default, maximum resolutions. */
+#ifdef X_DPI
+# define X_DPI2 X_DPI
+#else
+# define X_DPI 300
+# define X_DPI2 600
+#endif
+#ifdef Y_DPI
+# define Y_DPI2 Y_DPI
+#else
+# define Y_DPI 300
+# define Y_DPI2 600
+#endif
+
+#define GDI_FALSE 0
+#define GDI_TRUE 1
+#define GDI_MAX_COUNT 31
+#define GDI_NO_REPEAT_IDX 0x80000000L
+#define GDI_DATA_LENGTH 11
+#define GDI_REPEAT_LENGTH 2
+#define GDI_BAND_HEIGHT 128
+#define GDI_MAX_BAND 66
+/*#define GDI_BAND_WIDTH 4928*/
+/*#define GDI_BAND_WIDTH_BYTES (((GDI_BAND_WIDTH + 31)/32)*4)*/
+
+#define GDI_PRE_COMP 2
+#define GDI_REAL_COMP 0
+
+#define GDI_COMP_NONE 0
+#define GDI_COMP_TIFF 3
+#define GDI_COMP_SCANLINE 4
+#define GDI_COMP_MODITIFF 6
+#define GDI_COMP_NOSEND 0x7f
+
+#define GDI_MARGINS_A4 0.167, 0.167, 0.167, 0.167
+#define GDI_MARGINS_LETTER 0.167, 0.167, 0.167, 0.167
+/*#define GDI_MARGINS_A4 0.0, 0.0, 0.0, 0.0*/
+/*#define GDI_MARGINS_LETTER 0.0, 0.0, 0.0, 0.0*/
+
+/* The number of blank lines that make it worthwhile to reposition */
+/* the cursor. */
+#define MIN_SKIP_LINES 7
+
+/* We round up the LINE_SIZE to a multiple of a unsigned long for faster scanning. */
+#define W sizeof(word)
+
+int GDI_BAND_WIDTH[] = {4768, 4928};
+
+private int gdi_print_page(gx_device_printer *pdev, FILE *prn_stream);
+private int gdi_open(gx_device *pdev);
+private int gdi_close(gx_device *pdev);
+
+/* The device descriptors */
+private dev_proc_open_device(gdi_open);
+private dev_proc_close_device(gdi_close);
+private dev_proc_print_page(gdi_print_page);
+
+private gx_device_procs prn_gdi_procs =
+ prn_params_procs(gdi_open, gdev_prn_output_page, gdi_close,
+ gdev_prn_get_params, gdev_prn_put_params);
+
+gx_device_printer far_data gs_gdi_device =
+ prn_device(prn_gdi_procs, "gdi",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, /* paper size (unit : 10/72 inch size) */
+ X_DPI2, Y_DPI2,
+ 0.20, 0.25, 0.25, 0.25, /* margins filled in by gdi_open */
+ 1, /* color bit */
+ gdi_print_page);
+
+gx_device_printer far_data gs_samsunggdi_device =
+ prn_device(prn_gdi_procs, "samsunggdi",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, /* paper size (unit : 10/72 inch size) */
+ X_DPI2, Y_DPI2,
+ 0.20, 0.25, 0.25, 0.25, /* margins filled in by gdi_open */
+ 1, /* color bit */
+ gdi_print_page);
+
+private FILE *WritePJLHeaderData(gx_device_printer *pdev, FILE *fp);
+private FILE *WriteBandHeader(FILE *fp, unsigned int usBandNo,
+ unsigned char ubCompMode, unsigned int usBandWidth,
+ unsigned int usBandHeight, unsigned long ulBandSize);
+private FILE *WriteTrailerData(FILE *fp);
+private unsigned long FrameTiffComp(unsigned char *pubDest, unsigned char *pubSrc,
+ unsigned int usTotalLines, unsigned int usBytesPerLine,
+ unsigned char ubMode);
+private unsigned int FrameTiff_Comp(unsigned char *lpSrcBuf, unsigned char *lpTgtBuf,
+ unsigned int nSrcBytes);
+private unsigned int PreTiffComp(unsigned char *lpSrcBuf, unsigned int nSrcBytes);
+private long bmp2run(unsigned char *out_buf, unsigned char *in_buf, unsigned int sizeY, unsigned int sizeX, unsigned char ubMode);
+
+#define ppdev ((gx_device_printer *)pdev)
+
+/* Open the printer, adjusting the margins if necessary. */
+private int
+gdi_open(gx_device *pdev)
+{ /* Change the margins if necessary. */
+ const float *m = 0;
+ bool move_origin = true;
+
+ static const float m_a4[4] = { GDI_MARGINS_A4 };
+ static const float m_letter[4] = { GDI_MARGINS_LETTER };
+ m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 :
+ m_letter);
+ move_origin = false;
+
+ if ( m != 0 )
+ gx_device_set_margins(pdev, m, move_origin);
+
+ return gdev_prn_open(pdev);
+}
+
+/* gdi_close is only here to eject odd numbered pages in duplex mode. */
+private int
+gdi_close(gx_device *pdev)
+{ if ( ppdev->Duplex_set >= 0 && ppdev->Duplex )
+ { gdev_prn_open_printer(pdev, 1);
+ fputs("\033&l0H", ppdev->file) ;
+ }
+ return gdev_prn_close(pdev);
+}
+
+#undef ppdev
+
+/* ------ Internal routines ------ */
+
+/* Samsung SmartGDI series compresses, and it needs a special sequence to */
+/* allow it to specify coordinates at 600 dpi. */
+/* It too needs its coordinate system translated slightly. */
+
+private int
+gdi_print_page(gx_device_printer *pdev, FILE *prn_stream)
+{
+ int band_width_bytes;
+ int band_height;
+ int code=0, i, j, y, num_rows=0, band_num=0;
+ int dots_per_inch = (int)pdev->y_pixels_per_inch;
+ int raster = gx_device_raster((gx_device *)pdev, true);
+ int real_line_width;
+ long ul_band_size, ul_comp_size, ul_tiff_size, ul_min_size;
+ byte *ibp=NULL, *obp=NULL, *tmp=NULL;
+ byte paper_type=0, compression_type;
+
+ switch (gdev_pcl_paper_size((gx_device*)pdev))
+ {
+ case PAPER_SIZE_A4 : paper_type = 0;
+ break;
+ case PAPER_SIZE_LETTER : paper_type = 1;
+ break;
+ case PAPER_SIZE_LEGAL : paper_type = 1;
+ break;
+ default:
+ paper_type = 1;
+ break;
+ }
+ if (dots_per_inch == 600) { /* 600dpi */
+ band_width_bytes = (GDI_BAND_WIDTH[paper_type]+31)/32*4;
+ band_height = GDI_BAND_HEIGHT;
+ } else { /* 300dpi */
+ band_width_bytes = (GDI_BAND_WIDTH[paper_type]+31)/32*4/2;
+ band_height = GDI_BAND_HEIGHT*2;
+ }
+
+ ul_band_size = band_width_bytes * band_height;
+ ibp = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), ul_band_size, 1, "gdi_print_page");
+ obp = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), ul_band_size*13/10, 1, "gdi_print_page");
+ tmp = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), raster, 1, "gdi_print_page");
+
+ if (!ibp) return_error(gs_error_VMerror);
+ if (!obp) return_error(gs_error_VMerror);
+ if (!tmp) return_error(gs_error_VMerror);
+
+ if (ibp ==0 || obp == 0) return_error(gs_error_VMerror);
+
+ /* Header Output */
+ prn_stream = WritePJLHeaderData(pdev, prn_stream);
+ num_rows = dev_print_scan_lines(pdev);
+ band_num = (num_rows + band_height -1)/band_height;
+
+ if (raster > band_width_bytes)
+ real_line_width = band_width_bytes;
+ else
+ real_line_width = raster;
+
+ /* Real Data Output */
+ y = 0;
+ for (i=0; i< band_num; i++) {
+ memset(ibp, 0x00, ul_band_size);
+ memset(obp, 0x00, ul_band_size*13/10);
+ for (j=0; j<band_height; j++) {
+ memset(tmp, 0x00, raster);
+ /*code = gdev_prn_copy_scan_lines(pdev, i*band_height+j, */
+ if (y == num_rows) break;
+ code = gdev_prn_copy_scan_lines(pdev, y++,
+ (byte*)tmp, raster);
+ if (code < 0) break;
+ memcpy(ibp+j*band_width_bytes, tmp, real_line_width);
+ }
+
+ if ( i>= GDI_MAX_BAND) continue;
+
+ /* Write Band Data
+ Because of Scanline compression, extract Scanline compression mode */
+ /*ul_tiff_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/
+ /*ul_scan_size = (unsigned long)bmp2run(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/
+ /*ul_min_size = (ul_scan_size > ul_tiff_size) ? ul_tiff_size : ul_scan_size;*/
+ ul_min_size = ul_tiff_size;
+ compression_type = GDI_COMP_MODITIFF;
+ /*compression_type = (ul_scan_size > ul_tiff_size) ? GDI_COMP_MODITIFF : GDI_COMP_SCANLINE;*/
+ switch (compression_type) {
+ case GDI_COMP_MODITIFF:
+#define FUDGE_BIG_BANDS
+#ifndef FUDGE_BIG_BANDS
+ ul_comp_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
+#else
+ {
+ /* Very ugly. The printer will hose if the compressed
+ band size is over 65536, so we "fudge" the data in
+ this case repeatedly until we get what we want.
+
+ The fudge algorithm is simple, this is kinda-sorta
+ RLE, so we just round groups of bits in groups of
+ 2, then 3, then 4, etc until the thing works. */
+#define MAXBAND 0xffff
+#define ASSERT(x)
+ int fudge=0;
+ byte *use_band=ibp;
+ do {
+ ul_comp_size = FrameTiffComp(obp, use_band,
+ band_height, band_width_bytes,
+ GDI_REAL_COMP);
+ if (ul_comp_size > MAXBAND-8) {
+ int f, g, h;
+ if (!fudge) {
+ ASSERT(use_band == ibp);
+ use_band = (byte*)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), ul_band_size, 1, "gdi_print_page/fudge");
+ fudge=1;
+ }
+ memcpy(use_band, ibp, ul_band_size);
+ fudge++;
+ ASSERT(fudge>=2);
+ {
+#define FUDGE2(x) ( (((((x)>>6)&0x3)?3:0)<<6) \
+ | (((((x)>>4)&0x3)?3:0)<<4) \
+ | (((((x)>>2)&0x3)?3:0)<<2) \
+ | (((((x)>>0)&0x3)?3:0)) )
+#define FUDGE4(x) ( (((((x)>>4)&0xf)?0xf:0)<<4) \
+ | (((((x)>>0)&0xf)?0xf:0)) )
+#define FUDGE8(x) ( (((((x)>>0)&0xff)?0xf:0)) )
+#define FUDGE(fudge, x) ( (fudge == 2 ? FUDGE2(x) \
+ : fudge == 3 ? FUDGE4(x) \
+ : fudge == 4 ? FUDGE8(x) \
+ : 0 ) )
+
+ for(f=0;f<ul_band_size; f++) {
+ use_band[f] = FUDGE(fudge, ibp[f]);
+ }
+ }
+ }
+ } while (ul_comp_size > MAXBAND-8);
+ oh_well:
+ if (fudge > 1) {
+ ASSERT(use_band != ibp);
+ gs_free(gs_lib_ctx_get_non_gc_memory_t(), use_band, ul_band_size, 1, "gdi_print_page/fudge");
+ /*fprintf(stderr, "smartgdi: band %d fudge factor is %d\n", i, fudge);*/
+ }
+ }
+#endif
+ break;
+ case GDI_COMP_SCANLINE:
+ ul_comp_size = bmp2run(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
+ break;
+ default:
+ ul_comp_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_REAL_COMP);
+ compression_type = GDI_COMP_MODITIFF;
+ break;
+ }
+
+ prn_stream = WriteBandHeader(prn_stream, i, compression_type, (band_width_bytes * 8),
+ band_height, ul_comp_size);
+ /*fprintf(prn_stream, "[%d] band, size : %d\n", i, ul_tiff_size);*/
+ fwrite(obp, ul_comp_size, 1, prn_stream);
+ }
+
+ /* Trailer Output */
+ WriteTrailerData(prn_stream);
+ gs_free(gs_lib_ctx_get_non_gc_memory_t(), ibp, ul_band_size, 1, "gdi_line_buffer");
+ gs_free(gs_lib_ctx_get_non_gc_memory_t(), obp, ul_band_size*13/10, 1, "gdi_line_buffer");
+ gs_free(gs_lib_ctx_get_non_gc_memory_t(), tmp, raster, 1, "gdi_line_buffer");
+ return code;
+}
+
+FILE *WritePJLHeaderData(gx_device_printer *pdev, FILE *fp)
+{
+ unsigned long ulSize;
+ unsigned char buffer[300];
+ int dots_per_inch = (int)pdev->y_pixels_per_inch;
+
+ strcpy(buffer, "\033%-12345X");
+
+ /* Paper Type*/
+ strcat(buffer, "@PJL SET PAPERTYPE = NORMAL ON\015\012");
+ /*Density*/
+ strcat(buffer, "@PJL SET DENSITY = 1\015\012");
+ /* Toner Save*/
+ strcat(buffer, "@PJL SET TONERSAVE = OFF\015\012");
+ /* Enter Language SMART*/
+ strcat(buffer, "@PJL ENTER LANGUAGE = SMART\015\012");
+ /* JobStart*/
+ strcat(buffer, "$PJL JOB START\015\012");
+
+ /* Resolution*/
+ if (dots_per_inch == 600)
+ strcat(buffer, "$PJL RESOLUTION = 600\015\012");
+ else
+ strcat(buffer, "$PJL RESOLUTION = 300\015\012");
+
+ /* Copies*/
+ strcat(buffer, "$PJL COPIES = 1\015\012");
+ /* Paper Size*/
+ switch (gdev_pcl_paper_size((gx_device*)pdev))
+ {
+ case PAPER_SIZE_A4:
+ strcat(buffer, "$PJL PAGE A4 AUTO\015\012");
+ break;
+ case PAPER_SIZE_LETTER:
+ strcat(buffer, "$PJL PAGE LETTER AUTO\015\012");
+ break;
+ case PAPER_SIZE_LEGAL:
+ strcat(buffer, "$PJL PAGE LEGAL AUTO\015\012");
+ break;
+ default:
+ strcat(buffer, "$PJL PAGE LETTER AUTO\015\012");
+ break;
+ }
+ /* bitmap start*/
+ strcat(buffer, "$PJL BITMAP START\015\012");
+ /* write buffer to file.*/
+ ulSize = strlen(buffer);
+ fwrite(buffer, 1, ulSize, fp );
+ return(fp);
+} /* WritePJLHeaderData() */
+
+
+FILE *WriteBandHeader
+(
+FILE *fp,
+unsigned int usBandNo,
+unsigned char ubCompMode,
+unsigned int usBandWidth,
+unsigned int usBandHeight,
+unsigned long ulBandSize
+)
+{
+ unsigned char ubLeft=0;
+ unsigned int i = 0;
+ unsigned char buf[50];
+
+ memset(buf, 0x00, 50);
+
+ ulBandSize += 8;
+
+ /* bandsize*/
+ buf[i++] = (unsigned char)((ulBandSize >> 24) & 0xff);
+ buf[i++] = (unsigned char)((ulBandSize >> 16) & 0xff);
+ buf[i++] = (unsigned char)((ulBandSize >> 8) & 0xff);
+ buf[i++] = (unsigned char)(ulBandSize & 0xff);
+
+ /* id */
+ buf[i++] = (unsigned char)((usBandNo >> 8) & 0xff);
+ buf[i++] = (unsigned char)(usBandNo & 0xff);
+
+ /* compress mode */
+ buf[i++] = (unsigned char)(ubCompMode & 0xff);
+
+ /* ubLeft */
+ buf[i++] = (unsigned char)(ubLeft & 0xff);
+
+ /* height*/
+ buf[i++] = (unsigned char)((usBandHeight >> 8) & 0xff);
+ buf[i++] = (unsigned char)(usBandHeight & 0xff);
+
+ /* width */
+ buf[i++] = (unsigned char)((usBandWidth >> 8) & 0xff);
+ buf[i++] = (unsigned char)(usBandWidth & 0xff);
+
+ fwrite(buf, 1, i, fp);
+ return(fp);
+} /* end of WriteBandHeader()*/
+
+FILE *WriteTrailerData(FILE *fp)
+{
+ unsigned long ulSize;
+ unsigned long buffer[200];
+
+ memset((char*)buffer, 0x00, 200);
+ strcpy((char*)buffer, "$PJL PRINT 4\015\012");
+ strcat((char*)buffer, "$PJL EOJ\015\012");
+ strcat((char*)buffer, "$PJL SYNC\015\012");
+ strcat((char*)buffer, "$PJL RELEASE 0 2047\015\012");
+ strcat((char*)buffer, "$PJL GARBAGE\015\012");
+ strcat((char*)buffer, "\033%-12345X\015\012");
+
+ ulSize = strlen((char*)buffer);
+ fwrite(buffer, 1, ulSize, fp);
+
+ return(fp);
+} /* WriteTrailerData()*/
+
+unsigned long FrameTiffComp(unsigned char *pubDest,
+ unsigned char *pubSrc,
+ unsigned int usTotalLines,
+ unsigned int usBytesPerLine,
+ unsigned char ubMode)
+{
+ unsigned char *TgtPtr, *SrcPtr;
+ unsigned int usLineSize;
+ unsigned long ulret;
+ unsigned int i;
+
+ SrcPtr = pubSrc;
+ TgtPtr = pubDest;
+ ulret = 0;
+
+ for (i = 0; i < usTotalLines; i++)
+ {
+ if (!(ubMode & 0x02))
+ {
+ usLineSize = FrameTiff_Comp(SrcPtr, TgtPtr, usBytesPerLine);
+ }
+ else
+ {
+ if(i == 0x253)
+ {
+ i = i;
+ }
+ usLineSize = PreTiffComp(SrcPtr, usBytesPerLine);
+ }
+ SrcPtr += usBytesPerLine;
+ TgtPtr += usLineSize;
+ ulret += usLineSize;
+ }
+
+ if (!(ubMode & 0x02))
+ {
+ switch (ulret%4)
+ {
+ case 1:
+ *TgtPtr++ = 0x00;
+ ulret++;
+ case 2:
+ *TgtPtr++ = 0x00;
+ ulret++;
+ case 3:
+ *TgtPtr++ = 0x00;
+ ulret++;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (ulret%4)
+ {
+ case 1:
+ ulret++;
+ case 2:
+ ulret++;
+ case 3:
+ ulret++;
+ default:
+ break;
+ }
+ }
+ return(ulret);
+} /* FrameTiffComp()*/
+
+unsigned int FrameTiff_Comp(unsigned char *lpSrcBuf, unsigned char *lpTgtBuf, unsigned int nSrcBytes)
+{
+ unsigned int usret;
+ unsigned int usCount, usEndCnt;
+ unsigned int usControl;
+ unsigned int usCnt;
+ unsigned char ubFirst, ubSecond, ubMisCnt;
+ unsigned char *pubDst, *pubSrc, *pubOrg;
+
+ pubDst = lpTgtBuf;
+ pubSrc = lpSrcBuf;
+ usCount = nSrcBytes;
+ while(1)
+ {
+ if(!usCount)
+ {
+ break; /* exit while(1) loop */
+ }
+ else if (usCount == 1)
+ {
+ *pubDst++ = 0x00;
+ *pubDst++ = *pubSrc++;
+ break;
+ }
+
+ pubOrg = pubSrc;
+ ubFirst = *pubSrc++;
+ ubSecond = *pubSrc++;
+
+ if(ubFirst == ubSecond) /* case of data match */
+ {
+ usEndCnt = usCount;
+ if (usCount > 16384)
+ {
+ usEndCnt = 16384;
+ }
+ usEndCnt = usCount - 2;
+ while (usEndCnt--)
+ {
+ if (ubFirst != *pubSrc++)
+ {
+ pubSrc--;
+ break;
+ }
+ } /* of while */
+
+ /* Save compressed data */
+ usCnt = (unsigned int) (pubSrc - pubOrg);
+ usCount -= usCnt;
+ usCnt -=2;
+ if (usCnt >= 64)
+ {
+ /* save control code code 1100 0000 0000 0000 | usCnt */
+ usCnt = (~usCnt & 0x3fff) | 0xc000;
+ *pubDst++ = (unsigned char)((usCnt & 0xff00) >> 8);
+ *pubDst++ = (unsigned char)(usCnt & 0x00ff);
+ *pubDst++ = ubFirst;
+ }
+ else
+ {
+ /* save control code 0100 0000 | (unsigned char)(usCnt) */
+ usCnt = (~usCnt & 0x7f);
+ *pubDst++ = (unsigned char)usCnt;
+ *pubDst++ = ubFirst;
+ }
+ } /* of if (ubFirst == ubSecond) */
+
+ else /* case of data mismatch */
+ {
+ ubMisCnt = 0;
+ if (usCount > 2)
+ {
+ usEndCnt = usCount;
+ if (usCount > 16384)
+ {
+ usEndCnt = 16384;
+ }
+ usEndCnt = usCount - 2;
+ /* usEndCnt = usCount - 2; original*/
+ /* 19990824 by LSM : for end file while (usEndCnt--)*/
+ while (usEndCnt--)
+ {
+ /* read next data */
+ ubFirst = ubSecond;
+ ubSecond = *pubSrc++; /* read 3rd Data*/
+ if (ubFirst == ubSecond)
+ {
+ if (usEndCnt <= 1)
+ {
+ ubMisCnt = 2;
+ break;
+ }
+ else
+ {
+ ubSecond = *pubSrc++; /* read 4th Data*/
+ usEndCnt--;
+ if (ubFirst == ubSecond)
+ {
+ ubMisCnt = 3;
+ break;
+ }
+ }
+ }
+ } /* of while */
+ } /* of if (usCount > 2) */
+ /* save data */
+ usControl = (unsigned int) (pubSrc - pubOrg);
+ usControl -= (unsigned int) ubMisCnt;
+ if (usControl > usCount)
+ {
+ usCount = usControl;
+ }
+ usCount -= usControl;
+ usCnt = usControl - 1;
+ if ( usCnt >= 64)
+ {
+ /* save control code 1000 0000 0000 0000 | usCnt */
+ usCnt = ((usCnt & 0xbfff) | 0x8000);
+ *pubDst++ = (unsigned char)((usCnt & 0xff00) >> 8);
+ *pubDst++ = (unsigned char)(usCnt & 0x00ff);
+ }
+ else
+ {
+ /* save control code 0000 0000 | (BYTE)usCnt */
+ /* and invert it */
+ *pubDst++ = (unsigned char)(usCnt & 0x003f);
+ }
+ pubSrc = pubOrg;
+ while (usControl--)
+ {
+ *pubDst++ = *pubSrc++;
+ } /* of while */
+ } /* of else */
+ } /* of while(1) */
+
+ usret = (unsigned int) (pubDst - lpTgtBuf);
+ return (usret);
+}
+
+unsigned int PreTiffComp(unsigned char *lpSrcBuf, unsigned int nSrcBytes)
+{
+ unsigned int usret =0;
+ unsigned int usCount, usEndCnt;
+ unsigned int usControl;
+ unsigned int usCnt;
+ unsigned char ubFirst, ubSecond, ubMisCnt;
+ unsigned char *pubSrc, *pubOrg;
+
+ pubSrc = lpSrcBuf;
+ usCount = nSrcBytes;
+ while(1)
+ {
+ if(!usCount)
+ {
+ break; /* exit while(1) loop */
+ }
+ else if (usCount == 1)
+ {
+ usret +=2;
+ pubSrc++;
+ break;
+ }
+
+ pubOrg = pubSrc;
+ ubFirst = *pubSrc++;
+ ubSecond = *pubSrc++;
+
+ if(ubFirst == ubSecond) /* case of data match */
+ {
+ usEndCnt = usCount;
+ if (usCount > 16384)
+ {
+ usEndCnt = 16384;
+ }
+ usEndCnt = usCount - 2;
+ while (usEndCnt--)
+ {
+ if (ubFirst != *pubSrc++)
+ {
+ pubSrc--;
+ break;
+ }
+ } /* of while */
+
+ /* Save compressed data */
+ usCnt = (unsigned int) (pubSrc - pubOrg);
+ usCount -= usCnt;
+ usCnt -=2;
+ if (usCnt >= 64)
+ {
+ /* save control code code 1100 0000 0000 0000 | usCnt */
+ usret +=3;
+ }
+ else
+ {
+ /* save control code 0100 0000 | (unsigned char)(usCnt) */
+ usret += 2;
+ }
+ } /* of if (ubFirst == ubSecond) */
+
+ else /* case of data mismatch */
+ {
+ ubMisCnt = 0;
+ if (usCount > 2)
+ {
+ usEndCnt = usCount;
+ if (usCount > 16384)
+ {
+ usEndCnt = 16384;
+ }
+ /* usEndCnt = usCount - 2;*/
+ usEndCnt = usCount - 2;
+ /* 19990824 by LSM : for Last file while (usEndCnt--)*/
+ while (usEndCnt--)
+ {
+ /* read next data */
+ ubFirst = ubSecond;
+ ubSecond = *pubSrc++; /* read 3rd Data*/
+ if (ubFirst == ubSecond)
+ {
+ if (usEndCnt <= 1)
+ {
+ ubMisCnt = 2;
+ break;
+ }
+ else
+ {
+ ubSecond = *pubSrc++; /* read 4th Data*/
+ usEndCnt--; /* 19990824 by LSM*/
+ if (ubFirst == ubSecond)
+ {
+ ubMisCnt = 3;
+ break;
+ }
+ }
+ }
+ } /* of while */
+ } /* of if (usCount > 2) */
+ /* save data */
+ usControl = (unsigned int) (pubSrc - pubOrg);
+ usControl -= ubMisCnt;
+ /* 19990824 by LSM : for fixing GPF on Photoshop*/
+ if (usControl > usCount)
+ {
+ usControl = usCount;
+ }
+ usCount -= usControl;
+ usCnt = usControl - 1;
+ if ( usCnt >= 64)
+ {
+ /* save control code 1000 0000 0000 0000 | usCnt */
+ usret += 2;
+ }
+ else
+ {
+ /* save control code 0000 0000 | (BYTE)usCnt */
+ /* and invert it */
+ usret++;
+ }
+ pubSrc = pubOrg;
+ while (usControl--)
+ {
+ usret++;
+ pubSrc++;
+ } /* of while */
+ } /* of else */
+ } /* of while(1) */
+ return (usret);
+}
+
+typedef struct
+{
+ unsigned char ubDx;
+ unsigned char ubRl;
+ unsigned char ubLastBit;
+} sc_tbl;
+
+static sc_tbl gdi_ScanTbl[256] = {
+{ 8, 0, 0 }, { 7, 1, 1 }, { 6, 1, 0 }, { 6, 2, 1 }, /* 0x00*/
+{ 5, 1, 0 }, { 0, 0, 1 }, { 5, 2, 0 }, { 5, 3, 1 },
+{ 4, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 4, 2, 0 }, { 0, 0, 1 }, { 4, 3, 0 }, { 4, 4, 1 },
+{ 3, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x10*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 3, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 3, 3, 0 }, { 0, 0, 1 }, { 3, 4, 0 }, { 3, 5, 1 },
+{ 2, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x20*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 2, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x30*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 2, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 2, 4, 0 }, { 0, 0, 1 }, { 2, 5, 0 }, { 2, 6, 1 },
+{ 1, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x40*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x50*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 1, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x60*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 1, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x70*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 1, 4, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 1, 5, 0 }, { 0, 0, 1 }, { 1, 6, 0 }, { 1, 7, 1 },
+{ 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x80*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x90*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xa0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xb0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 2, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xc0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xd0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 3, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xe0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 4, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0xf0*/
+{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 5, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 },
+{ 0, 6, 0 }, { 0, 0, 1 }, { 0, 7, 0 }, { 0, 8, 1 },
+};
+
+static sc_tbl gdi_ScanTbl4[16] = {
+{ 4, 0, 0 }, { 3, 1, 1 }, { 2, 1, 0 }, { 2, 2, 1 }, /* 0x00*/
+{ 1, 1, 0 }, { 0, 0, 1 }, { 1, 2, 0 }, { 1, 3, 1 }, /* 0x04*/
+{ 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 1 }, /* 0x08*/
+{ 0, 2, 0 }, { 0, 0, 1 }, { 0, 3, 0 }, { 0, 4, 1 } /* 0x0c*/
+};
+
+long SaveScanData( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
+long UpdateScanSize( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
+typedef long (*funcptr)( unsigned char *, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short );
+
+funcptr UpdateScanLine[2] = { SaveScanData, UpdateScanSize };
+
+long Save6Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx, unsigned short usWarp)
+{
+ unsigned long ultmp_dat;
+ long lWarp, lDis;
+ unsigned short ustmp_dat;
+
+ lWarp = (long)(usWarp << 3);
+ lDis = ((long)usDy * lWarp) + (long)sDx;
+
+ /* 1st, 2nd, 3rd & 4th byte*/
+ ultmp_dat = 0xc0000000ul;
+ if (lDis < 0)
+ {
+ ultmp_dat |= 0x20000000ul;
+ }
+ ultmp_dat |= (lDis & 0x1ffffffful);
+ *out_buf++ = (unsigned char)((ultmp_dat & 0xff000000ul) >> 24);
+ *out_buf++ = (unsigned char)((ultmp_dat & 0xff0000ul) >> 16);
+ *out_buf++ = (unsigned char)((ultmp_dat & 0xff00ul) >> 8);
+ *out_buf++ = (unsigned char)(ultmp_dat & 0xfful);
+
+ /* 5th & 6th byte*/
+ ustmp_dat = 0xc000;
+ ustmp_dat |= (usRl & 0x3fff);
+ *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
+ *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
+
+ return(6);
+} /* Save6Bytes()*/
+
+long Save4Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx)
+{
+ unsigned short ustmp_dat;
+
+ /* 1st & 2nd byte*/
+ ustmp_dat = 0x8000;
+ if (sDx < 0)
+ {
+ ustmp_dat |= 0x2000;
+ }
+ ustmp_dat |= (sDx & 0x1fff);
+ *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
+ *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
+
+ /* 3rd & 4th byte*/
+ ustmp_dat = 0x8000;
+ ustmp_dat |= ((usDy & 0x03) << 12);
+ ustmp_dat |= (usRl & 0xfff);
+ *out_buf++ = (unsigned char)((ustmp_dat & 0xff00) >> 8);
+ *out_buf++ = (unsigned char)(ustmp_dat & 0xff);
+
+ return(4);
+} /* end of Save4Bytes()*/
+
+long Save2Bytes(unsigned char *out_buf, unsigned short usDy, unsigned short usRl, short sDx)
+{
+ unsigned char ubtmp_dat;
+
+ /* 1st byte*/
+ ubtmp_dat = 0x00;
+ if (usDy == 1)
+ {
+ ubtmp_dat |= 0x40;
+ }
+ ubtmp_dat |= (usRl & 0x3f);
+ *out_buf++ = ubtmp_dat;
+
+ /* 2nd byte*/
+ if (sDx < 0)
+ {
+ ubtmp_dat = 0x80;
+ }
+ else
+ {
+ ubtmp_dat = 0x00;
+ }
+ ubtmp_dat |= ((unsigned char)sDx & 0x7f);
+ *out_buf++ = ubtmp_dat;
+ return(2);
+} /* end of Save2Bytes()*/
+
+long SaveScanData (unsigned char *out_buf,
+ unsigned short us1Cnt,
+ unsigned short usDy,
+ unsigned short usPosX10,
+ unsigned short usPosX01,
+ unsigned short usWarp)
+{
+ short sDisX;
+ long lRet;
+
+ sDisX = (int)usPosX01 - (int)usPosX10;
+
+ /* 48 bit*/
+ if ( (usDy > 3) || (us1Cnt > 4095) )
+ {
+ Save6Bytes(out_buf, usDy, us1Cnt, sDisX, usWarp);
+ lRet = 6;
+ }
+ /* 32 bit*/
+ else if ( (usDy > 1) || (us1Cnt > 63) || (sDisX > 127) || (sDisX < -128) )
+ {
+ Save4Bytes(out_buf, usDy, us1Cnt, sDisX);
+ lRet = 4;
+ }
+ /* 16 bit*/
+ else
+ {
+ Save2Bytes(out_buf, usDy, us1Cnt, sDisX);
+ lRet = 2;
+ }
+ return(lRet);
+} /* end of SaveScanData()*/
+
+
+long UpdateScanSize (unsigned char *out_buf,
+ unsigned short us1Cnt,
+ unsigned short usDy,
+ unsigned short usPosX10,
+ unsigned short usPosX01,
+ unsigned short usWarp)
+{
+ short sDisX;
+ long lRet;
+
+ sDisX = usPosX01 - usPosX10;
+
+ /* 48 bit*/
+ if ( (usDy > 3) || (us1Cnt > 4095) )
+ {
+ lRet = 6;
+ }
+ /* 32 bit*/
+ else if ( (usDy > 1) || (us1Cnt > 63) || (sDisX > 127) || (sDisX < -128) )
+ {
+ lRet = 4;
+ }
+ /* 16 bit*/
+ else
+ {
+ lRet = 2;
+ }
+ return(lRet);
+} /* end of UpdateScanSize() by bglee 19981224*/
+
+long 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)
+{
+ long lScanSize;
+ unsigned char ubDx, ubRl, ubLastBit;
+
+ lScanSize = 0;
+ if (ubSize == 8)
+ {
+ ubDx = gdi_ScanTbl[ubCrtByte].ubDx;
+ ubRl = gdi_ScanTbl[ubCrtByte].ubRl;
+ ubLastBit = gdi_ScanTbl[ubCrtByte].ubLastBit;
+ }
+ else
+ {
+ ubCrtByte &= 0x0f;
+ ubDx = gdi_ScanTbl4[ubCrtByte].ubDx;
+ ubRl = gdi_ScanTbl4[ubCrtByte].ubRl;
+ ubLastBit = gdi_ScanTbl4[ubCrtByte].ubLastBit;
+ }
+
+
+ /* 1 X 1 X*/
+ if (ubPreBit)
+ {
+ /* 1 0 1 X*/
+ if (ubDx)
+ {
+ lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
+ *usPosX10 = usBytePos - *us1Count;
+ *usPosX01 = usBytePos + ubDx;
+ *us1Count = ubRl;
+ *usDy = 0;
+ /* 1 0 1 0*/
+ if (!ubLastBit)
+ {
+ /* 19990330 by bglee*/
+ out_buf = out_buf + lScanSize;
+
+ lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
+ *usPosX10 = *usPosX01 ;
+ *us1Count = 0;
+ }
+ /* 1 0 1 1*/
+ }
+ /* 1 1 1 X*/
+ else
+ {
+ *us1Count += ubRl;
+ /* 1 1 1 0*/
+ if (!ubLastBit)
+ {
+ lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
+ *usPosX10 = usBytePos + ubRl - *us1Count;
+ *us1Count = 0;
+ *usDy = 0;
+ }
+ /* 1 1 1 1*/
+ }
+ }
+ /* 0 X 1 X*/
+ else
+ {
+ /* 0 X 1 X*/
+ *usPosX01 = usBytePos + ubDx;
+ *us1Count += ubRl;
+ /* 0 X 1 0*/
+ if (!ubLastBit)
+ {
+ lScanSize += (*UpdateScanLine[ubSizeMode])(out_buf, *us1Count, *usDy, *usPosX10, *usPosX01, usWidth);
+ *usPosX10 = *usPosX01 + ubRl - *us1Count;
+ *us1Count = 0;
+ *usDy = 0;
+ }
+ /* 0 X 1 1*/
+ }
+
+ return(lScanSize);
+} /* end of GetSimpleScan() */
+
+
+long scan_map (unsigned char *in_buf,
+ unsigned char *out_buf,
+ unsigned short usWidth,
+ unsigned short usHeight,
+ unsigned char ubMode)
+{
+ unsigned int i, j, k;
+ unsigned char ubPreBit, ubCrtByte;/*, ubLastBit;*/
+ long lScanSize, lTmp;
+ long lCrtSize;
+ unsigned short us1Count;
+ unsigned short usPosX01, usPosX10;
+ unsigned short usDy, usBytePos;
+ unsigned char ubRevMode, ubSizeMode;
+ unsigned char ubTemp;
+
+ usDy = 0;
+ usPosX01 = usPosX10 = 0;
+ lScanSize = 0;
+ ubRevMode = ubMode & 0x01;
+ ubSizeMode = (ubMode & 0x02) >> 1;
+ for (i = 0; i < usHeight; i++)
+ {
+ ubPreBit = 0;
+ us1Count = 0;
+ for (j = 0; j < usWidth; j++)
+ {
+ ubCrtByte = *in_buf++;
+ if (ubRevMode)
+ {
+ ubCrtByte = ~ubCrtByte;
+ }
+
+ switch (ubCrtByte)
+ {
+ case 0x00:
+ /* 1 0 */
+ if (ubPreBit)
+ {
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ usPosX10 = (j << 3) - us1Count; /*by pkb*/
+ us1Count = 0;
+ usDy = 0;
+ }
+ /* 0 0*/
+ break;
+
+ case 0xff:
+ /* 1 1*/
+ if (ubPreBit)
+ {
+ us1Count += 8;
+ }
+ /* 0 1*/
+ else
+ {
+ us1Count = 8;
+ usPosX01 = (j << 3);
+ }
+ break;
+
+ default:
+ /* X X 1 X*/
+ if (gdi_ScanTbl[ubCrtByte].ubRl)
+ {
+ usBytePos = (j << 3);
+ lTmp = GetSimpleScan(out_buf, ubSizeMode, &us1Count, &usDy, &usPosX10, &usPosX01, usBytePos, ubCrtByte, 8, ubPreBit, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ }
+ /* complex pattern*/
+ else
+ {
+ for (k = 0; k < 2; k++)
+ { /*we calculate 4bit*/
+ ubTemp = (ubCrtByte >> (4 - (k * 4)) ) & 0x0f;
+ usBytePos = (j << 3) + (k << 2);
+ switch (ubTemp)
+ {
+ case 0x00:
+ /* 1 0*/
+ if (ubPreBit)
+ {
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ usPosX10 = usBytePos - us1Count;
+ us1Count = 0;
+ usDy = 0;
+ }
+ /* 0 0*/
+ break;
+
+ case 0x0f:
+ /* 1 1*/
+ if (ubPreBit)
+ {
+ us1Count += 4;
+ }
+ /* 0 1*/
+ else
+ {
+ us1Count = 4;
+ usPosX01 = (j << 3) + (k << 2);
+ }
+ break;
+
+ case 0x05:
+ /* 1 0101*/
+ if (ubPreBit)
+ {
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ usPosX10 = usBytePos - us1Count;
+ usDy = 0;
+ }
+ /* 0 0101*/
+ usPosX01 = usBytePos + 1;
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, 1, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ /* next*/
+ usPosX10 = 0;
+ usPosX01 = 2;
+ usDy = 0;
+ us1Count = 1;
+ break;
+
+ case 0x09:
+ /* 1 1001*/
+ if (ubPreBit)
+ {
+ us1Count++;
+ }
+ /* 0 1001*/
+ else
+ {
+ usPosX01 = usBytePos;
+ us1Count = 1;
+ }
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ /* next*/
+ if (ubPreBit)
+ {
+ usPosX10 = usBytePos - us1Count + 1;
+ usPosX01 = usBytePos + 3;
+ }
+ else
+ {
+ usPosX10 = 0;
+ usPosX01 = 3;
+ }
+ usDy = 0;
+ us1Count = 1;
+ break;
+
+ case 0x0a:
+ /* 1 1010*/
+ if (ubPreBit)
+ {
+ us1Count++;
+ }
+ /* 0 1010*/
+ else
+ {
+ us1Count = 1;
+ usPosX01 = usBytePos;
+ }
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ /* next*/
+ usPosX10 = usBytePos - us1Count + 1;
+ usPosX01 = usBytePos + 2;
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, 1, 0, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ /* next*/
+ usPosX10 = usBytePos + 2;
+ usDy = 0;
+ us1Count = 0;
+ break;
+
+ case 0x0b:
+ /* 1 1011*/
+ if (ubPreBit)
+ {
+ us1Count++;
+ }
+ /* 0 1011*/
+ else
+ {
+ us1Count = 1;
+ usPosX01 = usBytePos;
+ }
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ /* next*/
+ if (ubPreBit)
+ {
+ usPosX10 = usBytePos - us1Count + 1;
+ usPosX01 = usBytePos + 2;
+ }
+ else
+ {
+ usPosX10 = 0;
+ usPosX01 = 2;
+ }
+
+ usDy = 0;
+ us1Count = 2;
+ break;
+
+ case 0x0d:
+ /* 1 1101*/
+ if (ubPreBit)
+ {
+ us1Count += 2;
+ }
+ /* 0 1101*/
+ else
+ {
+ us1Count = 2;
+ usPosX01 = usBytePos;
+ }
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+
+ /* next*/
+ if (ubPreBit)
+ {
+ usPosX10 = usBytePos - us1Count + 2;
+ usPosX01 = usBytePos + 3;
+ }
+ else
+ {
+ usPosX10 = 0;
+ usPosX01 = 3;
+ }
+ usDy = 0;
+ us1Count = 1;
+ break;
+
+ default:
+ /* X X 1 X*/
+ lTmp = GetSimpleScan(out_buf, ubSizeMode, &us1Count, &usDy, &usPosX10, &usPosX01, usBytePos, ubTemp, 4, ubPreBit, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ break;
+ } /* end of switch()*/
+ ubPreBit = ubTemp & 0x01;
+ } /* end of k-loop*/
+ }
+ break;
+ } /* end of switch()*/
+
+ ubPreBit = ubCrtByte & 0x01;
+ } /*for usWidth */
+
+ if (us1Count)
+ {
+ lTmp = (*UpdateScanLine[ubSizeMode])(out_buf, us1Count, usDy, usPosX10, usPosX01, usWidth);
+ out_buf = out_buf + lTmp;
+ lScanSize += lTmp;
+ usPosX10 = (j << 3) - us1Count;
+
+ us1Count = 0;
+ usDy = 0;
+ usPosX01 = 0;
+ }
+ usDy++;
+
+ /* check size over*/
+ if ( (i % 5) == 4 )
+ {
+ lCrtSize = (long)((long)usWidth * (long)(i + 1));
+ if ( lScanSize >= lCrtSize )
+ {
+ return(-1);
+ }
+ }
+ } /* for usHeight */
+ lCrtSize = (long)((long)usWidth * (long)usHeight);
+ if ( (lScanSize + 4) >= lCrtSize )
+ {
+ lScanSize = -1;
+ }
+ return(lScanSize);
+} /* end of scan_map() */
+
+/*****************************************************************
+ * H : bmp2run
+ * I : unsigned char *in_buf - input buffer pointer
+ * unsigned char *out_buf - output buffer pointer
+ * unsigned int sizeX - image width by byte
+ * unsigned int sizeY - image height by scanline
+ * unsigned char ubMode - bit 0 & 1
+ * 0 0 - normal compression
+ * 0 1 - image reverse
+ * 1 X - you get scanline table size
+ * O : unsigned long lScanSize - scanline table size
+ * P : scanline table compression
+ ****************************************************************/
+long bmp2run(unsigned char *out_buf, unsigned char *in_buf, unsigned int sizeY, unsigned int sizeX, unsigned char ubMode)
+{
+ unsigned char *tmp_buf1, *tmp_buf2;
+ long scan_size;
+
+ /*return(-1);*/ /* 19990323 by bglee - request from SM Lee*/
+
+ tmp_buf1 = in_buf;
+ tmp_buf2 = out_buf;
+ scan_size = scan_map(tmp_buf1, tmp_buf2, sizeX, sizeY, ubMode);
+ if (scan_size == -1)
+ {
+ return(-1);
+ }
+
+ if ( !(ubMode & 0x02) ) /* real compression */
+ {
+ out_buf = tmp_buf2 + scan_size;
+ *out_buf++ = 0x00;
+ *out_buf++ = 0x00;
+ scan_size += 2;
+ if (scan_size % 4)
+ {
+ *out_buf++ = 0x00;
+ *out_buf++ = 0x00;
+ scan_size += 2;
+ }
+ }
+ else /* pre-compression*/
+ {
+ scan_size += 2;
+ if (scan_size % 4)
+ {
+ scan_size += 2;
+ }
+ }
+ return(scan_size);
+}
+