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