Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / core / src / fxcodec / codec / fx_codec_progress.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../include/fxge/fx_dib.h"\r
8 #include "../../../include/fxcodec/fx_codec.h"\r
9 #include "fx_codec_progress.h"\r
10 void CFXCODEC_WeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, FX_BOOL bInterpol)\r
11 {\r
12     if (m_pWeightTables) {\r
13         FX_Free(m_pWeightTables);\r
14     }\r
15     double scale, base;\r
16     scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len));\r
17     if (dest_len < 0) {\r
18         base = (FX_FLOAT)(src_len);\r
19     } else {\r
20         base = 0.0f;\r
21     }\r
22     m_ItemSize = (int)(sizeof(int) * 2 + sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1));\r
23     m_DestMin = dest_min;\r
24     m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4);\r
25     if(m_pWeightTables == NULL) {\r
26         return;\r
27     }\r
28     if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {\r
29         for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {\r
30             PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);\r
31             double src_pos = dest_pixel * scale + scale / 2 + base;\r
32             if (bInterpol) {\r
33                 pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);\r
34                 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);\r
35                 if (pixel_weights.m_SrcStart < src_min) {\r
36                     pixel_weights.m_SrcStart = src_min;\r
37                 }\r
38                 if (pixel_weights.m_SrcEnd >= src_max) {\r
39                     pixel_weights.m_SrcEnd = src_max - 1;\r
40                 }\r
41                 if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {\r
42                     pixel_weights.m_Weights[0] = 65536;\r
43                 } else {\r
44                     pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);\r
45                     pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];\r
46                 }\r
47             } else {\r
48                 pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos);\r
49                 pixel_weights.m_Weights[0] = 65536;\r
50             }\r
51         }\r
52         return;\r
53     }\r
54     for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {\r
55         PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);\r
56         double src_start = dest_pixel * scale + base;\r
57         double src_end = src_start + scale;\r
58         int start_i, end_i;\r
59         if (src_start < src_end) {\r
60             start_i = (int)FXSYS_floor((FX_FLOAT)src_start);\r
61             end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);\r
62         } else {\r
63             start_i = (int)FXSYS_floor((FX_FLOAT)src_end);\r
64             end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);\r
65         }\r
66         if (start_i < src_min) {\r
67             start_i = src_min;\r
68         }\r
69         if (end_i >= src_max) {\r
70             end_i = src_max - 1;\r
71         }\r
72         if (start_i > end_i) {\r
73             pixel_weights.m_SrcStart = start_i;\r
74             pixel_weights.m_SrcEnd = start_i;\r
75             continue;\r
76         }\r
77         pixel_weights.m_SrcStart = start_i;\r
78         pixel_weights.m_SrcEnd = end_i;\r
79         for (int j = start_i; j <= end_i; j ++) {\r
80             double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale);\r
81             double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale);\r
82             if (dest_start > dest_end) {\r
83                 double temp = dest_start;\r
84                 dest_start = dest_end;\r
85                 dest_end = temp;\r
86             }\r
87             double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel);\r
88             double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end;\r
89             double weight = area_start >= area_end ? 0.0f : area_end - area_start;\r
90             if (weight == 0 && j == end_i) {\r
91                 pixel_weights.m_SrcEnd --;\r
92                 break;\r
93             }\r
94             pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536));\r
95         }\r
96     }\r
97 }\r
98 void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol)\r
99 {\r
100     if (m_pWeightTables) {\r
101         FX_Free(m_pWeightTables);\r
102     }\r
103     double scale = (double)dest_len / (double)src_len;\r
104     m_ItemSize = sizeof(int) * 4;\r
105     int size = dest_len * m_ItemSize + 4;\r
106     m_pWeightTables = FX_Alloc(uint8_t, size);\r
107     if(m_pWeightTables == NULL) {\r
108         return;\r
109     }\r
110     FXSYS_memset32(m_pWeightTables, 0, size);\r
111     if(scale > 1) {\r
112         int pre_des_col = 0;\r
113         for (int src_col = 0; src_col < src_len; src_col++) {\r
114             double des_col_f = src_col * scale;\r
115             int des_col = FXSYS_round((FX_FLOAT)des_col_f);\r
116             PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);\r
117             pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;\r
118             pWeight->m_Weights[0] = 65536;\r
119             pWeight->m_Weights[1] = 0;\r
120             if(src_col == src_len - 1 && des_col < dest_len - 1) {\r
121                 for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; des_col_index++) {\r
122                     pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);\r
123                     pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;\r
124                     pWeight->m_Weights[0] = 65536;\r
125                     pWeight->m_Weights[1] = 0;\r
126                 }\r
127                 return;\r
128             }\r
129             int des_col_len = des_col - pre_des_col;\r
130             for (int des_col_index = pre_des_col + 1; des_col_index < des_col; des_col_index++) {\r
131                 pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);\r
132                 pWeight->m_SrcStart = src_col - 1;\r
133                 pWeight->m_SrcEnd = src_col;\r
134                 pWeight->m_Weights[0] = bInterpol ? FXSYS_round((FX_FLOAT)\r
135                                         (\r
136                                             ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index)\r
137                                             / (FX_FLOAT)des_col_len * 65536\r
138                                         )\r
139                                                                ) : 65536;\r
140                 pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];\r
141             }\r
142             pre_des_col = des_col;\r
143         }\r
144         return;\r
145     }\r
146     for (int des_col = 0; des_col < dest_len; des_col++) {\r
147         double src_col_f = des_col / scale;\r
148         int src_col = FXSYS_round((FX_FLOAT)src_col_f);\r
149         PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);\r
150         pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;\r
151         pWeight->m_Weights[0] = 65536;\r
152         pWeight->m_Weights[1] = 0;\r
153     }\r
154 }\r
155 void CFXCODEC_VertTable::Calc(int dest_len, int src_len)\r
156 {\r
157     if (m_pWeightTables) {\r
158         FX_Free(m_pWeightTables);\r
159     }\r
160     double scale = (double)dest_len / (double)src_len;\r
161     m_ItemSize = sizeof(int) * 4;\r
162     int size = dest_len * m_ItemSize + 4;\r
163     m_pWeightTables = FX_Alloc(uint8_t, size);\r
164     if(m_pWeightTables == NULL) {\r
165         return;\r
166     }\r
167     FXSYS_memset32(m_pWeightTables, 0, size);\r
168     if(scale > 1) {\r
169         double step = 0.0;\r
170         int src_row = 0;\r
171         while ( step < (double)dest_len ) {\r
172             int start_step = (int)step;\r
173             step = scale * (++src_row);\r
174             int end_step = (int)step;\r
175             if(end_step >= dest_len) {\r
176                 end_step = dest_len;\r
177                 for (int des_row = start_step; des_row < end_step; des_row++) {\r
178                     PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);\r
179                     pWeight->m_SrcStart = start_step;\r
180                     pWeight->m_SrcEnd = start_step;\r
181                     pWeight->m_Weights[0] = 65536;\r
182                     pWeight->m_Weights[1] = 0;\r
183                 }\r
184                 return;\r
185             }\r
186             int length = end_step - start_step;\r
187             {\r
188                 PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize);\r
189                 pWeight->m_SrcStart = start_step;\r
190                 pWeight->m_SrcEnd = start_step;\r
191                 pWeight->m_Weights[0] = 65536;\r
192                 pWeight->m_Weights[1] = 0;\r
193             }\r
194             for (int des_row = start_step + 1; des_row < end_step; des_row++) {\r
195                 PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);\r
196                 pWeight->m_SrcStart = start_step;\r
197                 pWeight->m_SrcEnd = end_step;\r
198                 pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / (FX_FLOAT)length * 65536);\r
199                 pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];\r
200             }\r
201         }\r
202     } else {\r
203         for (int des_row = 0; des_row < dest_len; des_row++) {\r
204             PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);\r
205             pWeight->m_SrcStart = des_row;\r
206             pWeight->m_SrcEnd = des_row;\r
207             pWeight->m_Weights[0] = 65536;\r
208             pWeight->m_Weights[1] = 0;\r
209         }\r
210     }\r
211 }\r
212 CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr)\r
213 {\r
214     m_pFile = NULL;\r
215     m_pJpegContext = NULL;\r
216     m_pPngContext = NULL;\r
217     m_pGifContext = NULL;\r
218     m_pBmpContext = NULL;\r
219     m_pTiffContext = NULL;\r
220     m_pCodecMgr = NULL;\r
221     m_pSrcBuf = NULL;\r
222     m_pDecodeBuf = NULL;\r
223     m_pDeviceBitmap = NULL;\r
224     m_pSrcPalette = NULL;\r
225     m_pCodecMgr = pCodecMgr;\r
226     m_offSet = 0;\r
227     m_SrcSize = 0;\r
228     m_ScanlineSize = 0;\r
229     m_SrcWidth = m_SrcHeight = 0;\r
230     m_SrcComponents = 0;\r
231     m_SrcBPC = 0;\r
232     m_SrcPassNumber = 0;\r
233     m_clipBox = FX_RECT(0, 0, 0, 0);\r
234     m_imagType = FXCODEC_IMAGE_UNKNOWN;\r
235     m_status = FXCODEC_STATUS_DECODE_FINISH;\r
236     m_TransMethod = -1;\r
237     m_SrcRow = 0;\r
238     m_SrcFormat = FXCodec_Invalid;\r
239     m_bInterpol = TRUE;\r
240     m_FrameNumber = 0;\r
241     m_FrameCur = 0;\r
242     m_SrcPaletteNumber = 0;\r
243     m_GifPltNumber = 0;\r
244     m_GifBgIndex = 0;\r
245     m_pGifPalette = NULL;\r
246     m_GifTransIndex = -1;\r
247     m_GifFrameRect = FX_RECT(0, 0, 0, 0);\r
248     m_BmpIsTopBottom = FALSE;\r
249 }\r
250 CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder()\r
251 {\r
252     m_pFile = NULL;\r
253     if(m_pJpegContext != NULL) {\r
254         m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext);\r
255     }\r
256     if(m_pPngContext != NULL) {\r
257         m_pCodecMgr->GetPngModule()->Finish(m_pPngContext);\r
258     }\r
259     if(m_pGifContext != NULL) {\r
260         m_pCodecMgr->GetGifModule()->Finish(m_pGifContext);\r
261     }\r
262     if(m_pBmpContext != NULL) {\r
263         m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext);\r
264     }\r
265     if(m_pTiffContext != NULL) {\r
266         m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext);\r
267     }\r
268     if(m_pSrcBuf != NULL) {\r
269         FX_Free(m_pSrcBuf);\r
270     }\r
271     if(m_pDecodeBuf != NULL) {\r
272         FX_Free(m_pDecodeBuf);\r
273     }\r
274     if(m_pSrcPalette != NULL) {\r
275         FX_Free(m_pSrcPalette);\r
276     }\r
277 }\r
278 FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData(ICodec_JpegModule* pJpegModule, FXCODEC_STATUS& err_status)\r
279 {\r
280     FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();\r
281     if (dwSize <= m_offSet) {\r
282         return FALSE;\r
283     }\r
284     dwSize = dwSize - m_offSet;\r
285     FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL);\r
286     if (dwAvail == m_SrcSize) {\r
287         if (dwSize > FXCODEC_BLOCK_SIZE) {\r
288             dwSize = FXCODEC_BLOCK_SIZE;\r
289         }\r
290         m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;\r
291         m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);\r
292         if (!m_pSrcBuf) {\r
293             err_status = FXCODEC_STATUS_ERR_MEMORY;\r
294             return FALSE;\r
295         }\r
296     } else {\r
297         FX_DWORD dwConsume = m_SrcSize - dwAvail;\r
298         if (dwAvail) {\r
299             FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);\r
300         }\r
301         if (dwSize > dwConsume) {\r
302             dwSize = dwConsume;\r
303         }\r
304     }\r
305     if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {\r
306         err_status = FXCODEC_STATUS_ERR_READ;\r
307         return FALSE;\r
308     }\r
309     m_offSet += dwSize;\r
310     pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail);\r
311     return TRUE;\r
312 }\r
313 FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, int width, int height, int bpc, int pass, int* color_type, double* gamma)\r
314 {\r
315     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
316     if(pCodec->m_pDeviceBitmap == NULL) {\r
317         pCodec->m_SrcWidth = width;\r
318         pCodec->m_SrcHeight = height;\r
319         pCodec->m_SrcBPC = bpc;\r
320         pCodec->m_SrcPassNumber = pass;\r
321         pCodec->m_SrcComponents = *color_type == 0 ? 1 :\r
322                                   *color_type == 2 ? 3 :\r
323                                   *color_type == 3 ? 4 :\r
324                                   *color_type == 4 ? 2 :\r
325                                   *color_type == 6 ? 4 : 0;\r
326         pCodec->m_clipBox = FX_RECT(0, 0, width, height);\r
327         return FALSE;\r
328     }\r
329     FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat();\r
330     switch(format) {\r
331         case FXDIB_1bppMask:\r
332         case FXDIB_1bppRgb:\r
333             ASSERT(FALSE);\r
334             return FALSE;\r
335         case FXDIB_8bppMask:\r
336         case FXDIB_8bppRgb:\r
337             *color_type = 0;\r
338             break;\r
339         case FXDIB_Rgb:\r
340             *color_type = 2;\r
341             break;\r
342         case FXDIB_Rgb32:\r
343         case FXDIB_Argb:\r
344             *color_type = 6;\r
345             break;\r
346         default:\r
347             ASSERT(FALSE);\r
348             return FALSE;\r
349     }\r
350     *gamma = FXCODEC_PNG_GAMMA;\r
351     return TRUE;\r
352 }\r
353 FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, int line, FX_LPBYTE& src_buf)\r
354 {\r
355     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
356     CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;\r
357     ASSERT(pDIBitmap != NULL);\r
358     if(pDIBitmap == NULL) {\r
359         return FALSE;\r
360     }\r
361     if(line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) {\r
362         double scale_y = (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height();\r
363         int32_t row = (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY;\r
364         FX_LPBYTE src_scan = (FX_LPBYTE)pDIBitmap->GetScanline(row);\r
365         FX_LPBYTE des_scan = pCodec->m_pDecodeBuf;\r
366         src_buf = pCodec->m_pDecodeBuf;\r
367         int32_t src_Bpp = pDIBitmap->GetBPP() >> 3;\r
368         int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3;\r
369         int32_t src_left = pCodec->m_startX;\r
370         int32_t des_left = pCodec->m_clipBox.left;\r
371         src_scan += src_left * src_Bpp;\r
372         des_scan += des_left * des_Bpp;\r
373         for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) {\r
374             PixelWeight* pPixelWeights = pCodec->m_WeightHorzOO.GetPixelWeight(src_col);\r
375             if(pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) {\r
376                 continue;\r
377             }\r
378             switch(pDIBitmap->GetFormat()) {\r
379                 case FXDIB_1bppMask:\r
380                 case FXDIB_1bppRgb:\r
381                     ASSERT(FALSE);\r
382                     return FALSE;\r
383                 case FXDIB_8bppMask:\r
384                 case FXDIB_8bppRgb: {\r
385                         if(pDIBitmap->GetPalette() != NULL) {\r
386                             return FALSE;\r
387                         }\r
388                         FX_DWORD des_g = 0;\r
389                         des_g += pPixelWeights->m_Weights[0] * src_scan[src_col];\r
390                         des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16);\r
391                     }\r
392                     break;\r
393                 case FXDIB_Rgb:\r
394                 case FXDIB_Rgb32: {\r
395                         FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
396                         FX_LPCBYTE p = src_scan + src_col * src_Bpp;\r
397                         des_b += pPixelWeights->m_Weights[0] * (*p++);\r
398                         des_g += pPixelWeights->m_Weights[0] * (*p++);\r
399                         des_r += pPixelWeights->m_Weights[0] * (*p);\r
400                         FX_LPBYTE pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];\r
401                         *pDes++ = (uint8_t)((des_b) >> 16);\r
402                         *pDes++ = (uint8_t)((des_g) >> 16);\r
403                         *pDes   = (uint8_t)((des_r) >> 16);\r
404                     }\r
405                     break;\r
406                 case FXDIB_Argb: {\r
407                         FX_DWORD des_r = 0, des_g = 0, des_b = 0;\r
408                         FX_LPCBYTE p = src_scan + src_col * src_Bpp;\r
409                         des_b += pPixelWeights->m_Weights[0] * (*p++);\r
410                         des_g += pPixelWeights->m_Weights[0] * (*p++);\r
411                         des_r += pPixelWeights->m_Weights[0] * (*p++);\r
412                         FX_LPBYTE pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];\r
413                         *pDes++ = (uint8_t)((des_b) >> 16);\r
414                         *pDes++ = (uint8_t)((des_g) >> 16);\r
415                         *pDes++ = (uint8_t)((des_r) >> 16);\r
416                         *pDes   = *p;\r
417                     }\r
418                     break;\r
419                 default:\r
420                     return FALSE;\r
421             }\r
422         }\r
423     }\r
424     return TRUE;\r
425 }\r
426 void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, int32_t des_line, FX_LPBYTE src_scan, FXCodec_Format src_format)\r
427 {\r
428     FX_LPBYTE des_scan = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_line);\r
429     int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;\r
430     int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3;\r
431     int32_t src_left = m_clipBox.left;\r
432     int32_t des_left = m_startX;\r
433     src_scan += src_left * src_Bpp;\r
434     des_scan += des_left * des_Bpp;\r
435     for (int32_t des_col = 0; des_col < m_sizeX; des_col++) {\r
436         PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col);\r
437         switch(pDeviceBitmap->GetFormat()) {\r
438             case FXDIB_1bppMask:\r
439             case FXDIB_1bppRgb:\r
440                 ASSERT(FALSE);\r
441                 return;\r
442             case FXDIB_8bppMask:\r
443             case FXDIB_8bppRgb: {\r
444                     if(pDeviceBitmap->GetPalette() != NULL) {\r
445                         return;\r
446                     }\r
447                     FX_DWORD des_g = 0;\r
448                     des_g += pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];\r
449                     des_g += pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];\r
450                     *des_scan++ = (uint8_t)(des_g >> 16);\r
451                 }\r
452                 break;\r
453             case FXDIB_Rgb:\r
454             case FXDIB_Rgb32: {\r
455                     FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
456                     FX_LPCBYTE p = src_scan;\r
457                     p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;\r
458                     des_b += pPixelWeights->m_Weights[0] * (*p++);\r
459                     des_g += pPixelWeights->m_Weights[0] * (*p++);\r
460                     des_r += pPixelWeights->m_Weights[0] * (*p);\r
461                     p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;\r
462                     des_b += pPixelWeights->m_Weights[1] * (*p++);\r
463                     des_g += pPixelWeights->m_Weights[1] * (*p++);\r
464                     des_r += pPixelWeights->m_Weights[1] * (*p);\r
465                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
466                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
467                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
468                     des_scan += des_Bpp - 3;\r
469                 }\r
470                 break;\r
471             case FXDIB_Argb: {\r
472                     FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;\r
473                     FX_LPCBYTE p = src_scan;\r
474                     p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;\r
475                     des_b += pPixelWeights->m_Weights[0] * (*p++);\r
476                     des_g += pPixelWeights->m_Weights[0] * (*p++);\r
477                     des_r += pPixelWeights->m_Weights[0] * (*p++);\r
478                     des_a += pPixelWeights->m_Weights[0] * (*p);\r
479                     p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;\r
480                     des_b += pPixelWeights->m_Weights[1] * (*p++);\r
481                     des_g += pPixelWeights->m_Weights[1] * (*p++);\r
482                     des_r += pPixelWeights->m_Weights[1] * (*p++);\r
483                     des_a += pPixelWeights->m_Weights[1] * (*p);\r
484                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
485                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
486                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
487                     *des_scan++ = (uint8_t)((des_a) >> 16);\r
488                 }\r
489                 break;\r
490             default:\r
491                 return;\r
492         }\r
493     }\r
494 }\r
495 void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, int pass, int line)\r
496 {\r
497     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
498     CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;\r
499     ASSERT(pDIBitmap != NULL);\r
500     int src_top = pCodec->m_clipBox.top;\r
501     int src_bottom = pCodec->m_clipBox.bottom;\r
502     int des_top = pCodec->m_startY;\r
503     int src_hei = pCodec->m_clipBox.Height();\r
504     int des_hei = pCodec->m_sizeY;\r
505     if(line >= src_top && line < src_bottom) {\r
506         double scale_y = (double)des_hei / (double)src_hei;\r
507         int src_row = line - src_top;\r
508         int des_row = (int)(src_row * scale_y)  + des_top;\r
509         if(des_row >= des_top + des_hei)        {\r
510             return;\r
511         }\r
512         pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);\r
513         if(pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) {\r
514             pCodec->ResampleVert(pDIBitmap, scale_y, des_row);\r
515             return;\r
516         }\r
517         if(pass == 6 && scale_y > 1.0) {\r
518             pCodec->ResampleVert(pDIBitmap, scale_y, des_row);\r
519         }\r
520     }\r
521 }\r
522 FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, FXCODEC_STATUS& err_status)\r
523 {\r
524     FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();\r
525     if (dwSize <= m_offSet) {\r
526         return FALSE;\r
527     }\r
528     dwSize = dwSize - m_offSet;\r
529     FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL);\r
530     if (dwAvail == m_SrcSize) {\r
531         if (dwSize > FXCODEC_BLOCK_SIZE) {\r
532             dwSize = FXCODEC_BLOCK_SIZE;\r
533         }\r
534         m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;\r
535         m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);\r
536         if (!m_pSrcBuf) {\r
537             err_status = FXCODEC_STATUS_ERR_MEMORY;\r
538             return FALSE;\r
539         }\r
540     } else {\r
541         FX_DWORD dwConsume = m_SrcSize - dwAvail;\r
542         if (dwAvail) {\r
543             FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);\r
544         }\r
545         if (dwSize > dwConsume) {\r
546             dwSize = dwConsume;\r
547         }\r
548     }\r
549     if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {\r
550         err_status = FXCODEC_STATUS_ERR_READ;\r
551         return FALSE;\r
552     }\r
553     m_offSet += dwSize;\r
554     pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail);\r
555     return TRUE;\r
556 }\r
557 void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback(void* pModule, FX_DWORD& cur_pos)\r
558 {\r
559     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
560     FX_DWORD remain_size = pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext);\r
561     cur_pos = pCodec->m_offSet - remain_size;\r
562 }\r
563 FX_LPBYTE CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback(void* pModule, int32_t frame_num, int32_t pal_size)\r
564 {\r
565     return FX_Alloc(uint8_t, pal_size);\r
566 }\r
567 FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void* pModule, FX_DWORD rcd_pos, const FX_RECT& img_rc,\r
568         int32_t pal_num, void* pal_ptr,\r
569         int32_t delay_time, FX_BOOL user_input,\r
570         int32_t trans_index, int32_t disposal_method, FX_BOOL interlace)\r
571 {\r
572     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
573     pCodec->m_offSet = rcd_pos;\r
574     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;\r
575     if(!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), error_status)) {\r
576         return FALSE;\r
577     }\r
578     FX_LPBYTE pPalette = NULL;\r
579     if(pal_num != 0 && pal_ptr) {\r
580         pPalette = (FX_LPBYTE)pal_ptr;\r
581     } else {\r
582         pal_num = pCodec->m_GifPltNumber;\r
583         pPalette = pCodec->m_pGifPalette;\r
584     }\r
585     if(pCodec->m_pSrcPalette == NULL) {\r
586         pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num);\r
587     } else if(pal_num > pCodec->m_SrcPaletteNumber) {\r
588         pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num);\r
589     }\r
590     if(pCodec->m_pSrcPalette == NULL) {\r
591         return FALSE;\r
592     }\r
593     pCodec->m_SrcPaletteNumber = pal_num;\r
594     for (int i = 0; i < pal_num; i++) {\r
595         register FX_DWORD j = i * 3;\r
596         pCodec->m_pSrcPalette[i] =\r
597             ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]);\r
598     }\r
599     pCodec->m_GifTransIndex = trans_index;\r
600     pCodec->m_GifFrameRect = img_rc;\r
601     pCodec->m_SrcPassNumber = interlace ? 4 : 1;\r
602     int32_t pal_index = pCodec->m_GifBgIndex;\r
603     CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap;\r
604     if (trans_index >= pal_num) {\r
605         trans_index = -1;\r
606     }\r
607     if (trans_index != -1) {\r
608         pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff;\r
609         if (pDevice->HasAlpha()) {\r
610             pal_index = trans_index;\r
611         }\r
612     }\r
613     int startX = pCodec->m_startX;\r
614     int startY = pCodec->m_startY;\r
615     int sizeX = pCodec->m_sizeX;\r
616     int sizeY = pCodec->m_sizeY;\r
617     int Bpp = pDevice->GetBPP() / 8;\r
618     FX_ARGB argb = pCodec->m_pSrcPalette[pal_index];\r
619     for (int row = 0; row < sizeY; row ++) {\r
620         FX_LPBYTE pScanline = (FX_LPBYTE)pDevice->GetScanline(row + startY) + startX * Bpp;\r
621         switch(pCodec->m_TransMethod) {\r
622             case 3:     {\r
623                     uint8_t gray = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));\r
624                     FXSYS_memset8(pScanline, gray, sizeX);\r
625                     break;\r
626                 }\r
627             case 8:     {\r
628                     for (int col = 0; col < sizeX; col ++) {\r
629                         *pScanline++ = FXARGB_B(argb);\r
630                         *pScanline++ = FXARGB_G(argb);\r
631                         *pScanline++ = FXARGB_R(argb);\r
632                         pScanline += Bpp - 3;\r
633                     }\r
634                     break;\r
635                 }\r
636             case 12: {\r
637                     for (int col = 0; col < sizeX; col ++) {\r
638                         FXARGB_SETDIB(pScanline, argb);\r
639                         pScanline += 4;\r
640                     }\r
641                     break;\r
642                 }\r
643         }\r
644     }\r
645     return TRUE;\r
646 }\r
647 void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, int32_t row_num, FX_LPBYTE row_buf)\r
648 {\r
649     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
650     CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;\r
651     ASSERT(pDIBitmap != NULL);\r
652     int32_t img_width = pCodec->m_GifFrameRect.Width();\r
653     if (!pDIBitmap->HasAlpha()) {\r
654         FX_LPBYTE byte_ptr = row_buf;\r
655         for (int i = 0; i < img_width; i++ ) {\r
656             if(*byte_ptr == pCodec->m_GifTransIndex) {\r
657                 *byte_ptr = pCodec->m_GifBgIndex;\r
658             }\r
659             byte_ptr++;\r
660         }\r
661     }\r
662     int32_t pal_index = pCodec->m_GifBgIndex;\r
663     if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) {\r
664         pal_index = pCodec->m_GifTransIndex;\r
665     }\r
666     FXSYS_memset8(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth);\r
667     FX_BOOL bLastPass = ((row_num % 2) == 1) ? TRUE : FALSE;\r
668     int32_t line = row_num + pCodec->m_GifFrameRect.top;\r
669     int32_t left = pCodec->m_GifFrameRect.left;\r
670     FXSYS_memcpy32(pCodec->m_pDecodeBuf + left, row_buf, img_width);\r
671     int src_top = pCodec->m_clipBox.top;\r
672     int src_bottom = pCodec->m_clipBox.bottom;\r
673     int des_top = pCodec->m_startY;\r
674     int src_hei = pCodec->m_clipBox.Height();\r
675     int des_hei = pCodec->m_sizeY;\r
676     if(line >= src_top && line < src_bottom) {\r
677         double scale_y = (double)des_hei / (double)src_hei;\r
678         int src_row = line - src_top;\r
679         int des_row = (int)(src_row * scale_y)  + des_top;\r
680         if(des_row >= des_top + des_hei)        {\r
681             return;\r
682         }\r
683         pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);\r
684         if(scale_y > 1.0 && (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) {\r
685             pCodec->ResampleVert(pDIBitmap, scale_y, des_row);\r
686             return;\r
687         }\r
688         if(scale_y > 1.0) {\r
689             int des_bottom = des_top + pCodec->m_sizeY;\r
690             int des_Bpp = pDIBitmap->GetBPP() >> 3;\r
691             FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp;\r
692             if(des_row + (int)scale_y >= des_bottom - 1) {\r
693                 FX_LPBYTE scan_src = (FX_LPBYTE)pDIBitmap->GetScanline(des_row) + des_ScanOffet;\r
694                 int cur_row = des_row;\r
695                 while (++cur_row < des_bottom) {\r
696                     FX_LPBYTE scan_des = (FX_LPBYTE)pDIBitmap->GetScanline(cur_row) + des_ScanOffet;\r
697                     FX_DWORD size = pCodec->m_sizeX * des_Bpp;\r
698                     FXSYS_memcpy32(scan_des, scan_src, size);\r
699                 }\r
700             }\r
701             if(bLastPass) {\r
702                 pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row);\r
703             }\r
704         }\r
705     }\r
706 }\r
707 void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)\r
708 {\r
709     int des_Bpp = pDeviceBitmap->GetBPP() >> 3;\r
710     FX_DWORD des_ScanOffet = m_startX * des_Bpp;\r
711     int des_top = m_startY;\r
712     int des_row_1 = des_row - int(2 * scale_y);\r
713     if(des_row_1 < des_top) {\r
714         des_row_1 = des_top;\r
715     }\r
716     for (; des_row_1 < des_row; des_row_1++) {\r
717         FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;\r
718         PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);\r
719         FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;\r
720         FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;\r
721         for (int des_col = 0; des_col < m_sizeX; des_col++) {\r
722             switch(pDeviceBitmap->GetFormat()) {\r
723                 case FXDIB_Invalid:\r
724                 case FXDIB_1bppMask:\r
725                 case FXDIB_1bppRgb:\r
726                     return;\r
727                 case FXDIB_8bppMask:\r
728                 case FXDIB_8bppRgb: {\r
729                         if(pDeviceBitmap->GetPalette() != NULL) {\r
730                             return;\r
731                         }\r
732                         int des_g = 0;\r
733                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
734                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
735                         *scan_des++ = (uint8_t)(des_g >> 16);\r
736                     }\r
737                     break;\r
738                 case FXDIB_Rgb:\r
739                 case FXDIB_Rgb32: {\r
740                         FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
741                         des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
742                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
743                         des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
744                         scan_src1 += des_Bpp - 3;\r
745                         des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
746                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
747                         des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
748                         scan_src2 += des_Bpp - 3;\r
749                         *scan_des++ = (uint8_t)((des_b) >> 16);\r
750                         *scan_des++ = (uint8_t)((des_g) >> 16);\r
751                         *scan_des++ = (uint8_t)((des_r) >> 16);\r
752                         scan_des += des_Bpp - 3;\r
753                     }\r
754                     break;\r
755                 case FXDIB_Argb: {\r
756                         FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;\r
757                         des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
758                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
759                         des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
760                         des_a += pWeight->m_Weights[0] * (*scan_src1++);\r
761                         des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
762                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
763                         des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
764                         des_a += pWeight->m_Weights[1] * (*scan_src2++);\r
765                         *scan_des++ = (uint8_t)((des_b) >> 16);\r
766                         *scan_des++ = (uint8_t)((des_g) >> 16);\r
767                         *scan_des++ = (uint8_t)((des_r) >> 16);\r
768                         *scan_des++ = (uint8_t)((des_a) >> 16);\r
769                     }\r
770                     break;\r
771                 default:\r
772                     return;\r
773             }\r
774         }\r
775     }\r
776     int des_bottom = des_top + m_sizeY - 1;\r
777     if(des_row + (int)(2 * scale_y) >= des_bottom && des_row + (int)scale_y < des_bottom) {\r
778         GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y);\r
779     }\r
780 }\r
781 FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, FXCODEC_STATUS& err_status)\r
782 {\r
783     FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();\r
784     if (dwSize <= m_offSet) {\r
785         return FALSE;\r
786     }\r
787     dwSize = dwSize - m_offSet;\r
788     FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL);\r
789     if (dwAvail == m_SrcSize) {\r
790         if (dwSize > FXCODEC_BLOCK_SIZE) {\r
791             dwSize = FXCODEC_BLOCK_SIZE;\r
792         }\r
793         m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;\r
794         m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);\r
795         if (!m_pSrcBuf) {\r
796             err_status = FXCODEC_STATUS_ERR_MEMORY;\r
797             return FALSE;\r
798         }\r
799     } else {\r
800         FX_DWORD dwConsume = m_SrcSize - dwAvail;\r
801         if (dwAvail) {\r
802             FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);\r
803         }\r
804         if (dwSize > dwConsume) {\r
805             dwSize = dwConsume;\r
806         }\r
807     }\r
808     if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {\r
809         err_status = FXCODEC_STATUS_ERR_READ;\r
810         return FALSE;\r
811     }\r
812     m_offSet += dwSize;\r
813     pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail);\r
814     return TRUE;\r
815 }\r
816 FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback(void* pModule, FX_DWORD rcd_pos)\r
817 {\r
818     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
819     pCodec->m_offSet = rcd_pos;\r
820     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;\r
821     if(!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), error_status)) {\r
822         return FALSE;\r
823     }\r
824     return TRUE;\r
825 }\r
826 void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, int32_t row_num, FX_LPBYTE row_buf)\r
827 {\r
828     CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;\r
829     CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;\r
830     ASSERT(pDIBitmap != NULL);\r
831     FXSYS_memcpy32(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize);\r
832     int src_top = pCodec->m_clipBox.top;\r
833     int src_bottom = pCodec->m_clipBox.bottom;\r
834     int des_top = pCodec->m_startY;\r
835     int src_hei = pCodec->m_clipBox.Height();\r
836     int des_hei = pCodec->m_sizeY;\r
837     if(row_num >= src_top && row_num < src_bottom) {\r
838         double scale_y = (double)des_hei / (double)src_hei;\r
839         int src_row = row_num - src_top;\r
840         int des_row = (int)(src_row * scale_y)  + des_top;\r
841         if(des_row >= des_top + des_hei)        {\r
842             return;\r
843         }\r
844         pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);\r
845         if(scale_y > 1.0) {\r
846             if(pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) {\r
847                 pCodec->ResampleVert(pDIBitmap, scale_y, des_row);\r
848                 return;\r
849             } else {\r
850                 pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row);\r
851             }\r
852         }\r
853     }\r
854 }\r
855 void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)\r
856 {\r
857     int des_Bpp = pDeviceBitmap->GetBPP() >> 3;\r
858     FX_DWORD des_ScanOffet = m_startX * des_Bpp;\r
859     int des_top = m_startY;\r
860     int des_bottom = m_startY + m_sizeY;\r
861     int des_row_1 = des_row + int(scale_y);\r
862     if(des_row_1 >= des_bottom - 1) {\r
863         FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
864         while (++des_row < des_bottom) {\r
865             FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
866             FX_DWORD size = m_sizeX * des_Bpp;\r
867             FXSYS_memcpy32(scan_des, scan_src, size);\r
868         }\r
869         return;\r
870     }\r
871     for (; des_row_1 > des_row; des_row_1--) {\r
872         FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;\r
873         PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);\r
874         FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;\r
875         FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;\r
876         for (int des_col = 0; des_col < m_sizeX; des_col++) {\r
877             switch(pDeviceBitmap->GetFormat()) {\r
878                 case FXDIB_Invalid:\r
879                 case FXDIB_1bppMask:\r
880                 case FXDIB_1bppRgb:\r
881                     return;\r
882                 case FXDIB_8bppMask:\r
883                 case FXDIB_8bppRgb: {\r
884                         if(pDeviceBitmap->GetPalette() != NULL) {\r
885                             return;\r
886                         }\r
887                         int des_g = 0;\r
888                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
889                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
890                         *scan_des++ = (uint8_t)(des_g >> 16);\r
891                     }\r
892                     break;\r
893                 case FXDIB_Rgb:\r
894                 case FXDIB_Rgb32: {\r
895                         FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
896                         des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
897                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
898                         des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
899                         scan_src1 += des_Bpp - 3;\r
900                         des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
901                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
902                         des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
903                         scan_src2 += des_Bpp - 3;\r
904                         *scan_des++ = (uint8_t)((des_b) >> 16);\r
905                         *scan_des++ = (uint8_t)((des_g) >> 16);\r
906                         *scan_des++ = (uint8_t)((des_r) >> 16);\r
907                         scan_des += des_Bpp - 3;\r
908                     }\r
909                     break;\r
910                 case FXDIB_Argb: {\r
911                         FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;\r
912                         des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
913                         des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
914                         des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
915                         des_a += pWeight->m_Weights[0] * (*scan_src1++);\r
916                         des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
917                         des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
918                         des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
919                         des_a += pWeight->m_Weights[1] * (*scan_src2++);\r
920                         *scan_des++ = (uint8_t)((des_b) >> 16);\r
921                         *scan_des++ = (uint8_t)((des_g) >> 16);\r
922                         *scan_des++ = (uint8_t)((des_r) >> 16);\r
923                         *scan_des++ = (uint8_t)((des_a) >> 16);\r
924                     }\r
925                     break;\r
926                 default:\r
927                     return;\r
928             }\r
929         }\r
930     }\r
931 }\r
932 FX_BOOL CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute)\r
933 {\r
934     m_offSet = 0;\r
935     FX_DWORD size = (FX_DWORD)m_pFile->GetSize();\r
936     if(size > FXCODEC_BLOCK_SIZE) {\r
937         size = FXCODEC_BLOCK_SIZE;\r
938     }\r
939     if(m_pSrcBuf != NULL) {\r
940         FX_Free(m_pSrcBuf);\r
941         m_pSrcBuf = NULL;\r
942     }\r
943     m_pSrcBuf = FX_Alloc(uint8_t, size);\r
944     if(m_pSrcBuf == NULL) {\r
945         m_status = FXCODEC_STATUS_ERR_MEMORY;\r
946         return FALSE;\r
947     }\r
948     FXSYS_memset32(m_pSrcBuf, 0, size);\r
949     m_SrcSize = size;\r
950     switch(imageType) {\r
951         case FXCODEC_IMAGE_BMP: {\r
952                 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();\r
953                 if(pBmpModule == NULL) {\r
954                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
955                     return FALSE;\r
956                 }\r
957                 pBmpModule->InputImagePositionBufCallback = BmpInputImagePositionBufCallback;\r
958                 pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback;\r
959                 m_pBmpContext = pBmpModule->Start((void*)this);\r
960                 if(m_pBmpContext == NULL) {\r
961                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
962                     return FALSE;\r
963                 }\r
964                 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);\r
965                 if(!bResult) {\r
966                     m_status = FXCODEC_STATUS_ERR_READ;\r
967                     return FALSE;\r
968                 }\r
969                 m_offSet += size;\r
970                 pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size);\r
971                 FX_DWORD* pPalette = NULL;\r
972                 int32_t readResult = pBmpModule->ReadHeader(m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,\r
973                                       &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);\r
974                 while(readResult == 2) {\r
975                     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;\r
976                     if(!BmpReadMoreData(pBmpModule, error_status)) {\r
977                         m_status = error_status;\r
978                         return FALSE;\r
979                     }\r
980                     readResult = pBmpModule->ReadHeader(m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,\r
981                                                         &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);\r
982                 }\r
983                 if(readResult == 1) {\r
984                     m_SrcBPC = 8;\r
985                     m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);\r
986                     if(m_pSrcPalette != NULL) {\r
987                         FX_Free(m_pSrcPalette);\r
988                         m_pSrcPalette = NULL;\r
989                     }\r
990                     if (m_SrcPaletteNumber) {\r
991                         m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber);\r
992                         if(m_pSrcPalette == NULL) {\r
993                             m_status = FXCODEC_STATUS_ERR_MEMORY;\r
994                             return FALSE;\r
995                         }\r
996                         FXSYS_memcpy32(m_pSrcPalette, pPalette, m_SrcPaletteNumber * sizeof(FX_DWORD));\r
997                     }\r
998                     return TRUE;\r
999                 }\r
1000                 if(m_pBmpContext != NULL) {\r
1001                     pBmpModule->Finish(m_pBmpContext);\r
1002                     m_pBmpContext = NULL;\r
1003                 }\r
1004                 m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1005                 return FALSE;\r
1006             }\r
1007             break;\r
1008         case FXCODEC_IMAGE_JPG: {\r
1009                 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();\r
1010                 if(pJpegModule == NULL) {\r
1011                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1012                     return FALSE;\r
1013                 }\r
1014                 m_pJpegContext = pJpegModule->Start();\r
1015                 if(m_pJpegContext == NULL) {\r
1016                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1017                     return FALSE;\r
1018                 }\r
1019                 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);\r
1020                 if(!bResult) {\r
1021                     m_status = FXCODEC_STATUS_ERR_READ;\r
1022                     return FALSE;\r
1023                 }\r
1024                 m_offSet += size;\r
1025                 pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size);\r
1026                 int32_t readResult = pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, &m_SrcComponents, pAttribute);\r
1027                 while(readResult == 2) {\r
1028                     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;\r
1029                     if(!JpegReadMoreData(pJpegModule, error_status)) {\r
1030                         m_status = error_status;\r
1031                         return FALSE;\r
1032                     }\r
1033                     readResult = pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, &m_SrcComponents, pAttribute);\r
1034                 }\r
1035                 if(!readResult) {\r
1036                     m_SrcBPC = 8;\r
1037                     m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);\r
1038                     return TRUE;\r
1039                 }\r
1040                 if(m_pJpegContext != NULL) {\r
1041                     pJpegModule->Finish(m_pJpegContext);\r
1042                     m_pJpegContext = NULL;\r
1043                 }\r
1044                 m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1045                 return FALSE;\r
1046             }\r
1047             break;\r
1048         case FXCODEC_IMAGE_PNG: {\r
1049                 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();\r
1050                 if(pPngModule == NULL) {\r
1051                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1052                     return FALSE;\r
1053                 }\r
1054                 pPngModule->ReadHeaderCallback = CCodec_ProgressiveDecoder::PngReadHeaderFunc;\r
1055                 pPngModule->AskScanlineBufCallback = CCodec_ProgressiveDecoder::PngAskScanlineBufFunc;\r
1056                 pPngModule->FillScanlineBufCompletedCallback = CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc;\r
1057                 m_pPngContext = pPngModule->Start((void*)this);\r
1058                 if(m_pPngContext == NULL) {\r
1059                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1060                     return FALSE;\r
1061                 }\r
1062                 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);\r
1063                 if(!bResult) {\r
1064                     m_status = FXCODEC_STATUS_ERR_READ;\r
1065                     return FALSE;\r
1066                 }\r
1067                 m_offSet += size;\r
1068                 bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute);\r
1069                 while(bResult) {\r
1070                     FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet;\r
1071                     FX_DWORD input_size = remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;\r
1072                     if(input_size == 0) {\r
1073                         if(m_pPngContext != NULL) {\r
1074                             pPngModule->Finish(m_pPngContext);\r
1075                         }\r
1076                         m_pPngContext = NULL;\r
1077                         m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1078                         return FALSE;\r
1079                     }\r
1080                     if(m_pSrcBuf != NULL && input_size > m_SrcSize) {\r
1081                         FX_Free(m_pSrcBuf);\r
1082                         m_pSrcBuf = FX_Alloc(uint8_t, input_size);\r
1083                         if(m_pSrcBuf == NULL) {\r
1084                             m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1085                             return FALSE;\r
1086                         }\r
1087                         FXSYS_memset32(m_pSrcBuf, 0, input_size);\r
1088                         m_SrcSize = input_size;\r
1089                     }\r
1090                     bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);\r
1091                     if(!bResult) {\r
1092                         m_status = FXCODEC_STATUS_ERR_READ;\r
1093                         return FALSE;\r
1094                     }\r
1095                     m_offSet += input_size;\r
1096                     bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute);\r
1097                 }\r
1098                 ASSERT(!bResult);\r
1099                 if(m_pPngContext != NULL) {\r
1100                     pPngModule->Finish(m_pPngContext);\r
1101                     m_pPngContext = NULL;\r
1102                 }\r
1103                 if(m_SrcPassNumber == 0) {\r
1104                     m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1105                     return FALSE;\r
1106                 }\r
1107             }\r
1108             break;\r
1109         case FXCODEC_IMAGE_GIF: {\r
1110                 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();\r
1111                 if(pGifModule == NULL) {\r
1112                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1113                     return FALSE;\r
1114                 }\r
1115                 pGifModule->RecordCurrentPositionCallback = CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback;\r
1116                 pGifModule->AskLocalPaletteBufCallback = CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback;\r
1117                 pGifModule->InputRecordPositionBufCallback = CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback;\r
1118                 pGifModule->ReadScanlineCallback = CCodec_ProgressiveDecoder::GifReadScanlineCallback;\r
1119                 m_pGifContext = pGifModule->Start((void*)this);\r
1120                 if(m_pGifContext == NULL) {\r
1121                     m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1122                     return FALSE;\r
1123                 }\r
1124                 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);\r
1125                 if(!bResult) {\r
1126                     m_status = FXCODEC_STATUS_ERR_READ;\r
1127                     return FALSE;\r
1128                 }\r
1129                 m_offSet += size;\r
1130                 pGifModule->Input(m_pGifContext, m_pSrcBuf, size);\r
1131                 m_SrcComponents = 1;\r
1132                 int32_t readResult = pGifModule->ReadHeader(m_pGifContext, &m_SrcWidth, &m_SrcHeight,\r
1133                                       &m_GifPltNumber, (void**)&m_pGifPalette, &m_GifBgIndex);\r
1134                 while(readResult == 2) {\r
1135                     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;\r
1136                     if(!GifReadMoreData(pGifModule, error_status)) {\r
1137                         m_status = error_status;\r
1138                         return FALSE;\r
1139                     }\r
1140                     readResult = pGifModule->ReadHeader(m_pGifContext, &m_SrcWidth, &m_SrcHeight,\r
1141                                                         &m_GifPltNumber, (void**)&m_pGifPalette, &m_GifBgIndex);\r
1142                 }\r
1143                 if(readResult == 1) {\r
1144                     m_SrcBPC = 8;\r
1145                     m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);\r
1146                     return TRUE;\r
1147                 }\r
1148                 if(m_pGifContext != NULL) {\r
1149                     pGifModule->Finish(m_pGifContext);\r
1150                     m_pGifContext = NULL;\r
1151                 }\r
1152                 m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1153                 return FALSE;\r
1154             }\r
1155             break;\r
1156         case FXCODEC_IMAGE_TIF: {\r
1157                 ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();\r
1158                 if(pTiffModule == NULL) {\r
1159                     m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1160                     return FALSE;\r
1161                 }\r
1162                 m_pTiffContext = pTiffModule->CreateDecoder(m_pFile);\r
1163                 if(m_pTiffContext == NULL) {\r
1164                     m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1165                     return FALSE;\r
1166                 }\r
1167                 int32_t frames = 0;\r
1168                 pTiffModule->GetFrames(m_pTiffContext, frames);\r
1169                 FX_DWORD bpc;\r
1170                 FX_BOOL ret = pTiffModule->LoadFrameInfo(m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, (FX_DWORD&)m_SrcComponents, bpc, pAttribute);\r
1171                 m_SrcComponents = 4;\r
1172                 m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);\r
1173                 if(!ret) {\r
1174                     pTiffModule->DestroyDecoder(m_pTiffContext);\r
1175                     (m_pTiffContext = NULL);\r
1176                     (m_status = FXCODEC_STATUS_ERR_FORMAT);\r
1177                     return FALSE;\r
1178                 }\r
1179             }\r
1180             break;\r
1181         default:\r
1182             m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1183             return FALSE;\r
1184     }\r
1185     return TRUE;\r
1186 }\r
1187 FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(IFX_FileRead* pFile, FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute)\r
1188 {\r
1189     switch(m_status) {\r
1190         case FXCODEC_STATUS_FRAME_READY:\r
1191         case FXCODEC_STATUS_FRAME_TOBECONTINUE:\r
1192         case FXCODEC_STATUS_DECODE_READY:\r
1193         case FXCODEC_STATUS_DECODE_TOBECONTINUE:\r
1194             return FXCODEC_STATUS_ERROR;\r
1195         default:\r
1196             ;\r
1197     }\r
1198     if(pFile == NULL) {\r
1199         m_status = FXCODEC_STATUS_ERR_PARAMS;\r
1200         m_pFile = NULL;\r
1201         return m_status;\r
1202     }\r
1203     m_pFile = pFile;\r
1204     m_offSet = 0;\r
1205     m_SrcWidth = m_SrcHeight = 0;\r
1206     m_SrcComponents = m_SrcBPC = 0;\r
1207     m_clipBox = FX_RECT(0, 0, 0, 0);\r
1208     m_startX = m_startY = 0;\r
1209     m_sizeX = m_sizeY = 0;\r
1210     m_SrcPassNumber = 0;\r
1211     if(imageType != FXCODEC_IMAGE_UNKNOWN &&\r
1212             DetectImageType(imageType, pAttribute)) {\r
1213         m_imagType = imageType;\r
1214         m_status = FXCODEC_STATUS_FRAME_READY;\r
1215         return m_status;\r
1216     }\r
1217     for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) {\r
1218         if(DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) {\r
1219             m_imagType = (FXCODEC_IMAGE_TYPE)type;\r
1220             m_status = FXCODEC_STATUS_FRAME_READY;\r
1221             return m_status;\r
1222         }\r
1223     }\r
1224     m_status = FXCODEC_STATUS_ERR_FORMAT;\r
1225     m_pFile = NULL;\r
1226     return m_status;\r
1227 }\r
1228 void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip)\r
1229 {\r
1230     if(m_status != FXCODEC_STATUS_FRAME_READY) {\r
1231         return;\r
1232     }\r
1233     if(clip->IsEmpty()) {\r
1234         m_clipBox = FX_RECT(0, 0, 0, 0);\r
1235         return;\r
1236     }\r
1237     if(clip->left < 0) {\r
1238         clip->left = 0;\r
1239     }\r
1240     if(clip->right > m_SrcWidth) {\r
1241         clip->right = m_SrcWidth;\r
1242     }\r
1243     if(clip->top < 0) {\r
1244         clip->top = 0;\r
1245     }\r
1246     if(clip->bottom > m_SrcHeight) {\r
1247         clip->bottom = m_SrcHeight;\r
1248     }\r
1249     if(clip->IsEmpty()) {\r
1250         m_clipBox = FX_RECT(0, 0, 0, 0);\r
1251         return;\r
1252     }\r
1253     m_clipBox = *clip;\r
1254 }\r
1255 void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale)\r
1256 {\r
1257     down_scale = 1;\r
1258     int ratio_w = m_clipBox.Width() / m_sizeX;\r
1259     int ratio_h = m_clipBox.Height() / m_sizeY;\r
1260     int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w;\r
1261     if (ratio >= 8) {\r
1262         down_scale = 8;\r
1263     } else if (ratio >= 4)      {\r
1264         down_scale = 4;\r
1265     } else if (ratio >= 2)      {\r
1266         down_scale = 2;\r
1267     }\r
1268     m_clipBox.left /= down_scale;\r
1269     m_clipBox.right /= down_scale;\r
1270     m_clipBox.top /= down_scale;\r
1271     m_clipBox.bottom /= down_scale;\r
1272     if(m_clipBox.right == m_clipBox.left) {\r
1273         m_clipBox.right = m_clipBox.left + 1;\r
1274     }\r
1275     if(m_clipBox.bottom == m_clipBox.top) {\r
1276         m_clipBox.bottom = m_clipBox.top + 1;\r
1277     }\r
1278 }\r
1279 void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format)\r
1280 {\r
1281     switch(des_format) {\r
1282         case FXDIB_1bppMask:\r
1283         case FXDIB_1bppRgb: {\r
1284                 switch(src_format) {\r
1285                     case FXCodec_1bppGray:\r
1286                         m_TransMethod = 0;\r
1287                         break;\r
1288                     default:\r
1289                         m_TransMethod = -1;\r
1290                 }\r
1291             }\r
1292             break;\r
1293         case FXDIB_8bppMask:\r
1294         case FXDIB_8bppRgb: {\r
1295                 switch(src_format) {\r
1296                     case FXCodec_1bppGray:\r
1297                         m_TransMethod = 1;\r
1298                         break;\r
1299                     case FXCodec_8bppGray:\r
1300                         m_TransMethod = 2;\r
1301                         break;\r
1302                     case FXCodec_1bppRgb:\r
1303                     case FXCodec_8bppRgb:\r
1304                         m_TransMethod = 3;\r
1305                         break;\r
1306                     case FXCodec_Rgb:\r
1307                     case FXCodec_Rgb32:\r
1308                     case FXCodec_Argb:\r
1309                         m_TransMethod = 4;\r
1310                         break;\r
1311                     case FXCodec_Cmyk:\r
1312                         m_TransMethod = 5;\r
1313                         break;\r
1314                     default:\r
1315                         m_TransMethod = -1;\r
1316                 }\r
1317             }\r
1318             break;\r
1319         case FXDIB_Rgb: {\r
1320                 switch(src_format) {\r
1321                     case FXCodec_1bppGray:\r
1322                         m_TransMethod = 6;\r
1323                         break;\r
1324                     case FXCodec_8bppGray:\r
1325                         m_TransMethod = 7;\r
1326                         break;\r
1327                     case FXCodec_1bppRgb:\r
1328                     case FXCodec_8bppRgb:\r
1329                         m_TransMethod = 8;\r
1330                         break;\r
1331                     case FXCodec_Rgb:\r
1332                     case FXCodec_Rgb32:\r
1333                     case FXCodec_Argb:\r
1334                         m_TransMethod = 9;\r
1335                         break;\r
1336                     case FXCodec_Cmyk:\r
1337                         m_TransMethod = 10;\r
1338                         break;\r
1339                     default:\r
1340                         m_TransMethod = -1;\r
1341                 }\r
1342             }\r
1343             break;\r
1344         case FXDIB_Rgb32:\r
1345         case FXDIB_Argb: {\r
1346                 switch(src_format) {\r
1347                     case FXCodec_1bppGray:\r
1348                         m_TransMethod = 6;\r
1349                         break;\r
1350                     case FXCodec_8bppGray:\r
1351                         m_TransMethod = 7;\r
1352                         break;\r
1353                     case FXCodec_1bppRgb:\r
1354                     case FXCodec_8bppRgb:\r
1355                         if(des_format == FXDIB_Argb) {\r
1356                             m_TransMethod = 12;\r
1357                         } else {\r
1358                             m_TransMethod = 8;\r
1359                         }\r
1360                         break;\r
1361                     case FXCodec_Rgb:\r
1362                     case FXCodec_Rgb32:\r
1363                         m_TransMethod = 9;\r
1364                         break;\r
1365                     case FXCodec_Cmyk:\r
1366                         m_TransMethod = 10;\r
1367                         break;\r
1368                     case FXCodec_Argb:\r
1369                         m_TransMethod = 11;\r
1370                         break;\r
1371                     default:\r
1372                         m_TransMethod = -1;\r
1373                 }\r
1374             }\r
1375             break;\r
1376         default:\r
1377             m_TransMethod = -1;\r
1378     }\r
1379 }\r
1380 void _RGB2BGR(FX_LPBYTE buffer, int width = 1)\r
1381 {\r
1382     if (buffer && width > 0) {\r
1383         uint8_t temp;\r
1384         int i = 0;\r
1385         int j = 0;\r
1386         for (; i < width; i++, j += 3) {\r
1387             temp = buffer[j];\r
1388             buffer[j] = buffer[j + 2];\r
1389             buffer[j + 2] = temp;\r
1390         }\r
1391     }\r
1392 }\r
1393 void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, int des_line, FX_LPBYTE src_scan, FXCodec_Format src_format)\r
1394 {\r
1395     int src_left = m_clipBox.left;\r
1396     int des_left = m_startX;\r
1397     FX_LPBYTE des_scan = pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch();\r
1398     int src_bpp = src_format & 0xff;\r
1399     int des_bpp = pDeviceBitmap->GetBPP();\r
1400     int src_Bpp = src_bpp >> 3;\r
1401     int des_Bpp = des_bpp >> 3;\r
1402     src_scan += src_left * src_Bpp;\r
1403     des_scan += des_left * des_Bpp;\r
1404     for (int des_col = 0; des_col < m_sizeX; des_col++) {\r
1405         PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col);\r
1406         switch(m_TransMethod) {\r
1407             case -1:\r
1408                 return;\r
1409             case 0:\r
1410                 return;\r
1411             case 1:\r
1412                 return;\r
1413             case 2: {\r
1414                     FX_DWORD des_g = 0;\r
1415                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1416                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1417                         des_g += pixel_weight * src_scan[j];\r
1418                     }\r
1419                     *des_scan++ = (uint8_t)(des_g >> 16);\r
1420                 }\r
1421                 break;\r
1422             case 3: {\r
1423                     int des_r = 0, des_g = 0, des_b = 0;\r
1424                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {\r
1425                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1426                         unsigned long argb = m_pSrcPalette[src_scan[j]];\r
1427                         des_r += pixel_weight * (uint8_t)(argb >> 16);\r
1428                         des_g += pixel_weight * (uint8_t)(argb >> 8);\r
1429                         des_b += pixel_weight * (uint8_t)argb;\r
1430                     }\r
1431                     *des_scan++ = (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));\r
1432                 }\r
1433                 break;\r
1434             case 4: {\r
1435                     FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
1436                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1437                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1438                         FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;\r
1439                         des_b += pixel_weight * (*src_pixel++);\r
1440                         des_g += pixel_weight * (*src_pixel++);\r
1441                         des_r += pixel_weight * (*src_pixel);\r
1442                     }\r
1443                     *des_scan++ = (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));\r
1444                 }\r
1445                 break;\r
1446             case 5: {\r
1447                     FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
1448                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1449                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1450                         FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;\r
1451                         uint8_t src_b = 0, src_g = 0, src_r = 0;\r
1452                         AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], 255 - src_pixel[2], 255 - src_pixel[3],\r
1453                                            src_r, src_g, src_b);\r
1454                         des_b += pixel_weight * src_b;\r
1455                         des_g += pixel_weight * src_g;\r
1456                         des_r += pixel_weight * src_r;\r
1457                     }\r
1458                     *des_scan++ = (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));\r
1459                 }\r
1460                 break;\r
1461             case 6:\r
1462                 return;\r
1463             case 7: {\r
1464                     FX_DWORD des_g = 0;\r
1465                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1466                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1467                         des_g += pixel_weight * src_scan[j];\r
1468                     }\r
1469                     FXSYS_memset8(des_scan, (uint8_t)(des_g >> 16), 3);\r
1470                     des_scan += des_Bpp;\r
1471                 }\r
1472                 break;\r
1473             case 8: {\r
1474                     int des_r = 0, des_g = 0, des_b = 0;\r
1475                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {\r
1476                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1477                         unsigned long argb = m_pSrcPalette[src_scan[j]];\r
1478                         des_r += pixel_weight * (uint8_t)(argb >> 16);\r
1479                         des_g += pixel_weight * (uint8_t)(argb >> 8);\r
1480                         des_b += pixel_weight * (uint8_t)argb;\r
1481                     }\r
1482                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
1483                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
1484                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
1485                     des_scan += des_Bpp - 3;\r
1486                 }\r
1487                 break;\r
1488             case 12: {\r
1489                     if (m_pBmpContext) {\r
1490                         int des_r = 0, des_g = 0, des_b = 0;\r
1491                         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {\r
1492                             int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1493                             unsigned long argb = m_pSrcPalette[src_scan[j]];\r
1494                             des_r += pixel_weight * (uint8_t)(argb >> 16);\r
1495                             des_g += pixel_weight * (uint8_t)(argb >> 8);\r
1496                             des_b += pixel_weight * (uint8_t)argb;\r
1497                         }\r
1498                         *des_scan++ = (uint8_t)((des_b) >> 16);\r
1499                         *des_scan++ = (uint8_t)((des_g) >> 16);\r
1500                         *des_scan++ = (uint8_t)((des_r) >> 16);\r
1501                         *des_scan++ = 0xFF;\r
1502                     } else {\r
1503                         int des_a = 0, des_r = 0, des_g = 0, des_b = 0;\r
1504                         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {\r
1505                             int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1506                             unsigned long argb = m_pSrcPalette[src_scan[j]];\r
1507                             des_a += pixel_weight * (uint8_t)(argb >> 24);\r
1508                             des_r += pixel_weight * (uint8_t)(argb >> 16);\r
1509                             des_g += pixel_weight * (uint8_t)(argb >> 8);\r
1510                             des_b += pixel_weight * (uint8_t)argb;\r
1511                         }\r
1512                         *des_scan++ = (uint8_t)((des_b) >> 16);\r
1513                         *des_scan++ = (uint8_t)((des_g) >> 16);\r
1514                         *des_scan++ = (uint8_t)((des_r) >> 16);\r
1515                         *des_scan++ = (uint8_t)((des_a) >> 16);\r
1516                     }\r
1517                 }\r
1518                 break;\r
1519             case 9: {\r
1520                     FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
1521                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1522                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1523                         FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;\r
1524                         des_b += pixel_weight * (*src_pixel++);\r
1525                         des_g += pixel_weight * (*src_pixel++);\r
1526                         des_r += pixel_weight * (*src_pixel);\r
1527                     }\r
1528                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
1529                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
1530                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
1531                     des_scan += des_Bpp - 3;\r
1532                 }\r
1533                 break;\r
1534             case 10: {\r
1535                     FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
1536                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {\r
1537                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1538                         FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;\r
1539                         uint8_t src_b = 0, src_g = 0, src_r = 0;\r
1540                         AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], 255 - src_pixel[2], 255 - src_pixel[3],\r
1541                                            src_r, src_g, src_b);\r
1542                         des_b += pixel_weight * src_b;\r
1543                         des_g += pixel_weight * src_g;\r
1544                         des_r += pixel_weight * src_r;\r
1545                     }\r
1546                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
1547                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
1548                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
1549                     des_scan += des_Bpp - 3;\r
1550                 }\r
1551                 break;\r
1552             case 11: {\r
1553                     FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0;\r
1554                     for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {\r
1555                         int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];\r
1556                         FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;\r
1557                         pixel_weight = pixel_weight * src_pixel[3] / 255;\r
1558                         des_b += pixel_weight * (*src_pixel++);\r
1559                         des_g += pixel_weight * (*src_pixel++);\r
1560                         des_r += pixel_weight * (*src_pixel);\r
1561                         des_alpha += pixel_weight;\r
1562                     }\r
1563                     *des_scan++ = (uint8_t)((des_b) >> 16);\r
1564                     *des_scan++ = (uint8_t)((des_g) >> 16);\r
1565                     *des_scan++ = (uint8_t)((des_r) >> 16);\r
1566                     *des_scan++ = (uint8_t)((des_alpha * 255) >> 16);\r
1567                 }\r
1568                 break;\r
1569             default:\r
1570                 return;\r
1571         }\r
1572     }\r
1573 }\r
1574 void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)\r
1575 {\r
1576     int des_Bpp = pDeviceBitmap->GetBPP() >> 3;\r
1577     FX_DWORD des_ScanOffet = m_startX * des_Bpp;\r
1578     if(m_bInterpol) {\r
1579         int des_top = m_startY;\r
1580         int des_row_1 = des_row - int(scale_y);\r
1581         if(des_row_1 < des_top) {\r
1582             int des_bottom = des_top + m_sizeY;\r
1583             if(des_row + (int)scale_y >= des_bottom - 1) {\r
1584                 FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
1585                 while (++des_row < des_bottom) {\r
1586                     FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
1587                     FX_DWORD size = m_sizeX * des_Bpp;\r
1588                     FXSYS_memcpy32(scan_des, scan_src, size);\r
1589                 }\r
1590             }\r
1591             return;\r
1592         }\r
1593         for (; des_row_1 < des_row; des_row_1++) {\r
1594             FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;\r
1595             PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);\r
1596             FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;\r
1597             FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;\r
1598             for (int des_col = 0; des_col < m_sizeX; des_col++) {\r
1599                 switch(pDeviceBitmap->GetFormat()) {\r
1600                     case FXDIB_Invalid:\r
1601                     case FXDIB_1bppMask:\r
1602                     case FXDIB_1bppRgb:\r
1603                         return;\r
1604                     case FXDIB_8bppMask:\r
1605                     case FXDIB_8bppRgb: {\r
1606                             if(pDeviceBitmap->GetPalette() != NULL) {\r
1607                                 return;\r
1608                             }\r
1609                             int des_g = 0;\r
1610                             des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
1611                             des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
1612                             *scan_des++ = (uint8_t)(des_g >> 16);\r
1613                         }\r
1614                         break;\r
1615                     case FXDIB_Rgb:\r
1616                     case FXDIB_Rgb32: {\r
1617                             FX_DWORD des_b = 0, des_g = 0, des_r = 0;\r
1618                             des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
1619                             des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
1620                             des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
1621                             scan_src1 += des_Bpp - 3;\r
1622                             des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
1623                             des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
1624                             des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
1625                             scan_src2 += des_Bpp - 3;\r
1626                             *scan_des++ = (uint8_t)((des_b) >> 16);\r
1627                             *scan_des++ = (uint8_t)((des_g) >> 16);\r
1628                             *scan_des++ = (uint8_t)((des_r) >> 16);\r
1629                             scan_des += des_Bpp - 3;\r
1630                         }\r
1631                         break;\r
1632                     case FXDIB_Argb: {\r
1633                             FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;\r
1634                             des_b += pWeight->m_Weights[0] * (*scan_src1++);\r
1635                             des_g += pWeight->m_Weights[0] * (*scan_src1++);\r
1636                             des_r += pWeight->m_Weights[0] * (*scan_src1++);\r
1637                             des_a += pWeight->m_Weights[0] * (*scan_src1++);\r
1638                             des_b += pWeight->m_Weights[1] * (*scan_src2++);\r
1639                             des_g += pWeight->m_Weights[1] * (*scan_src2++);\r
1640                             des_r += pWeight->m_Weights[1] * (*scan_src2++);\r
1641                             des_a += pWeight->m_Weights[1] * (*scan_src2++);\r
1642                             *scan_des++ = (uint8_t)((des_b) >> 16);\r
1643                             *scan_des++ = (uint8_t)((des_g) >> 16);\r
1644                             *scan_des++ = (uint8_t)((des_r) >> 16);\r
1645                             *scan_des++ = (uint8_t)((des_a) >> 16);\r
1646                         }\r
1647                         break;\r
1648                     default:\r
1649                         return;\r
1650                 }\r
1651             }\r
1652         }\r
1653         int des_bottom = des_top + m_sizeY;\r
1654         if(des_row + (int)scale_y >= des_bottom - 1) {\r
1655             FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
1656             while (++des_row < des_bottom) {\r
1657                 FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
1658                 FX_DWORD size = m_sizeX * des_Bpp;\r
1659                 FXSYS_memcpy32(scan_des, scan_src, size);\r
1660             }\r
1661         }\r
1662         return;\r
1663     }\r
1664     int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1);\r
1665     if(multiple > 0) {\r
1666         FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;\r
1667         for (int i = 1; i <= multiple; i++) {\r
1668             if(des_row + i >= m_startY + m_sizeY) {\r
1669                 return;\r
1670             }\r
1671             FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet;\r
1672             FX_DWORD size = m_sizeX * des_Bpp;\r
1673             FXSYS_memcpy32(scan_des, scan_src, size);\r
1674         }\r
1675     }\r
1676 }\r
1677 void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, int32_t src_line, FX_LPBYTE src_scan, FXCodec_Format src_format)\r
1678 {\r
1679     int src_top = m_clipBox.top;\r
1680     int des_top = m_startY;\r
1681     int src_hei = m_clipBox.Height();\r
1682     int des_hei = m_sizeY;\r
1683     if(src_line >= src_top) {\r
1684         double scale_y = (double)des_hei / (double)src_hei;\r
1685         int src_row = src_line - src_top;\r
1686         int des_row = (int)(src_row * scale_y)  + des_top;\r
1687         if(des_row >= des_top + des_hei)        {\r
1688             return;\r
1689         }\r
1690         ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format);\r
1691         if(scale_y > 1.0) {\r
1692             ResampleVert(pDeviceBitmap, scale_y, des_row);\r
1693         }\r
1694     }\r
1695 }\r
1696 FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, IFX_Pause* pPause)\r
1697 {\r
1698     if(!(m_status == FXCODEC_STATUS_FRAME_READY || m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) {\r
1699         return FXCODEC_STATUS_ERROR;\r
1700     }\r
1701     switch(m_imagType) {\r
1702         case FXCODEC_IMAGE_BMP:\r
1703         case FXCODEC_IMAGE_JPG:\r
1704         case FXCODEC_IMAGE_PNG:\r
1705         case FXCODEC_IMAGE_TIF:\r
1706             frames = m_FrameNumber = 1;\r
1707             return m_status = FXCODEC_STATUS_DECODE_READY;\r
1708         case FXCODEC_IMAGE_GIF: {\r
1709                 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();\r
1710                 while (TRUE) {\r
1711                     int32_t readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);\r
1712                     while(readResult == 2) {\r
1713                         FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ;\r
1714                         if(!GifReadMoreData(pGifModule, error_status)) {\r
1715                             return error_status;\r
1716                         }\r
1717                         if(pPause && pPause->NeedToPauseNow()) {\r
1718                             return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE;\r
1719                         }\r
1720                         readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);\r
1721                     }\r
1722                     if(readResult == 1) {\r
1723                         frames = m_FrameNumber;\r
1724                         return m_status = FXCODEC_STATUS_DECODE_READY;\r
1725                     }\r
1726                     if(m_pGifContext != NULL) {\r
1727                         pGifModule->Finish(m_pGifContext);\r
1728                         m_pGifContext = NULL;\r
1729                     }\r
1730                     return m_status = FXCODEC_STATUS_ERROR;\r
1731                 }\r
1732             }\r
1733             break;\r
1734         default:\r
1735             ;\r
1736     }\r
1737     return FXCODEC_STATUS_ERROR;\r
1738 }\r
1739 FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap,\r
1740         int start_x, int start_y, int size_x, int size_y,\r
1741         int32_t frames, FX_BOOL bInterpol)\r
1742 {\r
1743     if(m_status != FXCODEC_STATUS_DECODE_READY) {\r
1744         return FXCODEC_STATUS_ERROR;\r
1745     }\r
1746     if(pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 ||\r
1747             frames < 0 || frames >= m_FrameNumber) {\r
1748         return FXCODEC_STATUS_ERR_PARAMS;\r
1749     }\r
1750     m_pDeviceBitmap = pDIBitmap;\r
1751     if(m_clipBox.IsEmpty()) {\r
1752         return FXCODEC_STATUS_ERR_PARAMS;\r
1753     }\r
1754     if(size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) {\r
1755         return FXCODEC_STATUS_ERR_PARAMS;\r
1756     }\r
1757     FX_RECT device_rc = FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y);\r
1758     int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth();\r
1759     int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight();\r
1760     device_rc.Intersect(FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight()));\r
1761     if(device_rc.IsEmpty()) {\r
1762         return FXCODEC_STATUS_ERR_PARAMS;\r
1763     }\r
1764     m_startX = device_rc.left;\r
1765     m_startY = device_rc.top;\r
1766     m_sizeX  = device_rc.Width();\r
1767     m_sizeY  = device_rc.Height();\r
1768     m_bInterpol = bInterpol;\r
1769     m_FrameCur = 0;\r
1770     if(start_x < 0 || out_range_x > 0) {\r
1771         FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x;\r
1772         if(start_x < 0) {\r
1773             m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX);\r
1774         }\r
1775         if(out_range_x > 0)     {\r
1776             m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX);\r
1777         }\r
1778     }\r
1779     if(start_y < 0 || out_range_y > 0) {\r
1780         FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y;\r
1781         if(start_y < 0) {\r
1782             m_clipBox.top  -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY);\r
1783         }\r
1784         if(out_range_y > 0) {\r
1785             m_clipBox.bottom  -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY);\r
1786         }\r
1787     }\r
1788     if(m_clipBox.IsEmpty()) {\r
1789         return FXCODEC_STATUS_ERR_PARAMS;\r
1790     }\r
1791     switch(m_imagType) {\r
1792         case FXCODEC_IMAGE_JPG: {\r
1793                 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();\r
1794                 int down_scale = 1;\r
1795                 GetDownScale(down_scale);\r
1796                 FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);\r
1797                 while(!bStart) {\r
1798                     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;\r
1799                     if(!JpegReadMoreData(pJpegModule, error_status)) {\r
1800                         m_pDeviceBitmap = NULL;\r
1801                         m_pFile = NULL;\r
1802                         return m_status = error_status;\r
1803                     }\r
1804                     bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);\r
1805                 }\r
1806                 int scanline_size = ( m_SrcWidth + down_scale - 1) / down_scale;\r
1807                 scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;\r
1808                 if(m_pDecodeBuf != NULL) {\r
1809                     FX_Free(m_pDecodeBuf);\r
1810                     m_pDecodeBuf = NULL;\r
1811                 }\r
1812                 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);\r
1813                 if(m_pDecodeBuf == NULL) {\r
1814                     m_pDeviceBitmap = NULL;\r
1815                     m_pFile = NULL;\r
1816                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1817                 }\r
1818                 FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);\r
1819                 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);\r
1820                 m_WeightVert.Calc(m_sizeY, m_clipBox.Height());\r
1821                 switch(m_SrcComponents) {\r
1822                     case 1:\r
1823                         m_SrcFormat = FXCodec_8bppGray;\r
1824                         break;\r
1825                     case 3:\r
1826                         m_SrcFormat = FXCodec_Rgb;\r
1827                         break;\r
1828                     case 4:\r
1829                         m_SrcFormat = FXCodec_Cmyk;\r
1830                         break;\r
1831                 }\r
1832                 GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat);\r
1833                 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1834             }\r
1835             break;\r
1836         case FXCODEC_IMAGE_PNG: {\r
1837                 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();\r
1838                 if(pPngModule == NULL) {\r
1839                     m_pDeviceBitmap = NULL;\r
1840                     m_pFile = NULL;\r
1841                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1842                 }\r
1843                 if(m_pPngContext != NULL) {\r
1844                     pPngModule->Finish(m_pPngContext);\r
1845                     m_pPngContext = NULL;\r
1846                 }\r
1847                 m_pPngContext = pPngModule->Start((void*)this);\r
1848                 if(m_pPngContext == NULL) {\r
1849                     m_pDeviceBitmap = NULL;\r
1850                     m_pFile = NULL;\r
1851                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1852                 }\r
1853                 m_offSet = 0;\r
1854                 switch(m_pDeviceBitmap->GetFormat()) {\r
1855                     case FXDIB_8bppMask:\r
1856                     case FXDIB_8bppRgb:\r
1857                         m_SrcComponents = 1;\r
1858                         m_SrcFormat = FXCodec_8bppGray;\r
1859                         break;\r
1860                     case FXDIB_Rgb:\r
1861                         m_SrcComponents = 3;\r
1862                         m_SrcFormat = FXCodec_Rgb;\r
1863                         break;\r
1864                     case FXDIB_Rgb32:\r
1865                     case FXDIB_Argb:\r
1866                         m_SrcComponents = 4;\r
1867                         m_SrcFormat = FXCodec_Argb;\r
1868                         break;\r
1869                     default: {\r
1870                             m_pDeviceBitmap = NULL;\r
1871                             m_pFile = NULL;\r
1872                             return m_status = FXCODEC_STATUS_ERR_PARAMS;\r
1873                         }\r
1874                 }\r
1875                 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);\r
1876                 int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;\r
1877                 if(m_pDecodeBuf != NULL) {\r
1878                     FX_Free(m_pDecodeBuf);\r
1879                     m_pDecodeBuf = NULL;\r
1880                 }\r
1881                 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);\r
1882                 if(m_pDecodeBuf == NULL) {\r
1883                     m_pDeviceBitmap = NULL;\r
1884                     m_pFile = NULL;\r
1885                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1886                 }\r
1887                 FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);\r
1888                 m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol);\r
1889                 m_WeightVert.Calc(m_sizeY, m_clipBox.Height());\r
1890                 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1891             }\r
1892             break;\r
1893         case FXCODEC_IMAGE_GIF: {\r
1894                 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();\r
1895                 if(pGifModule == NULL) {\r
1896                     m_pDeviceBitmap = NULL;\r
1897                     m_pFile = NULL;\r
1898                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1899                 }\r
1900                 m_SrcFormat = FXCodec_8bppRgb;\r
1901                 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);\r
1902                 int scanline_size = (m_SrcWidth + 3) / 4 * 4;\r
1903                 if(m_pDecodeBuf != NULL) {\r
1904                     FX_Free(m_pDecodeBuf);\r
1905                     m_pDecodeBuf = NULL;\r
1906                 }\r
1907                 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);\r
1908                 if(m_pDecodeBuf == NULL) {\r
1909                     m_pDeviceBitmap = NULL;\r
1910                     m_pFile = NULL;\r
1911                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1912                 }\r
1913                 FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);\r
1914                 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);\r
1915                 m_WeightVert.Calc(m_sizeY, m_clipBox.Height());\r
1916                 m_FrameCur = frames;\r
1917                 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1918             }\r
1919             break;\r
1920         case FXCODEC_IMAGE_BMP: {\r
1921                 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();\r
1922                 if(pBmpModule == NULL) {\r
1923                     m_pDeviceBitmap = NULL;\r
1924                     m_pFile = NULL;\r
1925                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1926                 }\r
1927                 switch(m_SrcComponents) {\r
1928                     case 1:\r
1929                         m_SrcFormat = FXCodec_8bppRgb;\r
1930                         break;\r
1931                     case 3:\r
1932                         m_SrcFormat = FXCodec_Rgb;\r
1933                         break;\r
1934                     case 4:\r
1935                         m_SrcFormat = FXCodec_Rgb32;\r
1936                         break;\r
1937                 }\r
1938                 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);\r
1939                 m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;\r
1940                 if(m_pDecodeBuf != NULL) {\r
1941                     FX_Free(m_pDecodeBuf);\r
1942                     m_pDecodeBuf = NULL;\r
1943                 }\r
1944                 m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize);\r
1945                 if(m_pDecodeBuf == NULL) {\r
1946                     m_pDeviceBitmap = NULL;\r
1947                     m_pFile = NULL;\r
1948                     return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
1949                 }\r
1950                 FXSYS_memset32(m_pDecodeBuf, 0, m_ScanlineSize);\r
1951                 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);\r
1952                 m_WeightVert.Calc(m_sizeY, m_clipBox.Height());\r
1953                 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1954             }\r
1955             break;\r
1956         case FXCODEC_IMAGE_TIF:\r
1957             return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1958         default:\r
1959             break;\r
1960     }\r
1961     return FXCODEC_STATUS_ERROR;\r
1962 }\r
1963 FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause)\r
1964 {\r
1965     if(m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) {\r
1966         return FXCODEC_STATUS_ERROR;\r
1967     }\r
1968     switch(m_imagType) {\r
1969         case FXCODEC_IMAGE_JPG: {\r
1970                 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();\r
1971                 while(TRUE) {\r
1972                     FX_BOOL readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);\r
1973                     while(!readRes) {\r
1974                         FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;\r
1975                         if(!JpegReadMoreData(pJpegModule, error_status)) {\r
1976                             m_pDeviceBitmap = NULL;\r
1977                             m_pFile = NULL;\r
1978                             return m_status = error_status;\r
1979                         }\r
1980                         readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);\r
1981                     }\r
1982                     if(m_SrcFormat == FXCodec_Rgb) {\r
1983                         int src_Bpp = (m_SrcFormat & 0xff) >> 3;\r
1984                         _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width());\r
1985                     }\r
1986                     if(m_SrcRow >= m_clipBox.bottom) {\r
1987                         m_pDeviceBitmap = NULL;\r
1988                         m_pFile = NULL;\r
1989                         return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
1990                     }\r
1991                     Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);\r
1992                     m_SrcRow++;\r
1993                     if(pPause && pPause->NeedToPauseNow()) {\r
1994                         return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
1995                     }\r
1996                 }\r
1997             }\r
1998             break;\r
1999         case FXCODEC_IMAGE_PNG: {\r
2000                 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();\r
2001                 while (TRUE) {\r
2002                     FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet;\r
2003                     FX_DWORD input_size = remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;\r
2004                     if(input_size == 0) {\r
2005                         if(m_pPngContext != NULL) {\r
2006                             pPngModule->Finish(m_pPngContext);\r
2007                         }\r
2008                         m_pPngContext = NULL;\r
2009                         m_pDeviceBitmap = NULL;\r
2010                         m_pFile = NULL;\r
2011                         return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
2012                     }\r
2013                     if(m_pSrcBuf != NULL && input_size > m_SrcSize) {\r
2014                         FX_Free(m_pSrcBuf);\r
2015                         m_pSrcBuf = FX_Alloc(uint8_t, input_size);\r
2016                         if(m_pSrcBuf == NULL) {\r
2017                             m_pDeviceBitmap = NULL;\r
2018                             m_pFile = NULL;\r
2019                             return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
2020                         }\r
2021                         FXSYS_memset32(m_pSrcBuf, 0, input_size);\r
2022                         m_SrcSize = input_size;\r
2023                     }\r
2024                     FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);\r
2025                     if(!bResult) {\r
2026                         m_pDeviceBitmap = NULL;\r
2027                         m_pFile = NULL;\r
2028                         return m_status = FXCODEC_STATUS_ERR_READ;\r
2029                     }\r
2030                     m_offSet += input_size;\r
2031                     bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size);\r
2032                     if(!bResult) {\r
2033                         m_pDeviceBitmap = NULL;\r
2034                         m_pFile = NULL;\r
2035                         return m_status = FXCODEC_STATUS_ERROR;\r
2036                     }\r
2037                     if(pPause && pPause->NeedToPauseNow()) {\r
2038                         return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
2039                     }\r
2040                 }\r
2041             }\r
2042             break;\r
2043         case FXCODEC_IMAGE_GIF: {\r
2044                 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();\r
2045                 while(TRUE) {\r
2046                     int32_t readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur);\r
2047                     while(readRes == 2) {\r
2048                         FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;\r
2049                         if(!GifReadMoreData(pGifModule, error_status)) {\r
2050                             m_pDeviceBitmap = NULL;\r
2051                             m_pFile = NULL;\r
2052                             return m_status = error_status;\r
2053                         }\r
2054                         if(pPause && pPause->NeedToPauseNow()) {\r
2055                             return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
2056                         }\r
2057                         readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur);\r
2058                     }\r
2059                     if(readRes == 1) {\r
2060                         m_pDeviceBitmap = NULL;\r
2061                         m_pFile = NULL;\r
2062                         return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
2063                     }\r
2064                     m_pDeviceBitmap = NULL;\r
2065                     m_pFile = NULL;\r
2066                     return m_status = FXCODEC_STATUS_ERROR;\r
2067                 }\r
2068             }\r
2069             break;\r
2070         case FXCODEC_IMAGE_BMP: {\r
2071                 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();\r
2072                 while(TRUE) {\r
2073                     int32_t readRes = pBmpModule->LoadImage(m_pBmpContext);\r
2074                     while(readRes == 2) {\r
2075                         FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;\r
2076                         if(!BmpReadMoreData(pBmpModule, error_status)) {\r
2077                             m_pDeviceBitmap = NULL;\r
2078                             m_pFile = NULL;\r
2079                             return m_status = error_status;\r
2080                         }\r
2081                         if(pPause && pPause->NeedToPauseNow()) {\r
2082                             return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;\r
2083                         }\r
2084                         readRes = pBmpModule->LoadImage(m_pBmpContext);\r
2085                     }\r
2086                     if(readRes == 1) {\r
2087                         m_pDeviceBitmap = NULL;\r
2088                         m_pFile = NULL;\r
2089                         return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
2090                     }\r
2091                     m_pDeviceBitmap = NULL;\r
2092                     m_pFile = NULL;\r
2093                     return m_status = FXCODEC_STATUS_ERROR;\r
2094                 }\r
2095             }\r
2096             break;\r
2097         case FXCODEC_IMAGE_TIF: {\r
2098                 ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();\r
2099                 FX_BOOL ret = FALSE;\r
2100                 if(m_pDeviceBitmap->GetBPP() == 32 &&\r
2101                         m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX &&\r
2102                         m_pDeviceBitmap->GetHeight() == m_SrcHeight && m_SrcHeight == m_sizeY &&\r
2103                         m_startX == 0 && m_startY == 0 && m_clipBox.left == 0 && m_clipBox.top == 0\r
2104                         && m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) {\r
2105                     ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap);\r
2106                     m_pDeviceBitmap = NULL;\r
2107                     m_pFile = NULL;\r
2108                     if(!ret)    {\r
2109                         return m_status = FXCODEC_STATUS_ERROR;\r
2110                     }\r
2111                     return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
2112                 } else {\r
2113                     CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap;\r
2114                     pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);\r
2115                     if(pDIBitmap->GetBuffer() == NULL) {\r
2116                         delete pDIBitmap;\r
2117                         m_pDeviceBitmap = NULL;\r
2118                         m_pFile = NULL;\r
2119                         return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
2120                     }\r
2121                     ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap);\r
2122                     if(!ret) {\r
2123                         delete pDIBitmap;\r
2124                         m_pDeviceBitmap = NULL;\r
2125                         m_pFile = NULL;\r
2126                         return m_status = FXCODEC_STATUS_ERROR;\r
2127                     }\r
2128                     CFX_DIBitmap* pClipBitmap =\r
2129                         (m_clipBox.left  == 0 &&\r
2130                          m_clipBox.top == 0 &&\r
2131                          m_clipBox.right == m_SrcWidth &&\r
2132                          m_clipBox.bottom == m_SrcHeight) ? pDIBitmap : pDIBitmap->Clone(&m_clipBox);\r
2133                     if(pDIBitmap != pClipBitmap) {\r
2134                         delete pDIBitmap;\r
2135                     }\r
2136                     if(pClipBitmap == NULL) {\r
2137                         m_pDeviceBitmap = NULL;\r
2138                         m_pFile = NULL;\r
2139                         return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
2140                     }\r
2141                     CFX_DIBitmap* pFormatBitmap = NULL;\r
2142                     switch(m_pDeviceBitmap->GetFormat()) {\r
2143                         case FXDIB_8bppRgb:\r
2144                             pFormatBitmap = new CFX_DIBitmap;\r
2145                             pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_8bppRgb);\r
2146                             break;\r
2147                         case FXDIB_8bppMask:\r
2148                             pFormatBitmap = new CFX_DIBitmap;\r
2149                             pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_8bppMask);\r
2150                             break;\r
2151                         case FXDIB_Rgb:\r
2152                             pFormatBitmap = new CFX_DIBitmap;\r
2153                             pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_Rgb);\r
2154                             break;\r
2155                         case FXDIB_Rgb32:\r
2156                             pFormatBitmap = new CFX_DIBitmap;\r
2157                             pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_Rgb32);\r
2158                             break;\r
2159                         case FXDIB_Argb:\r
2160                             pFormatBitmap = pClipBitmap;\r
2161                             break;\r
2162                         default:\r
2163                             ;\r
2164                     }\r
2165                     switch(m_pDeviceBitmap->GetFormat()) {\r
2166                         case FXDIB_8bppRgb:\r
2167                         case FXDIB_8bppMask: {\r
2168                                 for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {\r
2169                                     FX_LPBYTE src_line = (FX_LPBYTE)pClipBitmap->GetScanline(row);\r
2170                                     FX_LPBYTE des_line = (FX_LPBYTE)pFormatBitmap->GetScanline(row);\r
2171                                     for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {\r
2172                                         uint8_t _a = 255 - src_line[3];\r
2173                                         uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;\r
2174                                         uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;\r
2175                                         uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;\r
2176                                         *des_line++ = FXRGB2GRAY(r, g, b);\r
2177                                         src_line += 4;\r
2178                                     }\r
2179                                 }\r
2180                             }\r
2181                             break;\r
2182                         case FXDIB_Rgb:\r
2183                         case FXDIB_Rgb32: {\r
2184                                 int32_t desBpp = (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;\r
2185                                 for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {\r
2186                                     FX_LPBYTE src_line = (FX_LPBYTE)pClipBitmap->GetScanline(row);\r
2187                                     FX_LPBYTE des_line = (FX_LPBYTE)pFormatBitmap->GetScanline(row);\r
2188                                     for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {\r
2189                                         uint8_t _a = 255 - src_line[3];\r
2190                                         uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;\r
2191                                         uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;\r
2192                                         uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;\r
2193                                         *des_line++ = b;\r
2194                                         *des_line++ = g;\r
2195                                         *des_line++ = r;\r
2196                                         des_line += desBpp - 3;\r
2197                                         src_line += 4;\r
2198                                     }\r
2199                                 }\r
2200                             }\r
2201                             break;\r
2202                         default:\r
2203                             ;\r
2204                     }\r
2205                     if(pClipBitmap != pFormatBitmap) {\r
2206                         delete pClipBitmap;\r
2207                     }\r
2208                     if(pFormatBitmap == NULL) {\r
2209                         m_pDeviceBitmap = NULL;\r
2210                         m_pFile = NULL;\r
2211                         return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
2212                     }\r
2213                     CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo(m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE);\r
2214                     delete pFormatBitmap;\r
2215                     pFormatBitmap = NULL;\r
2216                     if(pStrechBitmap == NULL) {\r
2217                         m_pDeviceBitmap = NULL;\r
2218                         m_pFile = NULL;\r
2219                         return m_status = FXCODEC_STATUS_ERR_MEMORY;\r
2220                     }\r
2221                     m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, pStrechBitmap, 0, 0);\r
2222                     delete pStrechBitmap;\r
2223                     pStrechBitmap = NULL;\r
2224                     m_pDeviceBitmap = NULL;\r
2225                     m_pFile = NULL;\r
2226                     return m_status = FXCODEC_STATUS_DECODE_FINISH;\r
2227                 }\r
2228             }\r
2229             break;\r
2230         default:\r
2231             break;\r
2232     }\r
2233     return FXCODEC_STATUS_ERROR;\r
2234 }\r
2235 ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder()\r
2236 {\r
2237     return new CCodec_ProgressiveDecoder(this);\r
2238 }\r