Tizen 2.1 base
[platform/upstream/epson-inkjet-printer-escpr.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         if(dwwkBufferSize == 0){\r
160                 *pulCompressType = 0;\r
161                 return NULL;\r
162         }\r
163 \r
164         if(!(pwkBuffer = (EPS_UINT8*)EPS_ALLOC( dwwkBufferSize ))){\r
165                 *pulCompressType = 0;\r
166                 return NULL;\r
167         }\r
168 \r
169         dwBuffer = (((ulSrcright - ulSrcleft ) * 24 + 31) / 32) * 4 * (ulSrcbottom - ulSrctop );\r
170         if(!(pTmp = (EPS_UINT8*)EPS_ALLOC( dwBuffer ))){\r
171                 EPS_FREE(pwkBuffer );\r
172                 *pulCompressType = 0;\r
173                 return NULL;\r
174         }\r
175 \r
176         dwCompressedSize = EPCompressImage( dwComMode,\r
177                                                                                         ulSrcleft,\r
178                                                                                         ulSrctop,\r
179                                                                                         ulSrcright - ulSrcleft ,\r
180                                                                                         ulSrcbottom - ulSrctop ,\r
181                                                                                         &bmi,\r
182                                                                                         EP_RGB,\r
183                                                                                         pRealBits,\r
184                                                                                         pTmp,\r
185                                                                                         dwBuffer,\r
186                                                                                         pwkBuffer );\r
187 \r
188         EPS_FREE(pwkBuffer);\r
189         if(dwCompressedSize == 0){\r
190                 EPS_FREE(pTmp);\r
191                 *pulCompressType = 0;\r
192                 return NULL;\r
193         }\r
194 \r
195         *pulImageSize = dwCompressedSize;\r
196 \r
197         return pTmp;\r
198 }\r
199 \r
200 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
201 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
202 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
203 /*--------------------               Local Functions               ---------------------*/\r
204 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
205 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
206 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
207 \r
208 static EPS_UINT32  EPGetCompressBufferSize (EPS_UINT32 dwMode)\r
209 {\r
210         EPS_UINT16 mode;\r
211         \r
212         EPS_LOG_FUNCIN\r
213 \r
214         mode = GetCompressMode(dwMode) ;\r
215 \r
216         switch (mode) {\r
217 \r
218         case EP_COMPRESS20 :\r
219                 EPS_RETURN( sizeof(COMPBUFFER20) )\r
220         default:\r
221                 break;\r
222         }\r
223 \r
224         EPS_RETURN( 0 )\r
225 }\r
226 \r
227 \r
228 static EPS_UINT32 EPCompressImage (\r
229                 EPS_UINT32 dwMode,\r
230                 EPS_UINT32 xSrc,\r
231                 EPS_UINT32 ySrc,\r
232                 EPS_UINT32 dwWidth,\r
233                 EPS_UINT32 dwHeight,\r
234                 EPS_BITMAPINFO *lpbmi,\r
235                 EPS_UINT32 biFormat,\r
236                 EPS_UINT8* lpBits,\r
237                 EPS_UINT8* lpBuf,\r
238                 EPS_UINT32 sizeBuf,\r
239                 EPS_UINT8* lpWorkBuf )\r
240 {\r
241         COMPRESSBUFFER* lpCBuf ;\r
242         EPS_UINT32 height ;\r
243 \r
244         EPS_LOG_FUNCIN\r
245 \r
246         if (dwWidth == 0 || dwHeight == 0) {\r
247                 EPS_RETURN( 0 )\r
248         }\r
249         if (lpWorkBuf == NULL) {\r
250                 EPS_RETURN( 0 )\r
251         }\r
252 \r
253         lpCBuf = (COMPRESSBUFFER*) lpWorkBuf ;\r
254                 \r
255         /* Check Width and calculate Scan Size */\r
256 \r
257         if (lpbmi->biWidth <= 0 || (EPS_UINT32) lpbmi->biWidth < xSrc + dwWidth) {\r
258                 EPS_RETURN( 0 )\r
259         }\r
260 \r
261         lpCBuf->dwWidth = dwWidth ;\r
262         lpCBuf->biBitCount = lpbmi->biBitCount ;\r
263         lpCBuf->format = biFormat ;\r
264         \r
265         lpCBuf->nextLine = ((lpbmi->biWidth * lpCBuf->biBitCount + 7) / 8 + 3) & 0xFFFFFFFC ;\r
266         lpCBuf->lpBitsOrg = lpBits + (xSrc*lpCBuf->biBitCount / 8) ;\r
267         /*lpCBuf->bitOffset = (EPS_INT16) (xSrc*lpCBuf->biBitCount % 8) ;*/\r
268         \r
269         /* Check Height and calculate start addr */\r
270         \r
271         lpCBuf->dwHeight = dwHeight ;\r
272         if (lpbmi->biHeight > 0) {\r
273                 /* bottom up bitmap */\r
274                 height = (EPS_UINT32) lpbmi->biHeight ;\r
275                 lpCBuf->lpBitsOrg += lpCBuf->nextLine * (ySrc + dwHeight - 1);\r
276                 lpCBuf->nextLine = -lpCBuf->nextLine ;\r
277         }\r
278         else {\r
279                 /* top down bitmap */\r
280                 height = (EPS_UINT32) -lpbmi->biHeight;\r
281                 lpCBuf->lpBitsOrg += lpCBuf->nextLine * ySrc;\r
282         }\r
283         if (height == 0 || height < ySrc + dwHeight) {\r
284                 EPS_RETURN( 0 )\r
285         }\r
286         \r
287         /* Fill Other fields */\r
288         lpCBuf->wMode = GetCompressMode(dwMode) ;\r
289         lpCBuf->wQuality = GetCompressQuality(dwMode) ;\r
290         lpCBuf->lpBuffer = lpBuf ;\r
291         lpCBuf->sizeBuffer = sizeBuf ;\r
292         lpCBuf->bInvertX = FALSE ;\r
293         \r
294         switch (lpCBuf->wMode) {\r
295         case EP_COMPRESS20 :\r
296                 EPS_RETURN( Compress20((COMPBUFFER20*) lpCBuf) )\r
297         default:\r
298                 break;\r
299         }\r
300         \r
301         EPS_RETURN( 0 )\r
302 }\r
303 \r
304 /*      24BPP Image Compress Mode 20 */\r
305 static EPS_UINT32 Compress20(COMPBUFFER20* lpC20Buf)\r
306 {\r
307         EPS_UINT8* lpSrc ;\r
308         EPS_INT32 nextBand ;\r
309         EPS_UINT32 y, yblock, ymod ;\r
310         EPS_INT32 incptr ;\r
311         \r
312         EPS_LOG_FUNCIN\r
313 \r
314         if (lpC20Buf->cbuf.biBitCount == 24) {\r
315                 incptr = 3 ;\r
316         }\r
317         else if (lpC20Buf->cbuf.biBitCount == 32) {\r
318                 incptr = 4 ;\r
319         }\r
320         else {\r
321                 EPS_RETURN( 0 )\r
322         }\r
323         \r
324         if (lpC20Buf->cbuf.bInvertX) {\r
325                 /* invert image */\r
326                 lpSrc = lpC20Buf->cbuf.lpBitsOrg + (lpC20Buf->cbuf.dwWidth - 1) * incptr ;\r
327                 incptr = -incptr ;\r
328         }\r
329         else {\r
330                 lpSrc = lpC20Buf->cbuf.lpBitsOrg ;\r
331         }\r
332         \r
333         if (lpC20Buf->cbuf.format == EP_RGB) {\r
334                 lpC20Buf->mode[0] = 2 ;\r
335                 lpC20Buf->mode[1] = 1 ;\r
336                 lpC20Buf->mode[2] = 0 ;\r
337         }\r
338         else {\r
339                 lpC20Buf->mode[0] = 0 ;\r
340                 lpC20Buf->mode[1] = 1 ;\r
341                 lpC20Buf->mode[2] = 2 ;\r
342         }\r
343         \r
344         /* Make Hufman Code Table */\r
345         MakeHufmanCodeTable(lpC20Buf->cbuf.wMode, lpC20Buf->cbuf.wQuality, &lpC20Buf->cd) ;\r
346         \r
347         /* Make Block Header */\r
348         lpC20Buf->bh.width              = ConvertEndianWord(lpC20Buf->cbuf.dwWidth) ;\r
349         lpC20Buf->bh.bandPixel  = ConvertEndianWord(BAND_PIXEL) ;\r
350         \r
351         /* Initialize */\r
352         lpC20Buf->cd.lpCurPtr = lpC20Buf->cbuf.lpBuffer ;\r
353         lpC20Buf->cd.leftCount = lpC20Buf->cbuf.sizeBuffer ;\r
354 \r
355         yblock  = lpC20Buf->cbuf.dwHeight / BAND_PIXEL ;\r
356         ymod    = lpC20Buf->cbuf.dwHeight % BAND_PIXEL ;\r
357 \r
358         nextBand = lpC20Buf->cbuf.nextLine * BAND_PIXEL ;\r
359 \r
360         lpC20Buf->bandLimit = SIZEOF_BLOCKHEADER20 + lpC20Buf->cbuf.dwWidth * BAND_PIXEL ;\r
361 \r
362         for (y = 0 ; y < yblock ; y++) {\r
363                 if (! WriteBandData20(BAND_PIXEL, incptr, lpSrc, lpC20Buf)) {\r
364                         EPS_RETURN( 0 )\r
365                 }\r
366                 lpSrc += nextBand ;\r
367         }\r
368         if (ymod) {\r
369                 lpC20Buf->bh.bandPixel  = ConvertEndianWord(ymod) ;\r
370                 lpC20Buf->bandLimit = SIZEOF_BLOCKHEADER20 + lpC20Buf->cbuf.dwWidth * ymod ;\r
371                 \r
372                 if (! WriteBandData20((EPS_UINT16) ymod, incptr, lpSrc, lpC20Buf)) {\r
373                         EPS_RETURN( 0 )\r
374                 }\r
375         }\r
376 \r
377         if (lpC20Buf->cd.leftCount == 0) {\r
378                         EPS_RETURN( 0 )\r
379         }\r
380 \r
381         EPS_RETURN( lpC20Buf->cbuf.sizeBuffer - lpC20Buf->cd.leftCount )\r
382 }\r
383 \r
384 \r
385 static EPS_BOOL WriteBandData20(EPS_INT32 band, EPS_INT32 incptr, EPS_UINT8* lpSrc, COMPBUFFER20* lpC20Buf) \r
386 {\r
387         EPS_UINT32 sizeBlockData ;\r
388         EPS_UINT8* lpBandStart ;\r
389         EPS_UINT32 countBandStart ;\r
390         EPS_UINT8 *lpBand, *lpPt, *lpPrePt;\r
391         EPS_UINT8 left ;\r
392 \r
393         EPS_INT32 i, j ;\r
394         EPS_UINT32 x ;\r
395 \r
396         EPS_LOG_FUNCIN\r
397 \r
398         for (i = 0 ; i <= 2 ; i++) {\r
399                 if (lpC20Buf->cd.leftCount <= SIZEOF_BLOCKHEADER20) {\r
400                         EPS_RETURN( FALSE )\r
401                 }\r
402 \r
403                 lpBandStart = lpC20Buf->cd.lpCurPtr ;\r
404                 countBandStart = lpC20Buf->cd.leftCount ;\r
405 \r
406                 lpC20Buf->cd.lpCurPtr += SIZEOF_BLOCKHEADER20;\r
407                 lpC20Buf->cd.leftCount -= SIZEOF_BLOCKHEADER20;\r
408                 lpC20Buf->cd.code = 0 ;\r
409                 lpC20Buf->cd.codeBits = 0 ;\r
410                 \r
411                 lpBand = lpSrc + i ;\r
412                 lpPt = lpBand ;\r
413                 left = 0 ;\r
414                 \r
415                 for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
416                         CodeHufmanData((EPS_UINT8) (*lpPt-left), &lpC20Buf->cd) ;\r
417                         left = *lpPt ;\r
418                         lpPt += incptr ;\r
419                 }\r
420                 \r
421                 for (j = 1 ; j < band ; j++) {\r
422                         lpPrePt = lpBand ;\r
423                         lpBand += lpC20Buf->cbuf.nextLine ;\r
424                         lpPt = lpBand ;\r
425                         left = 0 ;\r
426                         \r
427                         for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
428                                 CodeHufmanData((EPS_UINT8) (*lpPt-((left+*lpPrePt)>>1)), &lpC20Buf->cd) ;\r
429                                 left = *lpPt ;\r
430                                 lpPt += incptr ;\r
431                                 lpPrePt += incptr ;\r
432                         }\r
433                 }\r
434                 if (lpC20Buf->cd.codeBits) WriteDataToBuffer(&lpC20Buf->cd) ;\r
435                 \r
436                 if (countBandStart <= lpC20Buf->cd.leftCount + lpC20Buf->bandLimit) {\r
437                         /* Write Block Header */\r
438                         sizeBlockData = countBandStart - lpC20Buf->cd.leftCount ;\r
439                         lpC20Buf->bh.size = ConvertEndianDWORD(sizeBlockData) ;\r
440                         lpC20Buf->bh.mode = ConvertEndianWord(MakeCompress20Mode(lpC20Buf->mode[i])) ;\r
441 \r
442                         for (x = 0 ; x < SIZEOF_BLOCKHEADER20 ; x++) {\r
443                                 *lpBandStart++ = GetByteBLOCKHEADER20(&lpC20Buf->bh, x);\r
444                         }\r
445                 }\r
446                 else {\r
447                         /* Output Un-Compress Data */\r
448                         if (countBandStart < lpC20Buf->bandLimit) {\r
449                                 EPS_RETURN( FALSE )\r
450                         }\r
451 \r
452                         sizeBlockData = lpC20Buf->bandLimit ;\r
453                         lpC20Buf->bh.size = ConvertEndianDWORD(sizeBlockData) ;\r
454                         lpC20Buf->bh.mode = ConvertEndianWord(MakeUncompress20Mode(lpC20Buf->mode[i])) ;\r
455 \r
456                         for (x = 0 ; x < SIZEOF_BLOCKHEADER20; x++) {\r
457                                 *lpBandStart++ = GetByteBLOCKHEADER20(&lpC20Buf->bh, x);\r
458                         }\r
459 \r
460                         lpBand = lpSrc + i ;\r
461                         for (j = 0 ; j < band ; j++) {\r
462                                 lpPt = lpBand ;\r
463                                 lpBand += lpC20Buf->cbuf.nextLine ;\r
464                                 for (x = 0 ; x < lpC20Buf->cbuf.dwWidth ; x++) {\r
465                                         *lpBandStart++ = *lpPt ;\r
466                                         lpPt += incptr ;\r
467                                 }\r
468                         }\r
469                         \r
470                         lpC20Buf->cd.lpCurPtr = lpBandStart ;\r
471                         lpC20Buf->cd.leftCount = countBandStart - lpC20Buf->bandLimit ;\r
472                 }\r
473         }\r
474 \r
475         EPS_RETURN( TRUE )\r
476 }\r
477 \r
478 \r
479 static EPS_UINT8 GetByteBLOCKHEADER20(BLOCKHEADER20 *p, EPS_INT32 n)\r
480 {\r
481         EPS_UINT8 b = 0;\r
482         switch(n){\r
483         case 0:         b = (EPS_UINT8)(p->size)       & 0x000000FF;    break;\r
484         case 1:         b = (EPS_UINT8)(p->size >> 8)  & 0x000000FF;    break;\r
485         case 2:         b = (EPS_UINT8)(p->size >> 16) & 0x000000FF;    break;\r
486         case 3:         b = (EPS_UINT8)(p->size >> 24) & 0x000000FF;    break;\r
487 \r
488         case 4:         b = (EPS_UINT8)(p->width)      & 0x00FF;                break;\r
489         case 5:         b = (EPS_UINT8)(p->width >> 8) & 0x00FF;                break;\r
490 \r
491         case 6:         b = (EPS_UINT8)(p->bandPixel)      & 0x00FF;    break;\r
492         case 7:         b = (EPS_UINT8)(p->bandPixel >> 8) & 0x00FF;    break;\r
493 \r
494         case 8:         b = (EPS_UINT8)(p->mode)       & 0x00FF;                break;\r
495         case 9:         b = (unsigned char)(p->mode >> 8)  & 0x00FF;    break;\r
496 \r
497         default:        b = 0;\r
498         }\r
499         return b;\r
500 }\r
501 \r
502 \r
503 static void WriteDataToBuffer(CODINGDATA* const lpcd) \r
504 {\r
505         if (lpcd->leftCount) {\r
506                 *lpcd->lpCurPtr++ = (EPS_UINT8) lpcd->code ;\r
507                 lpcd->leftCount-- ;\r
508                 lpcd->code >>= 8 ;\r
509         }\r
510         lpcd->codeBits -= 8 ;\r
511 }\r
512 \r
513 \r
514 static void CodeHufmanData(const EPS_UINT8 d, CODINGDATA* const lpcd) \r
515 {\r
516         lpcd->code |= ((EPS_UINT32) lpcd->hufCode[d]) << (lpcd->codeBits) ;\r
517         lpcd->codeBits += lpcd->hufCodeLen[d] ;\r
518         \r
519         while (lpcd->codeBits >= 8) WriteDataToBuffer(lpcd) ;\r
520 }\r
521 \r
522 \r
523 static EPS_BOOL MakeHufmanCodeTable(EPS_UINT16 wMode, EPS_UINT16 wQuality, CODINGDATA* lpcd)\r
524 {\r
525         switch (wMode) {\r
526         case EP_COMPRESS20 :\r
527                 MakeHufmanTable1(HufmanDefTable2, lpcd) ;\r
528                 return TRUE ;\r
529         }\r
530 \r
531         return FALSE ;\r
532 }\r
533 \r
534 \r
535 static void MakeHufmanTable1(const EPS_UINT16 cdn[], CODINGDATA* lpcd) \r
536 {\r
537 \r
538         EPS_UINT16 huf, rhuf, temp, i ;\r
539         EPS_INT32 len, num, j ;\r
540 \r
541         huf = 0 ;\r
542         num = 0 ;\r
543         \r
544         for(len = 1 ; len <= 12; len++) {\r
545                 huf <<= 1;\r
546 \r
547                 for(i = 0; i < cdn[len] ; i++) {\r
548                         rhuf = 0 ;\r
549                         temp = huf ;\r
550 \r
551                         for (j = 0 ; j < len ; j++) {\r
552                                 rhuf = (rhuf << 1) | (temp & 1) ;\r
553                                 temp >>= 1 ;\r
554                         }\r
555                         \r
556                         if (num) {\r
557                                 j = (num+1) >> 1 ;\r
558                                 if ((num & 0x1) == 0) j = 256 - j ;\r
559                         }\r
560                         else {\r
561                                 j = 0 ;\r
562                         }\r
563 \r
564                         lpcd->hufCode[j] = rhuf ;\r
565                         lpcd->hufCodeLen[j] = (EPS_UINT8) len ;\r
566 \r
567                         huf ++ ;\r
568                         num ++ ;\r
569                 }\r
570         }\r
571 }\r
572 \r
573 \r
574 /*_______________________________   epson-escpage-comp.c   _____________________________*/\r
575 \r
576 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/\r
577 /*       1         2         3         4         5         6         7         8        */\r
578 /*******************************************|********************************************/\r
579 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
580 /***** End of File *** End of File *** End of File *** End of File *** End of File ******/\r
581 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r