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