| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../../third_party/base/nonstd_unique_ptr.h" | 7 #include "../../../../third_party/base/nonstd_unique_ptr.h" |
| 8 #include "../../../../third_party/zlib_v128/zlib.h" | 8 #include "../../../../third_party/zlib_v128/zlib.h" |
| 9 #include "../../../include/fxcodec/fx_codec.h" | 9 #include "../../../include/fxcodec/fx_codec.h" |
| 10 #include "../../../include/fxcodec/fx_codec_flate.h" | 10 #include "../../../include/fxcodec/fx_codec_flate.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 } | 68 } |
| 69 int FPDFAPI_FlateGetAvailOut(void* context) { | 69 int FPDFAPI_FlateGetAvailOut(void* context) { |
| 70 return ((z_stream*)context)->avail_out; | 70 return ((z_stream*)context)->avail_out; |
| 71 } | 71 } |
| 72 void FPDFAPI_FlateEnd(void* context) { | 72 void FPDFAPI_FlateEnd(void* context) { |
| 73 inflateEnd((z_stream*)context); | 73 inflateEnd((z_stream*)context); |
| 74 ((z_stream*)context)->zfree(0, context); | 74 ((z_stream*)context)->zfree(0, context); |
| 75 } | 75 } |
| 76 } // extern "C" | 76 } // extern "C" |
| 77 | 77 |
| 78 namespace { |
| 79 |
| 78 class CLZWDecoder { | 80 class CLZWDecoder { |
| 79 public: | 81 public: |
| 80 int Decode(uint8_t* output, | 82 int Decode(uint8_t* output, |
| 81 FX_DWORD& outlen, | 83 FX_DWORD& outlen, |
| 82 const uint8_t* input, | 84 const uint8_t* input, |
| 83 FX_DWORD& size, | 85 FX_DWORD& size, |
| 84 FX_BOOL bEarlyChange); | 86 FX_BOOL bEarlyChange); |
| 85 | 87 |
| 86 private: | 88 private: |
| 87 void AddCode(FX_DWORD prefix_code, uint8_t append_char); | 89 void AddCode(FX_DWORD prefix_code, uint8_t append_char); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 } else { | 217 } else { |
| 216 AddCode(old_code, last_char); | 218 AddCode(old_code, last_char); |
| 217 } | 219 } |
| 218 old_code = code; | 220 old_code = code; |
| 219 } | 221 } |
| 220 } | 222 } |
| 221 dest_size = m_OutPos; | 223 dest_size = m_OutPos; |
| 222 src_size = (m_InPos + 7) / 8; | 224 src_size = (m_InPos + 7) / 8; |
| 223 return 0; | 225 return 0; |
| 224 } | 226 } |
| 225 static uint8_t PaethPredictor(int a, int b, int c) { | 227 |
| 228 uint8_t PaethPredictor(int a, int b, int c) { |
| 226 int p = a + b - c; | 229 int p = a + b - c; |
| 227 int pa = FXSYS_abs(p - a); | 230 int pa = FXSYS_abs(p - a); |
| 228 int pb = FXSYS_abs(p - b); | 231 int pb = FXSYS_abs(p - b); |
| 229 int pc = FXSYS_abs(p - c); | 232 int pc = FXSYS_abs(p - c); |
| 230 if (pa <= pb && pa <= pc) { | 233 if (pa <= pb && pa <= pc) { |
| 231 return (uint8_t)a; | 234 return (uint8_t)a; |
| 232 } | 235 } |
| 233 if (pb <= pc) { | 236 if (pb <= pc) { |
| 234 return (uint8_t)b; | 237 return (uint8_t)b; |
| 235 } | 238 } |
| 236 return (uint8_t)c; | 239 return (uint8_t)c; |
| 237 } | 240 } |
| 238 static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, | 241 |
| 239 FX_DWORD& data_size, | 242 FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, |
| 240 int predictor, | 243 FX_DWORD& data_size, |
| 241 int Colors, | 244 int predictor, |
| 242 int BitsPerComponent, | 245 int Colors, |
| 243 int Columns) { | 246 int BitsPerComponent, |
| 247 int Columns) { |
| 244 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 248 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 245 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 249 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 246 if (row_size <= 0) | 250 if (row_size <= 0) |
| 247 return FALSE; | 251 return FALSE; |
| 248 const int row_count = (data_size + row_size - 1) / row_size; | 252 const int row_count = (data_size + row_size - 1) / row_size; |
| 249 const int last_row_size = data_size % row_size; | 253 const int last_row_size = data_size % row_size; |
| 250 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); | 254 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); |
| 251 int byte_cnt = 0; | 255 int byte_cnt = 0; |
| 252 uint8_t* pSrcData = data_buf; | 256 uint8_t* pSrcData = data_buf; |
| 253 uint8_t* pDestData = dest_buf; | 257 uint8_t* pDestData = dest_buf; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 } | 321 } |
| 318 pDestData += (row_size + 1); | 322 pDestData += (row_size + 1); |
| 319 pSrcData += row_size; | 323 pSrcData += row_size; |
| 320 } | 324 } |
| 321 FX_Free(data_buf); | 325 FX_Free(data_buf); |
| 322 data_buf = dest_buf; | 326 data_buf = dest_buf; |
| 323 data_size = (row_size + 1) * row_count - | 327 data_size = (row_size + 1) * row_count - |
| 324 (last_row_size > 0 ? (row_size - last_row_size) : 0); | 328 (last_row_size > 0 ? (row_size - last_row_size) : 0); |
| 325 return TRUE; | 329 return TRUE; |
| 326 } | 330 } |
| 327 static void PNG_PredictLine(uint8_t* pDestData, | 331 |
| 328 const uint8_t* pSrcData, | 332 void PNG_PredictLine(uint8_t* pDestData, |
| 329 const uint8_t* pLastLine, | 333 const uint8_t* pSrcData, |
| 330 int bpc, | 334 const uint8_t* pLastLine, |
| 331 int nColors, | 335 int bpc, |
| 332 int nPixels) { | 336 int nColors, |
| 337 int nPixels) { |
| 333 int row_size = (nPixels * bpc * nColors + 7) / 8; | 338 int row_size = (nPixels * bpc * nColors + 7) / 8; |
| 334 int BytesPerPixel = (bpc * nColors + 7) / 8; | 339 int BytesPerPixel = (bpc * nColors + 7) / 8; |
| 335 uint8_t tag = pSrcData[0]; | 340 uint8_t tag = pSrcData[0]; |
| 336 if (tag == 0) { | 341 if (tag == 0) { |
| 337 FXSYS_memmove(pDestData, pSrcData + 1, row_size); | 342 FXSYS_memmove(pDestData, pSrcData + 1, row_size); |
| 338 return; | 343 return; |
| 339 } | 344 } |
| 340 for (int byte = 0; byte < row_size; byte++) { | 345 for (int byte = 0; byte < row_size; byte++) { |
| 341 uint8_t raw_byte = pSrcData[byte + 1]; | 346 uint8_t raw_byte = pSrcData[byte + 1]; |
| 342 switch (tag) { | 347 switch (tag) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } | 388 } |
| 384 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); | 389 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
| 385 break; | 390 break; |
| 386 } | 391 } |
| 387 default: | 392 default: |
| 388 pDestData[byte] = raw_byte; | 393 pDestData[byte] = raw_byte; |
| 389 break; | 394 break; |
| 390 } | 395 } |
| 391 } | 396 } |
| 392 } | 397 } |
| 393 static FX_BOOL PNG_Predictor(uint8_t*& data_buf, | 398 |
| 394 FX_DWORD& data_size, | 399 FX_BOOL PNG_Predictor(uint8_t*& data_buf, |
| 395 int Colors, | 400 FX_DWORD& data_size, |
| 396 int BitsPerComponent, | 401 int Colors, |
| 397 int Columns) { | 402 int BitsPerComponent, |
| 403 int Columns) { |
| 398 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 404 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 399 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 405 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 400 if (row_size <= 0) | 406 if (row_size <= 0) |
| 401 return FALSE; | 407 return FALSE; |
| 402 const int row_count = (data_size + row_size) / (row_size + 1); | 408 const int row_count = (data_size + row_size) / (row_size + 1); |
| 403 if (row_count <= 0) | 409 if (row_count <= 0) |
| 404 return FALSE; | 410 return FALSE; |
| 405 const int last_row_size = data_size % (row_size + 1); | 411 const int last_row_size = data_size % (row_size + 1); |
| 406 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); | 412 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); |
| 407 int byte_cnt = 0; | 413 int byte_cnt = 0; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 } | 482 } |
| 477 pSrcData += row_size + 1; | 483 pSrcData += row_size + 1; |
| 478 pDestData += row_size; | 484 pDestData += row_size; |
| 479 } | 485 } |
| 480 FX_Free(data_buf); | 486 FX_Free(data_buf); |
| 481 data_buf = dest_buf; | 487 data_buf = dest_buf; |
| 482 data_size = row_size * row_count - | 488 data_size = row_size * row_count - |
| 483 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); | 489 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
| 484 return TRUE; | 490 return TRUE; |
| 485 } | 491 } |
| 486 static void TIFF_PredictorEncodeLine(uint8_t* dest_buf, | 492 |
| 487 int row_size, | 493 void TIFF_PredictorEncodeLine(uint8_t* dest_buf, |
| 488 int BitsPerComponent, | 494 int row_size, |
| 489 int Colors, | 495 int BitsPerComponent, |
| 490 int Columns) { | 496 int Colors, |
| 497 int Columns) { |
| 491 int BytesPerPixel = BitsPerComponent * Colors / 8; | 498 int BytesPerPixel = BitsPerComponent * Colors / 8; |
| 492 if (BitsPerComponent < 8) { | 499 if (BitsPerComponent < 8) { |
| 493 uint8_t mask = 0x01; | 500 uint8_t mask = 0x01; |
| 494 if (BitsPerComponent == 2) { | 501 if (BitsPerComponent == 2) { |
| 495 mask = 0x03; | 502 mask = 0x03; |
| 496 } else if (BitsPerComponent == 4) { | 503 } else if (BitsPerComponent == 4) { |
| 497 mask = 0x0F; | 504 mask = 0x0F; |
| 498 } | 505 } |
| 499 int row_bits = Colors * BitsPerComponent * Columns; | 506 int row_bits = Colors * BitsPerComponent * Columns; |
| 500 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; | 507 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 521 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; | 528 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; |
| 522 i -= BytesPerPixel) { | 529 i -= BytesPerPixel) { |
| 523 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; | 530 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 524 pixel -= | 531 pixel -= |
| 525 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; | 532 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
| 526 dest_buf[i] = pixel >> 8; | 533 dest_buf[i] = pixel >> 8; |
| 527 dest_buf[i + 1] = (uint8_t)pixel; | 534 dest_buf[i + 1] = (uint8_t)pixel; |
| 528 } | 535 } |
| 529 } | 536 } |
| 530 } | 537 } |
| 531 static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, | 538 |
| 532 FX_DWORD& data_size, | 539 FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, |
| 533 int Colors, | 540 FX_DWORD& data_size, |
| 534 int BitsPerComponent, | 541 int Colors, |
| 535 int Columns) { | 542 int BitsPerComponent, |
| 543 int Columns) { |
| 536 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 544 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 537 if (row_size == 0) | 545 if (row_size == 0) |
| 538 return FALSE; | 546 return FALSE; |
| 539 const int row_count = (data_size + row_size - 1) / row_size; | 547 const int row_count = (data_size + row_size - 1) / row_size; |
| 540 const int last_row_size = data_size % row_size; | 548 const int last_row_size = data_size % row_size; |
| 541 for (int row = 0; row < row_count; row++) { | 549 for (int row = 0; row < row_count; row++) { |
| 542 uint8_t* scan_line = data_buf + row * row_size; | 550 uint8_t* scan_line = data_buf + row * row_size; |
| 543 if ((row + 1) * row_size > (int)data_size) { | 551 if ((row + 1) * row_size > (int)data_size) { |
| 544 row_size = last_row_size; | 552 row_size = last_row_size; |
| 545 } | 553 } |
| 546 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, | 554 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, |
| 547 Columns); | 555 Columns); |
| 548 } | 556 } |
| 549 return TRUE; | 557 return TRUE; |
| 550 } | 558 } |
| 551 static void TIFF_PredictLine(uint8_t* dest_buf, | 559 |
| 552 int row_size, | 560 void TIFF_PredictLine(uint8_t* dest_buf, |
| 553 int BitsPerComponent, | 561 int row_size, |
| 554 int Colors, | 562 int BitsPerComponent, |
| 555 int Columns) { | 563 int Colors, |
| 564 int Columns) { |
| 556 if (BitsPerComponent == 1) { | 565 if (BitsPerComponent == 1) { |
| 557 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); | 566 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); |
| 558 int index_pre = 0; | 567 int index_pre = 0; |
| 559 int col_pre = 0; | 568 int col_pre = 0; |
| 560 for (int i = 1; i < row_bits; i++) { | 569 for (int i = 1; i < row_bits; i++) { |
| 561 int col = i % 8; | 570 int col = i % 8; |
| 562 int index = i / 8; | 571 int index = i / 8; |
| 563 if (((dest_buf[index] >> (7 - col)) & 1) ^ | 572 if (((dest_buf[index] >> (7 - col)) & 1) ^ |
| 564 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { | 573 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { |
| 565 dest_buf[index] |= 1 << (7 - col); | 574 dest_buf[index] |= 1 << (7 - col); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 579 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; | 588 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 580 dest_buf[i] = pixel >> 8; | 589 dest_buf[i] = pixel >> 8; |
| 581 dest_buf[i + 1] = (uint8_t)pixel; | 590 dest_buf[i + 1] = (uint8_t)pixel; |
| 582 } | 591 } |
| 583 } else { | 592 } else { |
| 584 for (int i = BytesPerPixel; i < row_size; i++) { | 593 for (int i = BytesPerPixel; i < row_size; i++) { |
| 585 dest_buf[i] += dest_buf[i - BytesPerPixel]; | 594 dest_buf[i] += dest_buf[i - BytesPerPixel]; |
| 586 } | 595 } |
| 587 } | 596 } |
| 588 } | 597 } |
| 589 static FX_BOOL TIFF_Predictor(uint8_t*& data_buf, | 598 |
| 590 FX_DWORD& data_size, | 599 FX_BOOL TIFF_Predictor(uint8_t*& data_buf, |
| 591 int Colors, | 600 FX_DWORD& data_size, |
| 592 int BitsPerComponent, | 601 int Colors, |
| 593 int Columns) { | 602 int BitsPerComponent, |
| 603 int Columns) { |
| 594 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 604 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 595 if (row_size == 0) | 605 if (row_size == 0) |
| 596 return FALSE; | 606 return FALSE; |
| 597 const int row_count = (data_size + row_size - 1) / row_size; | 607 const int row_count = (data_size + row_size - 1) / row_size; |
| 598 const int last_row_size = data_size % row_size; | 608 const int last_row_size = data_size % row_size; |
| 599 for (int row = 0; row < row_count; row++) { | 609 for (int row = 0; row < row_count; row++) { |
| 600 uint8_t* scan_line = data_buf + row * row_size; | 610 uint8_t* scan_line = data_buf + row * row_size; |
| 601 if ((row + 1) * row_size > (int)data_size) { | 611 if ((row + 1) * row_size > (int)data_size) { |
| 602 row_size = last_row_size; | 612 row_size = last_row_size; |
| 603 } | 613 } |
| 604 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); | 614 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); |
| 605 } | 615 } |
| 606 return TRUE; | 616 return TRUE; |
| 607 } | 617 } |
| 608 | 618 |
| 619 void FlateUncompress(const uint8_t* src_buf, |
| 620 FX_DWORD src_size, |
| 621 FX_DWORD orig_size, |
| 622 uint8_t*& dest_buf, |
| 623 FX_DWORD& dest_size, |
| 624 FX_DWORD& offset) { |
| 625 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; |
| 626 const FX_DWORD kStepSize = 10240; |
| 627 FX_DWORD alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize); |
| 628 static const FX_DWORD kMaxInitialAllocSize = 10000000; |
| 629 if (guess_size > kMaxInitialAllocSize) { |
| 630 guess_size = kMaxInitialAllocSize; |
| 631 alloc_step = kMaxInitialAllocSize; |
| 632 } |
| 633 FX_DWORD buf_size = guess_size; |
| 634 FX_DWORD last_buf_size = buf_size; |
| 635 |
| 636 dest_buf = nullptr; |
| 637 dest_size = 0; |
| 638 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
| 639 if (!context) |
| 640 return; |
| 641 |
| 642 nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( |
| 643 FX_Alloc(uint8_t, guess_size + 1)); |
| 644 guess_buf.get()[guess_size] = '\0'; |
| 645 |
| 646 FPDFAPI_FlateInput(context, src_buf, src_size); |
| 647 |
| 648 if (src_size < kStepSize) { |
| 649 // This is the old implementation. |
| 650 uint8_t* cur_buf = guess_buf.get(); |
| 651 while (1) { |
| 652 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
| 653 if (ret != Z_OK) |
| 654 break; |
| 655 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
| 656 if (avail_buf_size != 0) |
| 657 break; |
| 658 |
| 659 FX_DWORD old_size = guess_size; |
| 660 guess_size += alloc_step; |
| 661 if (guess_size < old_size || guess_size + 1 < guess_size) { |
| 662 FPDFAPI_FlateEnd(context); |
| 663 return; |
| 664 } |
| 665 |
| 666 { |
| 667 uint8_t* new_buf = |
| 668 FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); |
| 669 guess_buf.reset(new_buf); |
| 670 } |
| 671 guess_buf.get()[guess_size] = '\0'; |
| 672 cur_buf = guess_buf.get() + old_size; |
| 673 buf_size = guess_size - old_size; |
| 674 } |
| 675 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 676 offset = FPDFAPI_FlateGetTotalIn(context); |
| 677 if (guess_size / 2 > dest_size) { |
| 678 { |
| 679 uint8_t* new_buf = |
| 680 FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); |
| 681 guess_buf.reset(new_buf); |
| 682 } |
| 683 guess_size = dest_size; |
| 684 guess_buf.get()[guess_size] = '\0'; |
| 685 } |
| 686 dest_buf = guess_buf.release(); |
| 687 } else { |
| 688 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; |
| 689 uint8_t* cur_buf = guess_buf.release(); |
| 690 while (1) { |
| 691 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
| 692 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
| 693 if (ret != Z_OK) { |
| 694 last_buf_size = buf_size - avail_buf_size; |
| 695 result_tmp_bufs.Add(cur_buf); |
| 696 break; |
| 697 } |
| 698 if (avail_buf_size != 0) { |
| 699 last_buf_size = buf_size - avail_buf_size; |
| 700 result_tmp_bufs.Add(cur_buf); |
| 701 break; |
| 702 } |
| 703 |
| 704 result_tmp_bufs.Add(cur_buf); |
| 705 cur_buf = FX_Alloc(uint8_t, buf_size + 1); |
| 706 cur_buf[buf_size] = '\0'; |
| 707 } |
| 708 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 709 offset = FPDFAPI_FlateGetTotalIn(context); |
| 710 if (result_tmp_bufs.GetSize() == 1) { |
| 711 dest_buf = result_tmp_bufs[0]; |
| 712 } else { |
| 713 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); |
| 714 FX_DWORD result_pos = 0; |
| 715 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 716 uint8_t* tmp_buf = result_tmp_bufs[i]; |
| 717 FX_DWORD tmp_buf_size = buf_size; |
| 718 if (i == result_tmp_bufs.GetSize() - 1) { |
| 719 tmp_buf_size = last_buf_size; |
| 720 } |
| 721 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); |
| 722 result_pos += tmp_buf_size; |
| 723 FX_Free(result_tmp_bufs[i]); |
| 724 } |
| 725 dest_buf = result_buf; |
| 726 } |
| 727 } |
| 728 FPDFAPI_FlateEnd(context); |
| 729 } |
| 730 |
| 731 } // namespace |
| 732 |
| 609 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { | 733 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { |
| 610 public: | 734 public: |
| 611 CCodec_FlateScanlineDecoder(); | 735 CCodec_FlateScanlineDecoder(); |
| 612 ~CCodec_FlateScanlineDecoder() override; | 736 ~CCodec_FlateScanlineDecoder() override; |
| 613 | 737 |
| 614 void Create(const uint8_t* src_buf, | 738 void Create(const uint8_t* src_buf, |
| 615 FX_DWORD src_size, | 739 FX_DWORD src_size, |
| 616 int width, | 740 int width, |
| 617 int height, | 741 int height, |
| 618 int nComps, | 742 int nComps, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 } | 878 } |
| 755 } | 879 } |
| 756 } else { | 880 } else { |
| 757 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); | 881 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); |
| 758 } | 882 } |
| 759 return m_pScanline; | 883 return m_pScanline; |
| 760 } | 884 } |
| 761 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { | 885 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { |
| 762 return FPDFAPI_FlateGetTotalIn(m_pFlate); | 886 return FPDFAPI_FlateGetTotalIn(m_pFlate); |
| 763 } | 887 } |
| 764 static void FlateUncompress(const uint8_t* src_buf, | |
| 765 FX_DWORD src_size, | |
| 766 FX_DWORD orig_size, | |
| 767 uint8_t*& dest_buf, | |
| 768 FX_DWORD& dest_size, | |
| 769 FX_DWORD& offset) { | |
| 770 const FX_BOOL useOldImpl = src_size < 10240; | |
| 771 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; | |
| 772 FX_DWORD alloc_step = | |
| 773 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); | |
| 774 static const FX_DWORD kMaxInitialAllocSize = 10000000; | |
| 775 if (guess_size > kMaxInitialAllocSize) { | |
| 776 guess_size = kMaxInitialAllocSize; | |
| 777 alloc_step = kMaxInitialAllocSize; | |
| 778 } | |
| 779 FX_DWORD buf_size = guess_size; | |
| 780 FX_DWORD last_buf_size = buf_size; | |
| 781 void* context = nullptr; | |
| 782 | 888 |
| 783 uint8_t* guess_buf = FX_Alloc(uint8_t, guess_size + 1); | |
| 784 uint8_t* cur_buf = guess_buf; | |
| 785 guess_buf[guess_size] = '\0'; | |
| 786 context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 787 if (!context) | |
| 788 goto fail; | |
| 789 FPDFAPI_FlateInput(context, src_buf, src_size); | |
| 790 if (useOldImpl) { | |
| 791 while (1) { | |
| 792 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 793 if (ret != Z_OK) | |
| 794 break; | |
| 795 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 796 if (avail_buf_size != 0) | |
| 797 break; | |
| 798 | |
| 799 // |avail_buf_size| == 0 case. | |
| 800 FX_DWORD old_size = guess_size; | |
| 801 guess_size += alloc_step; | |
| 802 if (guess_size < old_size || guess_size + 1 < guess_size) | |
| 803 goto fail; | |
| 804 guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1); | |
| 805 if (!guess_buf) | |
| 806 goto fail; | |
| 807 guess_buf[guess_size] = '\0'; | |
| 808 cur_buf = guess_buf + old_size; | |
| 809 buf_size = guess_size - old_size; | |
| 810 } | |
| 811 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 812 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 813 if (guess_size / 2 > dest_size) { | |
| 814 guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1); | |
| 815 if (!guess_buf) | |
| 816 goto fail; | |
| 817 guess_size = dest_size; | |
| 818 guess_buf[guess_size] = '\0'; | |
| 819 } | |
| 820 dest_buf = guess_buf; | |
| 821 } else { | |
| 822 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; | |
| 823 while (1) { | |
| 824 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 825 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 826 if (ret != Z_OK) { | |
| 827 last_buf_size = buf_size - avail_buf_size; | |
| 828 result_tmp_bufs.Add(cur_buf); | |
| 829 break; | |
| 830 } | |
| 831 if (avail_buf_size != 0) { | |
| 832 last_buf_size = buf_size - avail_buf_size; | |
| 833 result_tmp_bufs.Add(cur_buf); | |
| 834 break; | |
| 835 } | |
| 836 | |
| 837 // |avail_buf_size| == 0 case. | |
| 838 result_tmp_bufs.Add(cur_buf); | |
| 839 cur_buf = FX_Alloc(uint8_t, buf_size + 1); | |
| 840 cur_buf[buf_size] = '\0'; | |
| 841 } | |
| 842 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 843 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 844 if (result_tmp_bufs.GetSize() == 1) { | |
| 845 dest_buf = result_tmp_bufs[0]; | |
| 846 } else { | |
| 847 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); | |
| 848 FX_DWORD result_pos = 0; | |
| 849 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { | |
| 850 uint8_t* tmp_buf = result_tmp_bufs[i]; | |
| 851 FX_DWORD tmp_buf_size = buf_size; | |
| 852 if (i == result_tmp_bufs.GetSize() - 1) { | |
| 853 tmp_buf_size = last_buf_size; | |
| 854 } | |
| 855 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); | |
| 856 result_pos += tmp_buf_size; | |
| 857 FX_Free(result_tmp_bufs[i]); | |
| 858 } | |
| 859 dest_buf = result_buf; | |
| 860 } | |
| 861 } | |
| 862 FPDFAPI_FlateEnd(context); | |
| 863 return; | |
| 864 | |
| 865 fail: | |
| 866 FX_Free(guess_buf); | |
| 867 dest_buf = nullptr; | |
| 868 dest_size = 0; | |
| 869 return; | |
| 870 } | |
| 871 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( | 889 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( |
| 872 const uint8_t* src_buf, | 890 const uint8_t* src_buf, |
| 873 FX_DWORD src_size, | 891 FX_DWORD src_size, |
| 874 int width, | 892 int width, |
| 875 int height, | 893 int height, |
| 876 int nComps, | 894 int nComps, |
| 877 int bpc, | 895 int bpc, |
| 878 int predictor, | 896 int predictor, |
| 879 int Colors, | 897 int Colors, |
| 880 int BitsPerComponent, | 898 int BitsPerComponent, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 FX_DWORD src_size, | 986 FX_DWORD src_size, |
| 969 uint8_t*& dest_buf, | 987 uint8_t*& dest_buf, |
| 970 FX_DWORD& dest_size) { | 988 FX_DWORD& dest_size) { |
| 971 dest_size = src_size + src_size / 1000 + 12; | 989 dest_size = src_size + src_size / 1000 + 12; |
| 972 dest_buf = FX_Alloc(uint8_t, dest_size); | 990 dest_buf = FX_Alloc(uint8_t, dest_size); |
| 973 unsigned long temp_size = dest_size; | 991 unsigned long temp_size = dest_size; |
| 974 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 992 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 975 dest_size = (FX_DWORD)temp_size; | 993 dest_size = (FX_DWORD)temp_size; |
| 976 return TRUE; | 994 return TRUE; |
| 977 } | 995 } |
| OLD | NEW |