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