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