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