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