Tizen 2.0 Release
[external/epson-laser-printer-escpage.git] / lib / epson-escpage-comp.c
1 /*_______________________________   epson-escpage-comp.c   _____________________________*/\r
2 \r
3 /*       1         2         3         4         5         6         7         8        */\r
4 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/\r
5 /*******************************************|********************************************/\r
6 /*\r
7  *   Copyright (c) 2010  Seiko Epson Corporation                 All rights reserved.\r
8  *\r
9  *   Copyright protection claimed includes all forms and matters of\r
10  *   copyrightable material and information now allowed by statutory or judicial\r
11  *   law or hereinafter granted, including without limitation, material generated\r
12  *   from the software programs which are displayed on the screen such as icons,\r
13  *   screen display looks, etc.\r
14  *\r
15  */\r
16 \r
17 /*------------------------------------  Includes   -------------------------------------*/\r
18 /*******************************************|********************************************/\r
19 #include "epson-escpr-mem.h"\r
20 #include "epson-escpage-comp.h"\r
21 \r
22 /*-----------------------------------  Definitions  ------------------------------------*/\r
23 /*******************************************|********************************************/\r
24 \r
25 #ifdef EPS_LOG_MODULE_PAGE\r
26 #define EPS_LOG_MODULE  EPS_LOG_MODULE_PAGE\r
27 #else\r
28 #define EPS_LOG_MODULE  0\r
29 #endif\r
30 \r
31 /* Define Bitmap Format */\r
32 #define EP_BGR                          0\r
33 #define EP_RGB                          1\r
34 \r
35 #define ConvertEndianWord(w)    ((EPS_UINT16) ((((w) >> 8) & 0xFF) | (((w) << 8) & 0xFF00)))\r
36 #define ConvertEndianDWORD(d)   (((EPS_UINT32) (d) << 24) | (((EPS_UINT32) (d) << 8) &  0x00FF0000) | (((EPS_UINT32) (d) >> 8) & 0x0000FF00) | ((EPS_UINT32) (d) >> 24))\r
37 #define GetCompressMode(d)              ((EPS_UINT16) ((d) >> 16))\r
38 #define GetCompressQuality(d)   ((EPS_UINT16) ((d) & 0xFFFF))\r
39 \r
40 #define BAND_PIXEL                              4\r
41 #define MakeCompress20Mode(q)   (0x20 + (q))\r
42 #define MakeUncompress20Mode(q) (0x00 + (q))\r
43 \r
44 /*---------------------------  Data Structure Declarations   ---------------------------*/\r
45 /*******************************************|********************************************/\r
46 typedef struct tagCODINGDATA {\r
47         EPS_UINT16              hufCode[256] ;\r
48         EPS_UINT8               hufCodeLen[256] ;\r
49         EPS_UINT8*              lpCurPtr ;\r
50         EPS_UINT32              leftCount ;\r
51         EPS_UINT32              code ;\r
52         EPS_UINT16              codeBits ;\r
53 } CODINGDATA ;\r
54 \r
55 typedef struct tagCOMPRESSBUFFER {\r
56         EPS_UINT16              wMode ;                         /* Compress Mode */\r
57         EPS_UINT16              wQuality ;                      /* Compress Quality */\r
58         EPS_UINT8*              lpBuffer ;                      /* Output Buffer */\r
59         EPS_UINT32              sizeBuffer ;            /* Output Buffer Size */\r
60         EPS_UINT32              dwWidth ;                                       \r
61         EPS_UINT32              dwHeight ;                                      \r
62         EPS_UINT32              format ;                        /* Align Format */\r
63         EPS_UINT16              biBitCount ;            /* Bitmap Bit Count */\r
64         EPS_INT32               nextLine ;\r
65         EPS_BOOL                bInvertX ;                      /* Invert Image X */\r
66         EPS_UINT8*              lpBitsOrg ;                     /* Start Address */\r
67         EPS_UINT32              ySrc ;\r
68 } COMPRESSBUFFER ;\r
69 \r
70 typedef struct tagBLOCKHEADER20 {\r
71         EPS_UINT32              size ;          /* 0 */\r
72         EPS_UINT16              width ;         /* 4 */\r
73         EPS_UINT16              bandPixel ;     /* 6 */\r
74         EPS_UINT16              mode ;          /* 8 */\r
75 } BLOCKHEADER20 ;\r
76 #define SIZEOF_BLOCKHEADER20    (4+2+2+2)\r
77 \r
78 typedef struct tagCOMPBUFFER20 {\r
79         COMPRESSBUFFER  cbuf ;\r
80         BLOCKHEADER20   bh ;\r
81         CODINGDATA              cd ;\r
82         EPS_UINT32              bandLimit ;\r
83         EPS_UINT8               mode[4] ;\r
84 } COMPBUFFER20 ;\r
85 \r
86 /*----------------------------  ESC/P-R Lib Global Variables  --------------------------*/\r
87 /*******************************************|********************************************/\r
88 extern EPS_CMN_FUNC             epsCmnFnc;\r
89 \r
90 /*------------------------------  Local Global Variables  ------------------------------*/\r
91 /*******************************************|********************************************/\r
92 static const EPS_UINT16 HufmanDefTable2[] \r
93                                         = {0, 0, 1, 2, 2, 4, 4, 7, 9, 14, 17, 24, 172} ;\r
94 static const EPS_UINT16 HufmanDefTable3[][2] \r
95                                         = { 0x00, 2, 0x02, 2, 0x01, 2, 0x03, 4, 0x0b, 4, \r
96                                             0x07, 5, 0x17, 5, 0x0f, 5, 0x1f, 5,\r
97                                         } ;\r
98 \r
99 /*--------------------------  Private Functions Declaration   --------------------------*/\r
100 /*******************************************|********************************************/\r
101 static EPS_UINT32 EPGetCompressBufferSize(EPS_UINT32 dwMode) ;\r
102 static EPS_UINT32 EPCompressImage(\r
103                                 EPS_UINT32 dwMode, \r
104                                 EPS_UINT32 xSrc, EPS_UINT32 ySrc, EPS_UINT32 dwWidth, EPS_UINT32 dwHeight, \r
105                                 EPS_BITMAPINFO *lpbmi, EPS_UINT32 biFormat, EPS_UINT8* lpBits,\r
106                                 EPS_UINT8* lpBuf, EPS_UINT32 sizeBuf, \r
107                                 EPS_UINT8* lpWorkBuf ) ;\r
108 static EPS_UINT32 Compress20(COMPBUFFER20* lpC20Buf) ;\r
109 static EPS_BOOL MakeHufmanCodeTable(EPS_UINT16 wMode, EPS_UINT16 wQuality, CODINGDATA* lpcd) ;\r
110 static EPS_BOOL WriteBandData20(EPS_INT32 band, EPS_INT32 incptr, EPS_UINT8* lpSrc, COMPBUFFER20* lpC20Buf) ;\r
111 static EPS_UINT8 GetByteBLOCKHEADER20(BLOCKHEADER20 *p, EPS_INT32 n);\r
112 static void MakeHufmanTable1(const EPS_UINT16 cdn[], CODINGDATA* lpcd) ;\r
113 static void CodeHufmanData(const EPS_UINT8 d, CODINGDATA* const lpcd);\r
114 static void WriteDataToBuffer(CODINGDATA* const lpcd);\r
115 \r
116 \r
117 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
118 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
119 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
120 /*--------------------              Public Functions               ---------------------*/\r
121 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
122 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
123 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
124 \r
125 EPS_UINT8*      CompressBitImage(\r
126 \r
127         EPS_RECT                        *pRec,\r
128         EPS_BITMAPINFO          *pBitMapInfo,\r
129         EPS_UINT8*                      pRealBits,\r
130         EPS_UINT32                      ulDataFormat,\r
131         EPS_UINT32                      *pulCompressType,\r
132         EPS_UINT32                      *pulImageSize\r
133 \r
134 ){\r
135         EPS_BITMAPINFO          bmi;\r
136         EPS_UINT32                      dwComMode = 0;\r
137         EPS_UINT32                      dwwkBufferSize;\r
138         EPS_UINT8*                      pwkBuffer = NULL;\r
139         EPS_UINT32                      dwBuffer;\r
140         EPS_UINT8*                      pTmp = NULL;\r
141         EPS_UINT32                      dwCompressedSize;\r
142 \r
143         EPS_INT32                       ulSrcleft, ulSrcright, ulSrcbottom, ulSrctop;\r
144 \r
145         ulSrcleft = pRec->left; \r
146         ulSrcright= pRec->right;\r
147         ulSrcbottom = pRec->bottom;\r
148         ulSrctop= pRec->top;\r
149 \r
150         bmi = *pBitMapInfo;\r
151 \r
152         dwComMode = ulDataFormat;\r
153 \r
154         *pulCompressType = dwComMode;\r
155         dwComMode = dwComMode << 16;\r
156 \r
157         dwwkBufferSize = EPGetCompressBufferSize( dwComMode);\r
158 \r
159         debug_msg("dwwkBufferSize = %d\n", dwwkBufferSize);\r
160         if(dwwkBufferSize == 0){\r
161                 *pulCompressType = 0;\r
162                 return NULL;\r
163         }\r
164 \r
165         if(!(pwkBuffer = (EPS_UINT8*)EPS_ALLOC( dwwkBufferSize ))){\r
166                 *pulCompressType = 0;\r
167                 return NULL;\r
168         }\r
169 \r
170         dwBuffer = (((ulSrcright - ulSrcleft ) * 24 + 31) / 32) * 4 * (ulSrcbottom - ulSrctop );\r
171         if(!(pTmp = (EPS_UINT8*)EPS_ALLOC( dwBuffer ))){\r
172                 EPS_FREE(pwkBuffer );\r
173                 *pulCompressType = 0;\r
174                 return NULL;\r
175         }\r
176 \r
177         dwCompressedSize = EPCompressImage( dwComMode,\r
178                                                                                         ulSrcleft,\r
179                                                                                         ulSrctop,\r
180                                                                                         ulSrcright - ulSrcleft ,\r
181                                                                                         ulSrcbottom - ulSrctop ,\r
182                                                                                         &bmi,\r
183                                                                                         EP_RGB,\r
184                                                                                         pRealBits,\r
185                                                                                         pTmp,\r
186                                                                                         dwBuffer,\r
187                                                                                         pwkBuffer );\r
188 \r
189         EPS_FREE(pwkBuffer);\r
190         if(dwCompressedSize == 0){\r
191                 EPS_FREE(pTmp);\r
192                 *pulCompressType = 0;\r
193                 return NULL;\r
194         }\r
195 \r
196         *pulImageSize = dwCompressedSize;\r
197 \r
198         return pTmp;\r
199 }\r
200 \r
201 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
202 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
203 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
204 /*--------------------               Local Functions               ---------------------*/\r
205 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
206 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
207 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
208 \r
209 static EPS_UINT32  EPGetCompressBufferSize (EPS_UINT32 dwMode)\r
210 {\r
211         EPS_UINT16 mode;\r
212         \r
213         EPS_LOG_FUNCIN\r
214 \r
215         mode = GetCompressMode(dwMode) ;\r
216 \r
217         switch (mode) {\r
218 \r
219         case EP_COMPRESS20 :\r
220                 EPS_RETURN( sizeof(COMPBUFFER20) )\r
221         default:\r
222                 break;\r
223         }\r
224 \r
225         EPS_RETURN( 0 )\r
226 }\r
227 \r
228 \r
229 static EPS_UINT32 EPCompressImage (\r
230                 EPS_UINT32 dwMode,\r
231                 EPS_UINT32 xSrc,\r
232                 EPS_UINT32 ySrc,\r
233                 EPS_UINT32 dwWidth,\r
234                 EPS_UINT32 dwHeight,\r
235                 EPS_BITMAPINFO *lpbmi,\r
236                 EPS_UINT32 biFormat,\r
237                 EPS_UINT8* lpBits,\r
238                 EPS_UINT8* lpBuf,\r
239                 EPS_UINT32 sizeBuf,\r
240                 EPS_UINT8* lpWorkBuf )\r
241 {\r
242         COMPRESSBUFFER* lpCBuf ;\r
243         EPS_UINT32 height ;\r
244 \r
245         EPS_LOG_FUNCIN\r
246 \r
247         if (dwWidth == 0 || dwHeight == 0) {\r
248                 EPS_RETURN( 0 )\r
249         }\r
250         if (lpWorkBuf == NULL) {\r
251                 EPS_RETURN( 0 )\r
252         }\r
253 \r
254         lpCBuf = (COMPRESSBUFFER*) lpWorkBuf ;\r
255                 \r
256         /* Check Width and calculate Scan Size */\r
257 \r
258         if (lpbmi->biWidth <= 0 || (EPS_UINT32) lpbmi->biWidth < xSrc + dwWidth) {\r
259                 EPS_RETURN( 0 )\r
260         }\r
261 \r
262         lpCBuf->dwWidth = dwWidth ;\r
263         lpCBuf->biBitCount = lpbmi->biBitCount ;\r
264         lpCBuf->format = biFormat ;\r
265         \r
266         lpCBuf->nextLine = ((lpbmi->biWidth * lpCBuf->biBitCount + 7) / 8 + 3) & 0xFFFFFFFC ;\r
267         lpCBuf->lpBitsOrg = lpBits + (xSrc*lpCBuf->biBitCount / 8) ;\r
268         /*lpCBuf->bitOffset = (EPS_INT16) (xSrc*lpCBuf->biBitCount % 8) ;*/\r
269         \r
270         /* Check Height and calculate start addr */\r
271         \r
272         lpCBuf->dwHeight = dwHeight ;\r
273         if (lpbmi->biHeight > 0) {\r
274                 /* bottom up bitmap */\r
275                 height = (EPS_UINT32) lpbmi->biHeight ;\r
276                 lpCBuf->lpBitsOrg += lpCBuf->nextLine * (ySrc + dwHeight - 1);\r
277                 lpCBuf->nextLine = -lpCBuf->nextLine ;\r
278         }\r
279         else {\r
280                 /* top down bitmap */\r
281                 height = (EPS_UINT32) -lpbmi->biHeight;\r
282                 lpCBuf->lpBitsOrg += lpCBuf->nextLine * ySrc;\r
283         }\r
284         if (height == 0 || height < ySrc + dwHeight) {\r
285                 EPS_RETURN( 0 )\r
286         }\r
287         \r
288         /* Fill Other fields */\r
289         lpCBuf->wMode = GetCompressMode(dwMode) ;\r
290         lpCBuf->wQuality = GetCompressQuality(dwMode) ;\r
291         lpCBuf->lpBuffer = lpBuf ;\r
292         lpCBuf->sizeBuffer = sizeBuf ;\r
293         lpCBuf->bInvertX = FALSE ;\r
294         debug_msg("lpCBuf->wMode = %d\n", lpCBuf->wMode);\r
295         debug_msg("dwMode = %d\n", dwMode);\r
296         switch (lpCBuf->wMode) {\r
297         case EP_COMPRESS20 :\r
298                 debug_msg("check compress20\n");\r
299                 EPS_RETURN( Compress20((COMPBUFFER20*) lpCBuf) )\r
300         default:\r
301                 break;\r
302         }\r
303         \r
304         EPS_RETURN( 0 )\r
305 }\r
306 \r
307 /*      24BPP Image Compress Mode 20 */\r
308 static EPS_UINT32 Compress20(COMPBUFFER20* lpC20Buf)\r
309 {\r
310         EPS_UINT8* lpSrc ;\r
311         EPS_INT32 nextBand ;\r
312         EPS_UINT32 y, yblock, ymod ;\r
313         EPS_INT32 incptr ;\r
314         \r
315         EPS_LOG_FUNCIN\r
316 \r
317         if (lpC20Buf->cbuf.biBitCount == 24) {\r
318                 incptr = 3 ;\r
319         }\r
320         else if (lpC20Buf->cbuf.biBitCount == 32) {\r
321                 incptr = 4 ;\r
322         }\r
323         else {\r
324                 EPS_RETURN( 0 )\r
325         }\r
326         \r
327         if (lpC20Buf->cbuf.bInvertX) {\r
328                 /* invert image */\r
329                 lpSrc = lpC20Buf->cbuf.lpBitsOrg + (lpC20Buf->cbuf.dwWidth - 1) * incptr ;\r
330                 incptr = -incptr ;\r
331         }\r
332         else {\r
333                 lpSrc = lpC20Buf->cbuf.lpBitsOrg ;\r
334         }\r
335         \r
336         if (lpC20Buf->cbuf.format == EP_RGB) {\r
337                 lpC20Buf->mode[0] = 2 ;\r
338                 lpC20Buf->mode[1] = 1 ;\r
339                 lpC20Buf->mode[2] = 0 ;\r
340         }\r
341         else {\r
342                 lpC20Buf->mode[0] = 0 ;\r
343                 lpC20Buf->mode[1] = 1 ;\r
344                 lpC20Buf->mode[2] = 2 ;\r
345         }\r
346         \r
347         /* Make Hufman Code Table */\r
348         MakeHufmanCodeTable(lpC20Buf->cbuf.wMode, lpC20Buf->cbuf.wQuality, &lpC20Buf->cd) ;\r
349         \r
350         /* Make Block Header */\r
351         lpC20Buf->bh.width              = ConvertEndianWord(lpC20Buf->cbuf.dwWidth) ;\r
352         lpC20Buf->bh.bandPixel  = ConvertEndianWord(BAND_PIXEL) ;\r
353         \r
354         /* Initialize */\r
355         lpC20Buf->cd.lpCurPtr = lpC20Buf->cbuf.lpBuffer ;\r
356         lpC20Buf->cd.leftCount = lpC20Buf->cbuf.sizeBuffer ;\r
357 \r
358         yblock  = lpC20Buf->cbuf.dwHeight / BAND_PIXEL ;\r
359         ymod    = lpC20Buf->cbuf.dwHeight % BAND_PIXEL ;\r
360 \r
361         nextBand = lpC20Buf->cbuf.nextLine * BAND_PIXEL ;\r
362 \r
363         lpC20Buf->bandLimit = SIZEOF_BLOCKHEADER20 + lpC20Buf->cbuf.dwWidth * BAND_PIXEL ;\r
364 \r
365         for (y = 0 ; y < yblock ; y++) {\r
366                 if (! WriteBandData20(BAND_PIXEL, incptr, lpSrc, lpC20Buf)) {\r
367                         EPS_RETURN( 0 )\r
368                 }\r
369                 lpSrc += nextBand ;\r
370         }\r
371         if (ymod) {\r
372                 lpC20Buf->bh.bandPixel  = ConvertEndianWord(ymod) ;\r
373                 lpC20Buf->bandLimit = SIZEOF_BLOCKHEADER20 + lpC20Buf->cbuf.dwWidth * ymod ;\r
374                 \r
375                 if (! WriteBandData20((EPS_UINT16) ymod, incptr, lpSrc, lpC20Buf)) {\r
376                         EPS_RETURN( 0 )\r
377                 }\r
378         }\r
379 \r
380         if (lpC20Buf->cd.leftCount == 0) {\r
381                         EPS_RETURN( 0 )\r
382         }\r
383 \r
384         EPS_RETURN( lpC20Buf->cbuf.sizeBuffer - lpC20Buf->cd.leftCount )\r
385 }\r
386 \r
387 \r
388 static EPS_BOOL WriteBandData20(EPS_INT32 band, EPS_INT32 incptr, EPS_UINT8* lpSrc, COMPBUFFER20* lpC20Buf) \r
389 {\r
390         EPS_UINT32 sizeBlockData ;\r
391         EPS_UINT8* lpBandStart ;\r
392         EPS_UINT32 countBandStart ;\r
393         EPS_UINT8 *lpBand, *lpPt, *lpPrePt;\r
394         EPS_UINT8 left ;\r
395 \r
396         EPS_INT32 i, j ;\r
397         EPS_UINT32 x ;\r
398 \r
399         EPS_LOG_FUNCIN\r
400 \r
401         for (i = 0 ; i <= 2 ; i++) {\r
402                 if (lpC20Buf->cd.leftCount <= SIZEOF_BLOCKHEADER20) {\r
403                         EPS_RETURN( FALSE )\r
404                 }\r
405 \r
406                 lpBandStart = lpC20Buf->cd.lpCurPtr ;\r
407                 countBandStart = lpC20Buf->cd.leftCount ;\r
408 \r
409                 lpC20Buf->cd.lpCurPtr += SIZEOF_BLOCKHEADER20;\r
410                 lpC20Buf->cd.leftCount -= SIZEOF_BLOCKHEADER20;\r
411                 lpC20Buf->cd.code = 0 ;\r
412                 lpC20Buf->cd.codeBits = 0 ;\r
413                 \r
414                 lpBand = lpSrc + i ;\r
415                 lpPt = lpBand ;\r
416                 left = 0 ;\r
417                 \r
418                 for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
419                         CodeHufmanData((EPS_UINT8) (*lpPt-left), &lpC20Buf->cd) ;\r
420                         left = *lpPt ;\r
421                         lpPt += incptr ;\r
422                 }\r
423                 \r
424                 for (j = 1 ; j < band ; j++) {\r
425                         lpPrePt = lpBand ;\r
426                         lpBand += lpC20Buf->cbuf.nextLine ;\r
427                         lpPt = lpBand ;\r
428                         left = 0 ;\r
429                         \r
430                         for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
431                                 CodeHufmanData((EPS_UINT8) (*lpPt-((left+*lpPrePt)>>1)), &lpC20Buf->cd) ;\r
432                                 left = *lpPt ;\r
433                                 lpPt += incptr ;\r
434                                 lpPrePt += incptr ;\r
435                         }\r
436                 }\r
437                 if (lpC20Buf->cd.codeBits) WriteDataToBuffer(&lpC20Buf->cd) ;\r
438                 \r
439                 if (countBandStart <= lpC20Buf->cd.leftCount + lpC20Buf->bandLimit) {\r
440                         /* Write Block Header */\r
441                         sizeBlockData = countBandStart - lpC20Buf->cd.leftCount ;\r
442                         lpC20Buf->bh.size = ConvertEndianDWORD(sizeBlockData) ;\r
443                         lpC20Buf->bh.mode = ConvertEndianWord(MakeCompress20Mode(lpC20Buf->mode[i])) ;\r
444 \r
445                         for (x = 0 ; x < SIZEOF_BLOCKHEADER20 ; x++) {\r
446                                 *lpBandStart++ = GetByteBLOCKHEADER20(&lpC20Buf->bh, x);\r
447                         }\r
448                 }\r
449                 else {\r
450                         /* Output Un-Compress Data */\r
451                         if (countBandStart < lpC20Buf->bandLimit) {\r
452                                 EPS_RETURN( FALSE )\r
453                         }\r
454 \r
455                         sizeBlockData = lpC20Buf->bandLimit ;\r
456                         lpC20Buf->bh.size = ConvertEndianDWORD(sizeBlockData) ;\r
457                         lpC20Buf->bh.mode = ConvertEndianWord(MakeUncompress20Mode(lpC20Buf->mode[i])) ;\r
458 \r
459                         for (x = 0 ; x < SIZEOF_BLOCKHEADER20; x++) {\r
460                                 *lpBandStart++ = GetByteBLOCKHEADER20(&lpC20Buf->bh, x);\r
461                         }\r
462 \r
463                         lpBand = lpSrc + i ;\r
464                         for (j = 0 ; j < band ; j++) {\r
465                                 lpPt = lpBand ;\r
466                                 lpBand += lpC20Buf->cbuf.nextLine ;\r
467                                 for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
468                                         *lpBandStart++ = *lpPt ;\r
469                                         lpPt += incptr ;\r
470                                 }\r
471                         }\r
472                         \r
473                         lpC20Buf->cd.lpCurPtr = lpBandStart ;\r
474                         lpC20Buf->cd.leftCount = countBandStart - lpC20Buf->bandLimit ;\r
475                 }\r
476         }\r
477 \r
478         EPS_RETURN( TRUE )\r
479 }\r
480 \r
481 \r
482 static EPS_UINT8 GetByteBLOCKHEADER20(BLOCKHEADER20 *p, EPS_INT32 n)\r
483 {\r
484         EPS_UINT8 b = 0;\r
485         switch(n){\r
486         case 0:         b = (EPS_UINT8)(p->size)       & 0x000000FF;    break;\r
487         case 1:         b = (EPS_UINT8)(p->size >> 8)  & 0x000000FF;    break;\r
488         case 2:         b = (EPS_UINT8)(p->size >> 16) & 0x000000FF;    break;\r
489         case 3:         b = (EPS_UINT8)(p->size >> 24) & 0x000000FF;    break;\r
490 \r
491         case 4:         b = (EPS_UINT8)(p->width)      & 0x00FF;                break;\r
492         case 5:         b = (EPS_UINT8)(p->width >> 8) & 0x00FF;                break;\r
493 \r
494         case 6:         b = (EPS_UINT8)(p->bandPixel)      & 0x00FF;    break;\r
495         case 7:         b = (EPS_UINT8)(p->bandPixel >> 8) & 0x00FF;    break;\r
496 \r
497         case 8:         b = (EPS_UINT8)(p->mode)       & 0x00FF;                break;\r
498         case 9:         b = (unsigned char)(p->mode >> 8)  & 0x00FF;    break;\r
499 \r
500         default:        b = 0;\r
501         }\r
502         return b;\r
503 }\r
504 \r
505 \r
506 static void WriteDataToBuffer(CODINGDATA* const lpcd) \r
507 {\r
508         if (lpcd->leftCount) {\r
509                 *lpcd->lpCurPtr++ = (EPS_UINT8) lpcd->code ;\r
510                 lpcd->leftCount-- ;\r
511                 lpcd->code >>= 8 ;\r
512         }\r
513         lpcd->codeBits -= 8 ;\r
514 }\r
515 \r
516 \r
517 static void CodeHufmanData(const EPS_UINT8 d, CODINGDATA* const lpcd) \r
518 {\r
519         lpcd->code |= ((EPS_UINT32) lpcd->hufCode[d]) << (lpcd->codeBits) ;\r
520         lpcd->codeBits += lpcd->hufCodeLen[d] ;\r
521         \r
522         while (lpcd->codeBits >= 8) WriteDataToBuffer(lpcd) ;\r
523 }\r
524 \r
525 \r
526 static EPS_BOOL MakeHufmanCodeTable(EPS_UINT16 wMode, EPS_UINT16 wQuality, CODINGDATA* lpcd)\r
527 {\r
528         switch (wMode) {\r
529         case EP_COMPRESS20 :\r
530                 MakeHufmanTable1(HufmanDefTable2, lpcd) ;\r
531                 return TRUE ;\r
532         }\r
533 \r
534         return FALSE ;\r
535 }\r
536 \r
537 \r
538 static void MakeHufmanTable1(const EPS_UINT16 cdn[], CODINGDATA* lpcd) \r
539 {\r
540 \r
541         EPS_UINT16 huf, rhuf, temp, i ;\r
542         EPS_INT32 len, num, j ;\r
543 \r
544         huf = 0 ;\r
545         num = 0 ;\r
546         \r
547         for(len = 1 ; len <= 12; len++) {\r
548                 huf <<= 1;\r
549 \r
550                 for(i = 0; i < cdn[len] ; i++) {\r
551                         rhuf = 0 ;\r
552                         temp = huf ;\r
553 \r
554                         for (j = 0 ; j < len ; j++) {\r
555                                 rhuf = (rhuf << 1) | (temp & 1) ;\r
556                                 temp >>= 1 ;\r
557                         }\r
558                         \r
559                         if (num) {\r
560                                 j = (num+1) >> 1 ;\r
561                                 if ((num & 0x1) == 0) j = 256 - j ;\r
562                         }\r
563                         else {\r
564                                 j = 0 ;\r
565                         }\r
566 \r
567                         lpcd->hufCode[j] = rhuf ;\r
568                         lpcd->hufCodeLen[j] = (EPS_UINT8) len ;\r
569 \r
570                         huf ++ ;\r
571                         num ++ ;\r
572                 }\r
573         }\r
574 }\r
575 \r
576 \r
577 /*_______________________________   epson-escpage-comp.c   _____________________________*/\r
578 \r
579 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/\r
580 /*       1         2         3         4         5         6         7         8        */\r
581 /*******************************************|********************************************/\r
582 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
583 /***** End of File *** End of File *** End of File *** End of File *** End of File ******/\r
584 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r