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" 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 } 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 != 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 2352 ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { 2353 return new CCodec_ProgressiveDecoder(this); 2354 } 2355