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