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/codec_int.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_ext.h" 16 #include "third_party/base/ptr_util.h" 17 #include "third_party/zlib_v128/zlib.h" 18 19 extern "C" { 20 static void* my_alloc_func(void* opaque, 21 unsigned int items, 22 unsigned int size) { 23 return FX_Alloc2D(uint8_t, items, size); 24 } 25 static void my_free_func(void* opaque, void* address) { 26 FX_Free(address); 27 } 28 static int FPDFAPI_FlateGetTotalOut(void* context) { 29 return ((z_stream*)context)->total_out; 30 } 31 static int FPDFAPI_FlateGetTotalIn(void* context) { 32 return ((z_stream*)context)->total_in; 33 } 34 35 static bool FPDFAPI_FlateCompress(unsigned char* dest_buf, 36 unsigned long* dest_size, 37 const unsigned char* src_buf, 38 unsigned long src_size) { 39 return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK; 40 } 41 42 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), 43 void (*free_func)(void*, void*)) { 44 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); 45 if (!p) 46 return nullptr; 47 48 FXSYS_memset(p, 0, sizeof(z_stream)); 49 p->zalloc = alloc_func; 50 p->zfree = free_func; 51 inflateInit(p); 52 return p; 53 } 54 55 void FPDFAPI_FlateInput(void* context, 56 const unsigned char* src_buf, 57 unsigned int src_size) { 58 ((z_stream*)context)->next_in = (unsigned char*)src_buf; 59 ((z_stream*)context)->avail_in = src_size; 60 } 61 62 int FPDFAPI_FlateOutput(void* context, 63 unsigned char* dest_buf, 64 unsigned int dest_size) { 65 ((z_stream*)context)->next_out = dest_buf; 66 ((z_stream*)context)->avail_out = dest_size; 67 unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 68 int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); 69 unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 70 unsigned int written = post_pos - pre_pos; 71 if (written < dest_size) { 72 FXSYS_memset(dest_buf + written, '\0', dest_size - written); 73 } 74 return ret; 75 } 76 77 int FPDFAPI_FlateGetAvailIn(void* context) { 78 return ((z_stream*)context)->avail_in; 79 } 80 81 int FPDFAPI_FlateGetAvailOut(void* context) { 82 return ((z_stream*)context)->avail_out; 83 } 84 85 void FPDFAPI_FlateEnd(void* context) { 86 inflateEnd((z_stream*)context); 87 ((z_stream*)context)->zfree(0, context); 88 } 89 90 } // extern "C" 91 92 namespace { 93 94 class CLZWDecoder { 95 public: 96 int Decode(uint8_t* output, 97 uint32_t& outlen, 98 const uint8_t* input, 99 uint32_t& size, 100 bool bEarlyChange); 101 102 private: 103 void AddCode(uint32_t prefix_code, uint8_t append_char); 104 void DecodeString(uint32_t code); 105 106 uint32_t m_InPos; 107 uint32_t m_OutPos; 108 uint8_t* m_pOutput; 109 const uint8_t* m_pInput; 110 bool m_Early; 111 uint32_t m_CodeArray[5021]; 112 uint32_t m_nCodes; 113 uint8_t m_DecodeStack[4000]; 114 uint32_t m_StackLen; 115 int m_CodeLen; 116 }; 117 118 void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { 119 if (m_nCodes + m_Early == 4094) { 120 return; 121 } 122 m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; 123 if (m_nCodes + m_Early == 512 - 258) { 124 m_CodeLen = 10; 125 } else if (m_nCodes + m_Early == 1024 - 258) { 126 m_CodeLen = 11; 127 } else if (m_nCodes + m_Early == 2048 - 258) { 128 m_CodeLen = 12; 129 } 130 } 131 void CLZWDecoder::DecodeString(uint32_t code) { 132 while (1) { 133 int index = code - 258; 134 if (index < 0 || index >= (int)m_nCodes) { 135 break; 136 } 137 uint32_t data = m_CodeArray[index]; 138 if (m_StackLen >= sizeof(m_DecodeStack)) { 139 return; 140 } 141 m_DecodeStack[m_StackLen++] = (uint8_t)data; 142 code = data >> 16; 143 } 144 if (m_StackLen >= sizeof(m_DecodeStack)) { 145 return; 146 } 147 m_DecodeStack[m_StackLen++] = (uint8_t)code; 148 } 149 int CLZWDecoder::Decode(uint8_t* dest_buf, 150 uint32_t& dest_size, 151 const uint8_t* src_buf, 152 uint32_t& src_size, 153 bool bEarlyChange) { 154 m_CodeLen = 9; 155 m_InPos = 0; 156 m_OutPos = 0; 157 m_pInput = src_buf; 158 m_pOutput = dest_buf; 159 m_Early = bEarlyChange ? 1 : 0; 160 m_nCodes = 0; 161 uint32_t old_code = (uint32_t)-1; 162 uint8_t last_char = 0; 163 while (1) { 164 if (m_InPos + m_CodeLen > src_size * 8) { 165 break; 166 } 167 int byte_pos = m_InPos / 8; 168 int bit_pos = m_InPos % 8, bit_left = m_CodeLen; 169 uint32_t code = 0; 170 if (bit_pos) { 171 bit_left -= 8 - bit_pos; 172 code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; 173 } 174 if (bit_left < 8) { 175 code |= m_pInput[byte_pos] >> (8 - bit_left); 176 } else { 177 bit_left -= 8; 178 code |= m_pInput[byte_pos++] << bit_left; 179 if (bit_left) { 180 code |= m_pInput[byte_pos] >> (8 - bit_left); 181 } 182 } 183 m_InPos += m_CodeLen; 184 if (code < 256) { 185 if (m_OutPos == dest_size) { 186 return -5; 187 } 188 if (m_pOutput) { 189 m_pOutput[m_OutPos] = (uint8_t)code; 190 } 191 m_OutPos++; 192 last_char = (uint8_t)code; 193 if (old_code != (uint32_t)-1) { 194 AddCode(old_code, last_char); 195 } 196 old_code = code; 197 } else if (code == 256) { 198 m_CodeLen = 9; 199 m_nCodes = 0; 200 old_code = (uint32_t)-1; 201 } else if (code == 257) { 202 break; 203 } else { 204 if (old_code == (uint32_t)-1) { 205 return 2; 206 } 207 m_StackLen = 0; 208 if (code >= m_nCodes + 258) { 209 if (m_StackLen < sizeof(m_DecodeStack)) { 210 m_DecodeStack[m_StackLen++] = last_char; 211 } 212 DecodeString(old_code); 213 } else { 214 DecodeString(code); 215 } 216 if (m_OutPos + m_StackLen > dest_size) { 217 return -5; 218 } 219 if (m_pOutput) { 220 for (uint32_t i = 0; i < m_StackLen; i++) { 221 m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; 222 } 223 } 224 m_OutPos += m_StackLen; 225 last_char = m_DecodeStack[m_StackLen - 1]; 226 if (old_code < 256) { 227 AddCode(old_code, last_char); 228 } else if (old_code - 258 >= m_nCodes) { 229 dest_size = m_OutPos; 230 src_size = (m_InPos + 7) / 8; 231 return 0; 232 } else { 233 AddCode(old_code, last_char); 234 } 235 old_code = code; 236 } 237 } 238 dest_size = m_OutPos; 239 src_size = (m_InPos + 7) / 8; 240 return 0; 241 } 242 243 uint8_t PathPredictor(int a, int b, int c) { 244 int p = a + b - c; 245 int pa = FXSYS_abs(p - a); 246 int pb = FXSYS_abs(p - b); 247 int pc = FXSYS_abs(p - c); 248 if (pa <= pb && pa <= pc) 249 return (uint8_t)a; 250 if (pb <= pc) 251 return (uint8_t)b; 252 return (uint8_t)c; 253 } 254 255 void PNG_PredictorEncode(uint8_t** data_buf, uint32_t* data_size) { 256 const int row_size = 7; 257 const int row_count = (*data_size + row_size - 1) / row_size; 258 const int last_row_size = *data_size % row_size; 259 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); 260 int byte_cnt = 0; 261 uint8_t* pSrcData = *data_buf; 262 uint8_t* pDestData = dest_buf; 263 for (int row = 0; row < row_count; row++) { 264 for (int byte = 0; byte < row_size && byte_cnt < (int)*data_size; byte++) { 265 pDestData[0] = 2; 266 uint8_t up = 0; 267 if (row) 268 up = pSrcData[byte - row_size]; 269 pDestData[byte + 1] = pSrcData[byte] - up; 270 ++byte_cnt; 271 } 272 pDestData += (row_size + 1); 273 pSrcData += row_size; 274 } 275 FX_Free(*data_buf); 276 *data_buf = dest_buf; 277 *data_size = (row_size + 1) * row_count - 278 (last_row_size > 0 ? (row_size - last_row_size) : 0); 279 } 280 281 void PNG_PredictLine(uint8_t* pDestData, 282 const uint8_t* pSrcData, 283 const uint8_t* pLastLine, 284 int bpc, 285 int nColors, 286 int nPixels) { 287 int row_size = (nPixels * bpc * nColors + 7) / 8; 288 int BytesPerPixel = (bpc * nColors + 7) / 8; 289 uint8_t tag = pSrcData[0]; 290 if (tag == 0) { 291 FXSYS_memmove(pDestData, pSrcData + 1, row_size); 292 return; 293 } 294 for (int byte = 0; byte < row_size; byte++) { 295 uint8_t raw_byte = pSrcData[byte + 1]; 296 switch (tag) { 297 case 1: { 298 uint8_t left = 0; 299 if (byte >= BytesPerPixel) { 300 left = pDestData[byte - BytesPerPixel]; 301 } 302 pDestData[byte] = raw_byte + left; 303 break; 304 } 305 case 2: { 306 uint8_t up = 0; 307 if (pLastLine) { 308 up = pLastLine[byte]; 309 } 310 pDestData[byte] = raw_byte + up; 311 break; 312 } 313 case 3: { 314 uint8_t left = 0; 315 if (byte >= BytesPerPixel) { 316 left = pDestData[byte - BytesPerPixel]; 317 } 318 uint8_t up = 0; 319 if (pLastLine) { 320 up = pLastLine[byte]; 321 } 322 pDestData[byte] = raw_byte + (up + left) / 2; 323 break; 324 } 325 case 4: { 326 uint8_t left = 0; 327 if (byte >= BytesPerPixel) { 328 left = pDestData[byte - BytesPerPixel]; 329 } 330 uint8_t up = 0; 331 if (pLastLine) { 332 up = pLastLine[byte]; 333 } 334 uint8_t upper_left = 0; 335 if (byte >= BytesPerPixel && pLastLine) { 336 upper_left = pLastLine[byte - BytesPerPixel]; 337 } 338 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); 339 break; 340 } 341 default: 342 pDestData[byte] = raw_byte; 343 break; 344 } 345 } 346 } 347 348 bool PNG_Predictor(uint8_t*& data_buf, 349 uint32_t& data_size, 350 int Colors, 351 int BitsPerComponent, 352 int Columns) { 353 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; 354 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 355 if (row_size <= 0) 356 return false; 357 const int row_count = (data_size + row_size) / (row_size + 1); 358 if (row_count <= 0) 359 return false; 360 const int last_row_size = data_size % (row_size + 1); 361 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); 362 int byte_cnt = 0; 363 uint8_t* pSrcData = data_buf; 364 uint8_t* pDestData = dest_buf; 365 for (int row = 0; row < row_count; row++) { 366 uint8_t tag = pSrcData[0]; 367 byte_cnt++; 368 if (tag == 0) { 369 int move_size = row_size; 370 if ((row + 1) * (move_size + 1) > (int)data_size) { 371 move_size = last_row_size - 1; 372 } 373 FXSYS_memmove(pDestData, pSrcData + 1, move_size); 374 pSrcData += move_size + 1; 375 pDestData += move_size; 376 byte_cnt += move_size; 377 continue; 378 } 379 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { 380 uint8_t raw_byte = pSrcData[byte + 1]; 381 switch (tag) { 382 case 1: { 383 uint8_t left = 0; 384 if (byte >= BytesPerPixel) { 385 left = pDestData[byte - BytesPerPixel]; 386 } 387 pDestData[byte] = raw_byte + left; 388 break; 389 } 390 case 2: { 391 uint8_t up = 0; 392 if (row) { 393 up = pDestData[byte - row_size]; 394 } 395 pDestData[byte] = raw_byte + up; 396 break; 397 } 398 case 3: { 399 uint8_t left = 0; 400 if (byte >= BytesPerPixel) { 401 left = pDestData[byte - BytesPerPixel]; 402 } 403 uint8_t up = 0; 404 if (row) { 405 up = pDestData[byte - row_size]; 406 } 407 pDestData[byte] = raw_byte + (up + left) / 2; 408 break; 409 } 410 case 4: { 411 uint8_t left = 0; 412 if (byte >= BytesPerPixel) { 413 left = pDestData[byte - BytesPerPixel]; 414 } 415 uint8_t up = 0; 416 if (row) { 417 up = pDestData[byte - row_size]; 418 } 419 uint8_t upper_left = 0; 420 if (byte >= BytesPerPixel && row) { 421 upper_left = pDestData[byte - row_size - BytesPerPixel]; 422 } 423 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); 424 break; 425 } 426 default: 427 pDestData[byte] = raw_byte; 428 break; 429 } 430 byte_cnt++; 431 } 432 pSrcData += row_size + 1; 433 pDestData += row_size; 434 } 435 FX_Free(data_buf); 436 data_buf = dest_buf; 437 data_size = row_size * row_count - 438 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); 439 return true; 440 } 441 442 void TIFF_PredictLine(uint8_t* dest_buf, 443 uint32_t row_size, 444 int BitsPerComponent, 445 int Colors, 446 int Columns) { 447 if (BitsPerComponent == 1) { 448 int row_bits = std::min(BitsPerComponent * Colors * Columns, 449 pdfium::base::checked_cast<int>(row_size * 8)); 450 int index_pre = 0; 451 int col_pre = 0; 452 for (int i = 1; i < row_bits; i++) { 453 int col = i % 8; 454 int index = i / 8; 455 if (((dest_buf[index] >> (7 - col)) & 1) ^ 456 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { 457 dest_buf[index] |= 1 << (7 - col); 458 } else { 459 dest_buf[index] &= ~(1 << (7 - col)); 460 } 461 index_pre = index; 462 col_pre = col; 463 } 464 return; 465 } 466 int BytesPerPixel = BitsPerComponent * Colors / 8; 467 if (BitsPerComponent == 16) { 468 for (uint32_t i = BytesPerPixel; i < row_size; i += 2) { 469 uint16_t pixel = 470 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; 471 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; 472 dest_buf[i] = pixel >> 8; 473 dest_buf[i + 1] = (uint8_t)pixel; 474 } 475 } else { 476 for (uint32_t i = BytesPerPixel; i < row_size; i++) { 477 dest_buf[i] += dest_buf[i - BytesPerPixel]; 478 } 479 } 480 } 481 482 bool TIFF_Predictor(uint8_t*& data_buf, 483 uint32_t& data_size, 484 int Colors, 485 int BitsPerComponent, 486 int Columns) { 487 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 488 if (row_size == 0) 489 return false; 490 const int row_count = (data_size + row_size - 1) / row_size; 491 const int last_row_size = data_size % row_size; 492 for (int row = 0; row < row_count; row++) { 493 uint8_t* scan_line = data_buf + row * row_size; 494 if ((row + 1) * row_size > (int)data_size) { 495 row_size = last_row_size; 496 } 497 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); 498 } 499 return true; 500 } 501 502 void FlateUncompress(const uint8_t* src_buf, 503 uint32_t src_size, 504 uint32_t orig_size, 505 uint8_t*& dest_buf, 506 uint32_t& dest_size, 507 uint32_t& offset) { 508 uint32_t guess_size = orig_size ? orig_size : src_size * 2; 509 const uint32_t kStepSize = 10240; 510 uint32_t alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize); 511 static const uint32_t kMaxInitialAllocSize = 10000000; 512 if (guess_size > kMaxInitialAllocSize) { 513 guess_size = kMaxInitialAllocSize; 514 alloc_step = kMaxInitialAllocSize; 515 } 516 uint32_t buf_size = guess_size; 517 uint32_t last_buf_size = buf_size; 518 519 dest_buf = nullptr; 520 dest_size = 0; 521 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 522 if (!context) 523 return; 524 525 std::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( 526 FX_Alloc(uint8_t, guess_size + 1)); 527 guess_buf.get()[guess_size] = '\0'; 528 529 FPDFAPI_FlateInput(context, src_buf, src_size); 530 531 if (src_size < kStepSize) { 532 // This is the old implementation. 533 uint8_t* cur_buf = guess_buf.get(); 534 while (1) { 535 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); 536 if (ret != Z_OK) 537 break; 538 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); 539 if (avail_buf_size != 0) 540 break; 541 542 uint32_t old_size = guess_size; 543 guess_size += alloc_step; 544 if (guess_size < old_size || guess_size + 1 < guess_size) { 545 FPDFAPI_FlateEnd(context); 546 return; 547 } 548 549 { 550 uint8_t* new_buf = 551 FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); 552 guess_buf.reset(new_buf); 553 } 554 guess_buf.get()[guess_size] = '\0'; 555 cur_buf = guess_buf.get() + old_size; 556 buf_size = guess_size - old_size; 557 } 558 dest_size = FPDFAPI_FlateGetTotalOut(context); 559 offset = FPDFAPI_FlateGetTotalIn(context); 560 if (guess_size / 2 > dest_size) { 561 { 562 uint8_t* new_buf = 563 FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); 564 guess_buf.reset(new_buf); 565 } 566 guess_size = dest_size; 567 guess_buf.get()[guess_size] = '\0'; 568 } 569 dest_buf = guess_buf.release(); 570 } else { 571 std::vector<uint8_t*> result_tmp_bufs; 572 uint8_t* cur_buf = guess_buf.release(); 573 while (1) { 574 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); 575 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); 576 if (ret != Z_OK) { 577 last_buf_size = buf_size - avail_buf_size; 578 result_tmp_bufs.push_back(cur_buf); 579 break; 580 } 581 if (avail_buf_size != 0) { 582 last_buf_size = buf_size - avail_buf_size; 583 result_tmp_bufs.push_back(cur_buf); 584 break; 585 } 586 result_tmp_bufs.push_back(cur_buf); 587 cur_buf = FX_Alloc(uint8_t, buf_size + 1); 588 cur_buf[buf_size] = '\0'; 589 } 590 dest_size = FPDFAPI_FlateGetTotalOut(context); 591 offset = FPDFAPI_FlateGetTotalIn(context); 592 if (result_tmp_bufs.size() == 1) { 593 dest_buf = result_tmp_bufs[0]; 594 } else { 595 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); 596 uint32_t result_pos = 0; 597 for (size_t i = 0; i < result_tmp_bufs.size(); i++) { 598 uint8_t* tmp_buf = result_tmp_bufs[i]; 599 uint32_t tmp_buf_size = buf_size; 600 if (i == result_tmp_bufs.size() - 1) { 601 tmp_buf_size = last_buf_size; 602 } 603 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); 604 result_pos += tmp_buf_size; 605 FX_Free(result_tmp_bufs[i]); 606 } 607 dest_buf = result_buf; 608 } 609 } 610 FPDFAPI_FlateEnd(context); 611 } 612 613 } // namespace 614 615 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { 616 public: 617 CCodec_FlateScanlineDecoder(); 618 ~CCodec_FlateScanlineDecoder() override; 619 620 void Create(const uint8_t* src_buf, 621 uint32_t src_size, 622 int width, 623 int height, 624 int nComps, 625 int bpc, 626 int predictor, 627 int Colors, 628 int BitsPerComponent, 629 int Columns); 630 631 // CCodec_ScanlineDecoder 632 bool v_Rewind() override; 633 uint8_t* v_GetNextLine() override; 634 uint32_t GetSrcOffset() override; 635 636 void* m_pFlate; 637 const uint8_t* m_SrcBuf; 638 uint32_t m_SrcSize; 639 uint8_t* m_pScanline; 640 uint8_t* m_pLastLine; 641 uint8_t* m_pPredictBuffer; 642 uint8_t* m_pPredictRaw; 643 int m_Predictor; 644 int m_Colors; 645 int m_BitsPerComponent; 646 int m_Columns; 647 uint32_t m_PredictPitch; 648 size_t m_LeftOver; 649 }; 650 651 CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() { 652 m_pFlate = nullptr; 653 m_pScanline = nullptr; 654 m_pLastLine = nullptr; 655 m_pPredictBuffer = nullptr; 656 m_pPredictRaw = nullptr; 657 m_LeftOver = 0; 658 } 659 CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() { 660 FX_Free(m_pScanline); 661 FX_Free(m_pLastLine); 662 FX_Free(m_pPredictBuffer); 663 FX_Free(m_pPredictRaw); 664 if (m_pFlate) { 665 FPDFAPI_FlateEnd(m_pFlate); 666 } 667 } 668 void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf, 669 uint32_t src_size, 670 int width, 671 int height, 672 int nComps, 673 int bpc, 674 int predictor, 675 int Colors, 676 int BitsPerComponent, 677 int Columns) { 678 m_SrcBuf = src_buf; 679 m_SrcSize = src_size; 680 m_OutputWidth = m_OrigWidth = width; 681 m_OutputHeight = m_OrigHeight = height; 682 m_nComps = nComps; 683 m_bpc = bpc; 684 m_Pitch = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8; 685 m_pScanline = FX_Alloc(uint8_t, m_Pitch); 686 m_Predictor = 0; 687 if (predictor) { 688 if (predictor >= 10) { 689 m_Predictor = 2; 690 } else if (predictor == 2) { 691 m_Predictor = 1; 692 } 693 if (m_Predictor) { 694 if (BitsPerComponent * Colors * Columns == 0) { 695 BitsPerComponent = m_bpc; 696 Colors = m_nComps; 697 Columns = m_OrigWidth; 698 } 699 m_Colors = Colors; 700 m_BitsPerComponent = BitsPerComponent; 701 m_Columns = Columns; 702 m_PredictPitch = 703 (static_cast<uint32_t>(m_BitsPerComponent) * m_Colors * m_Columns + 704 7) / 705 8; 706 m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); 707 m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); 708 m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); 709 } 710 } 711 } 712 bool CCodec_FlateScanlineDecoder::v_Rewind() { 713 if (m_pFlate) { 714 FPDFAPI_FlateEnd(m_pFlate); 715 } 716 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 717 if (!m_pFlate) { 718 return false; 719 } 720 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); 721 m_LeftOver = 0; 722 return true; 723 } 724 uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { 725 if (m_Predictor) { 726 if (m_Pitch == m_PredictPitch) { 727 if (m_Predictor == 2) { 728 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 729 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, 730 m_BitsPerComponent, m_Colors, m_Columns); 731 FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch); 732 } else { 733 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 734 TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, 735 m_OutputWidth); 736 } 737 } else { 738 size_t bytes_to_go = m_Pitch; 739 size_t read_leftover = 740 m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; 741 if (read_leftover) { 742 FXSYS_memcpy(m_pScanline, 743 m_pPredictBuffer + m_PredictPitch - m_LeftOver, 744 read_leftover); 745 m_LeftOver -= read_leftover; 746 bytes_to_go -= read_leftover; 747 } 748 while (bytes_to_go) { 749 if (m_Predictor == 2) { 750 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 751 PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine, 752 m_BitsPerComponent, m_Colors, m_Columns); 753 FXSYS_memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch); 754 } else { 755 FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch); 756 TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, 757 m_Colors, m_Columns); 758 } 759 size_t read_bytes = 760 m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; 761 FXSYS_memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, 762 read_bytes); 763 m_LeftOver += m_PredictPitch - read_bytes; 764 bytes_to_go -= read_bytes; 765 } 766 } 767 } else { 768 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 769 } 770 return m_pScanline; 771 } 772 uint32_t CCodec_FlateScanlineDecoder::GetSrcOffset() { 773 return FPDFAPI_FlateGetTotalIn(m_pFlate); 774 } 775 776 std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder( 777 const uint8_t* src_buf, 778 uint32_t src_size, 779 int width, 780 int height, 781 int nComps, 782 int bpc, 783 int predictor, 784 int Colors, 785 int BitsPerComponent, 786 int Columns) { 787 auto pDecoder = pdfium::MakeUnique<CCodec_FlateScanlineDecoder>(); 788 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, 789 Colors, BitsPerComponent, Columns); 790 return std::move(pDecoder); 791 } 792 793 uint32_t CCodec_FlateModule::FlateOrLZWDecode(bool bLZW, 794 const uint8_t* src_buf, 795 uint32_t src_size, 796 bool bEarlyChange, 797 int predictor, 798 int Colors, 799 int BitsPerComponent, 800 int Columns, 801 uint32_t estimated_size, 802 uint8_t*& dest_buf, 803 uint32_t& dest_size) { 804 dest_buf = nullptr; 805 uint32_t offset = 0; 806 int predictor_type = 0; 807 if (predictor) { 808 if (predictor >= 10) { 809 predictor_type = 2; 810 } else if (predictor == 2) { 811 predictor_type = 1; 812 } 813 } 814 if (bLZW) { 815 { 816 std::unique_ptr<CLZWDecoder> decoder(new CLZWDecoder); 817 dest_size = (uint32_t)-1; 818 offset = src_size; 819 int err = 820 decoder->Decode(nullptr, dest_size, src_buf, offset, bEarlyChange); 821 if (err || dest_size == 0 || dest_size + 1 < dest_size) { 822 return FX_INVALID_OFFSET; 823 } 824 } 825 { 826 std::unique_ptr<CLZWDecoder> decoder(new CLZWDecoder); 827 dest_buf = FX_Alloc(uint8_t, dest_size + 1); 828 dest_buf[dest_size] = '\0'; 829 decoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); 830 } 831 } else { 832 FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, 833 offset); 834 } 835 if (predictor_type == 0) { 836 return offset; 837 } 838 bool ret = true; 839 if (predictor_type == 2) { 840 ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 841 } else if (predictor_type == 1) { 842 ret = 843 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 844 } 845 return ret ? offset : FX_INVALID_OFFSET; 846 } 847 848 bool CCodec_FlateModule::Encode(const uint8_t* src_buf, 849 uint32_t src_size, 850 uint8_t** dest_buf, 851 uint32_t* dest_size) { 852 *dest_size = src_size + src_size / 1000 + 12; 853 *dest_buf = FX_Alloc(uint8_t, *dest_size); 854 unsigned long temp_size = *dest_size; 855 if (!FPDFAPI_FlateCompress(*dest_buf, &temp_size, src_buf, src_size)) 856 return false; 857 858 *dest_size = (uint32_t)temp_size; 859 return true; 860 } 861 862 bool CCodec_FlateModule::PngEncode(const uint8_t* src_buf, 863 uint32_t src_size, 864 uint8_t** dest_buf, 865 uint32_t* dest_size) { 866 uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); 867 FXSYS_memcpy(pSrcBuf, src_buf, src_size); 868 PNG_PredictorEncode(&pSrcBuf, &src_size); 869 bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); 870 FX_Free(pSrcBuf); 871 return ret; 872 } 873