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