Chromium Code Reviews| 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 const int last_row_size = data_size % (row_size + 1); | 409 const int last_row_size = data_size % (row_size + 1); |
| 404 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); | 410 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); |
| 405 int byte_cnt = 0; | 411 int byte_cnt = 0; |
| 406 uint8_t* pSrcData = data_buf; | 412 uint8_t* pSrcData = data_buf; |
| 407 uint8_t* pDestData = dest_buf; | 413 uint8_t* pDestData = dest_buf; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 } | 480 } |
| 475 pSrcData += row_size + 1; | 481 pSrcData += row_size + 1; |
| 476 pDestData += row_size; | 482 pDestData += row_size; |
| 477 } | 483 } |
| 478 FX_Free(data_buf); | 484 FX_Free(data_buf); |
| 479 data_buf = dest_buf; | 485 data_buf = dest_buf; |
| 480 data_size = row_size * row_count - | 486 data_size = row_size * row_count - |
| 481 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); | 487 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
| 482 return TRUE; | 488 return TRUE; |
| 483 } | 489 } |
| 484 static void TIFF_PredictorEncodeLine(uint8_t* dest_buf, | 490 |
| 485 int row_size, | 491 void TIFF_PredictorEncodeLine(uint8_t* dest_buf, |
| 486 int BitsPerComponent, | 492 int row_size, |
| 487 int Colors, | 493 int BitsPerComponent, |
| 488 int Columns) { | 494 int Colors, |
| 495 int Columns) { | |
| 489 int BytesPerPixel = BitsPerComponent * Colors / 8; | 496 int BytesPerPixel = BitsPerComponent * Colors / 8; |
| 490 if (BitsPerComponent < 8) { | 497 if (BitsPerComponent < 8) { |
| 491 uint8_t mask = 0x01; | 498 uint8_t mask = 0x01; |
| 492 if (BitsPerComponent == 2) { | 499 if (BitsPerComponent == 2) { |
| 493 mask = 0x03; | 500 mask = 0x03; |
| 494 } else if (BitsPerComponent == 4) { | 501 } else if (BitsPerComponent == 4) { |
| 495 mask = 0x0F; | 502 mask = 0x0F; |
| 496 } | 503 } |
| 497 int row_bits = Colors * BitsPerComponent * Columns; | 504 int row_bits = Colors * BitsPerComponent * Columns; |
| 498 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; | 505 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 519 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; | 526 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; |
| 520 i -= BytesPerPixel) { | 527 i -= BytesPerPixel) { |
| 521 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; | 528 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 522 pixel -= | 529 pixel -= |
| 523 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; | 530 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
| 524 dest_buf[i] = pixel >> 8; | 531 dest_buf[i] = pixel >> 8; |
| 525 dest_buf[i + 1] = (uint8_t)pixel; | 532 dest_buf[i + 1] = (uint8_t)pixel; |
| 526 } | 533 } |
| 527 } | 534 } |
| 528 } | 535 } |
| 529 static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, | 536 |
| 530 FX_DWORD& data_size, | 537 FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, |
| 531 int Colors, | 538 FX_DWORD& data_size, |
| 532 int BitsPerComponent, | 539 int Colors, |
| 533 int Columns) { | 540 int BitsPerComponent, |
| 541 int Columns) { | |
| 534 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 542 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 535 if (row_size == 0) | 543 if (row_size == 0) |
| 536 return FALSE; | 544 return FALSE; |
| 537 const int row_count = (data_size + row_size - 1) / row_size; | 545 const int row_count = (data_size + row_size - 1) / row_size; |
| 538 const int last_row_size = data_size % row_size; | 546 const int last_row_size = data_size % row_size; |
| 539 for (int row = 0; row < row_count; row++) { | 547 for (int row = 0; row < row_count; row++) { |
| 540 uint8_t* scan_line = data_buf + row * row_size; | 548 uint8_t* scan_line = data_buf + row * row_size; |
| 541 if ((row + 1) * row_size > (int)data_size) { | 549 if ((row + 1) * row_size > (int)data_size) { |
| 542 row_size = last_row_size; | 550 row_size = last_row_size; |
| 543 } | 551 } |
| 544 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, | 552 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, |
| 545 Columns); | 553 Columns); |
| 546 } | 554 } |
| 547 return TRUE; | 555 return TRUE; |
| 548 } | 556 } |
| 549 static void TIFF_PredictLine(uint8_t* dest_buf, | 557 |
| 550 int row_size, | 558 void TIFF_PredictLine(uint8_t* dest_buf, |
| 551 int BitsPerComponent, | 559 int row_size, |
| 552 int Colors, | 560 int BitsPerComponent, |
| 553 int Columns) { | 561 int Colors, |
| 562 int Columns) { | |
| 554 if (BitsPerComponent == 1) { | 563 if (BitsPerComponent == 1) { |
| 555 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); | 564 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); |
| 556 int index_pre = 0; | 565 int index_pre = 0; |
| 557 int col_pre = 0; | 566 int col_pre = 0; |
| 558 for (int i = 1; i < row_bits; i++) { | 567 for (int i = 1; i < row_bits; i++) { |
| 559 int col = i % 8; | 568 int col = i % 8; |
| 560 int index = i / 8; | 569 int index = i / 8; |
| 561 if (((dest_buf[index] >> (7 - col)) & 1) ^ | 570 if (((dest_buf[index] >> (7 - col)) & 1) ^ |
| 562 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { | 571 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { |
| 563 dest_buf[index] |= 1 << (7 - col); | 572 dest_buf[index] |= 1 << (7 - col); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 577 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; | 586 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 578 dest_buf[i] = pixel >> 8; | 587 dest_buf[i] = pixel >> 8; |
| 579 dest_buf[i + 1] = (uint8_t)pixel; | 588 dest_buf[i + 1] = (uint8_t)pixel; |
| 580 } | 589 } |
| 581 } else { | 590 } else { |
| 582 for (int i = BytesPerPixel; i < row_size; i++) { | 591 for (int i = BytesPerPixel; i < row_size; i++) { |
| 583 dest_buf[i] += dest_buf[i - BytesPerPixel]; | 592 dest_buf[i] += dest_buf[i - BytesPerPixel]; |
| 584 } | 593 } |
| 585 } | 594 } |
| 586 } | 595 } |
| 587 static FX_BOOL TIFF_Predictor(uint8_t*& data_buf, | 596 |
| 588 FX_DWORD& data_size, | 597 FX_BOOL TIFF_Predictor(uint8_t*& data_buf, |
| 589 int Colors, | 598 FX_DWORD& data_size, |
| 590 int BitsPerComponent, | 599 int Colors, |
| 591 int Columns) { | 600 int BitsPerComponent, |
| 601 int Columns) { | |
| 592 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 602 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 593 if (row_size == 0) | 603 if (row_size == 0) |
| 594 return FALSE; | 604 return FALSE; |
| 595 const int row_count = (data_size + row_size - 1) / row_size; | 605 const int row_count = (data_size + row_size - 1) / row_size; |
| 596 const int last_row_size = data_size % row_size; | 606 const int last_row_size = data_size % row_size; |
| 597 for (int row = 0; row < row_count; row++) { | 607 for (int row = 0; row < row_count; row++) { |
| 598 uint8_t* scan_line = data_buf + row * row_size; | 608 uint8_t* scan_line = data_buf + row * row_size; |
| 599 if ((row + 1) * row_size > (int)data_size) { | 609 if ((row + 1) * row_size > (int)data_size) { |
| 600 row_size = last_row_size; | 610 row_size = last_row_size; |
| 601 } | 611 } |
| 602 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); | 612 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); |
| 603 } | 613 } |
| 604 return TRUE; | 614 return TRUE; |
| 605 } | 615 } |
| 606 | 616 |
| 617 void FlateUncompress(const uint8_t* src_buf, | |
|
Lei Zhang
2015/09/23 19:22:28
A bit harder to see what I changed since I moved t
| |
| 618 FX_DWORD src_size, | |
| 619 FX_DWORD orig_size, | |
| 620 uint8_t*& dest_buf, | |
| 621 FX_DWORD& dest_size, | |
| 622 FX_DWORD& offset) { | |
| 623 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; | |
| 624 FX_DWORD alloc_step = | |
| 625 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); | |
|
Tom Sepez
2015/09/23 21:48:41
nit: maybe std::min(src_size, 10240)
maybe a const
Lei Zhang
2015/09/25 09:33:49
Done.
| |
| 626 static const FX_DWORD kMaxInitialAllocSize = 10000000; | |
| 627 if (guess_size > kMaxInitialAllocSize) { | |
| 628 guess_size = kMaxInitialAllocSize; | |
| 629 alloc_step = kMaxInitialAllocSize; | |
| 630 } | |
| 631 FX_DWORD buf_size = guess_size; | |
| 632 FX_DWORD last_buf_size = buf_size; | |
| 633 | |
| 634 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 635 if (!context) { | |
| 636 dest_buf = nullptr; | |
|
Tom Sepez
2015/09/23 21:48:41
how about we set these to null/0 initially, and th
Lei Zhang
2015/09/25 09:33:48
Done.
| |
| 637 dest_size = 0; | |
| 638 return; | |
| 639 } | |
| 640 | |
| 641 nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( | |
| 642 FX_Alloc(uint8_t, guess_size + 1)); | |
| 643 guess_buf.get()[guess_size] = '\0'; | |
|
Tom Sepez
2015/09/23 21:48:41
The real std::unique_ptr has operator[]. do we wan
Lei Zhang
2015/09/25 09:33:48
There's no new equivalent to FX_Realloc(), right?
Tom Sepez
2015/09/25 16:25:34
ah.
| |
| 644 | |
| 645 FPDFAPI_FlateInput(context, src_buf, src_size); | |
| 646 | |
| 647 if (src_size < 10240) { | |
| 648 // This is the old implementation. | |
| 649 uint8_t* cur_buf = guess_buf.get(); | |
| 650 while (1) { | |
| 651 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 652 if (ret != Z_OK) | |
| 653 break; | |
| 654 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 655 if (avail_buf_size != 0) | |
| 656 break; | |
| 657 | |
| 658 // |avail_buf_size| == 0 case. | |
|
Tom Sepez
2015/09/23 21:48:41
nit: not sure this comment adds value.
Lei Zhang
2015/09/25 09:33:48
Done.
| |
| 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 dest_buf = nullptr; | |
| 664 dest_size = 0; | |
| 665 return; | |
| 666 } | |
| 667 | |
| 668 { | |
| 669 uint8_t* new_buf = | |
| 670 FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); | |
| 671 guess_buf.reset(new_buf); | |
|
Tom Sepez
2015/09/23 21:48:41
nit: how about guess_buf.reset(FX_Realloc(...)); a
Lei Zhang
2015/09/25 09:33:48
No, we get in trouble doing guess_buf.reset() and
Tom Sepez
2015/09/25 16:25:34
Acknowledged.
| |
| 672 } | |
| 673 guess_buf.get()[guess_size] = '\0'; | |
| 674 cur_buf = guess_buf.get() + old_size; | |
| 675 buf_size = guess_size - old_size; | |
| 676 } | |
| 677 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 678 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 679 if (guess_size / 2 > dest_size) { | |
| 680 { | |
| 681 uint8_t* new_buf = | |
|
Tom Sepez
2015/09/23 21:48:41
ditto
Lei Zhang
2015/09/25 09:33:48
Acknowledged.
| |
| 682 FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); | |
| 683 guess_buf.reset(new_buf); | |
| 684 } | |
| 685 guess_size = dest_size; | |
| 686 guess_buf.get()[guess_size] = '\0'; | |
| 687 } | |
| 688 dest_buf = guess_buf.release(); | |
| 689 } else { | |
| 690 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; | |
| 691 uint8_t* cur_buf = guess_buf.release(); | |
| 692 while (1) { | |
| 693 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 694 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 695 if (ret != Z_OK) { | |
| 696 last_buf_size = buf_size - avail_buf_size; | |
| 697 result_tmp_bufs.Add(cur_buf); | |
| 698 break; | |
| 699 } | |
| 700 if (avail_buf_size != 0) { | |
| 701 last_buf_size = buf_size - avail_buf_size; | |
| 702 result_tmp_bufs.Add(cur_buf); | |
| 703 break; | |
| 704 } | |
| 705 | |
| 706 // |avail_buf_size| == 0 case. | |
|
Tom Sepez
2015/09/23 21:48:41
ditto
Lei Zhang
2015/09/25 09:33:48
Done.
| |
| 707 result_tmp_bufs.Add(cur_buf); | |
| 708 cur_buf = FX_Alloc(uint8_t, buf_size + 1); | |
| 709 cur_buf[buf_size] = '\0'; | |
| 710 } | |
| 711 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 712 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 713 if (result_tmp_bufs.GetSize() == 1) { | |
| 714 dest_buf = result_tmp_bufs[0]; | |
| 715 } else { | |
| 716 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); | |
| 717 FX_DWORD result_pos = 0; | |
| 718 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { | |
| 719 uint8_t* tmp_buf = result_tmp_bufs[i]; | |
| 720 FX_DWORD tmp_buf_size = buf_size; | |
| 721 if (i == result_tmp_bufs.GetSize() - 1) { | |
| 722 tmp_buf_size = last_buf_size; | |
| 723 } | |
| 724 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); | |
| 725 result_pos += tmp_buf_size; | |
| 726 FX_Free(result_tmp_bufs[i]); | |
| 727 } | |
| 728 dest_buf = result_buf; | |
| 729 } | |
| 730 } | |
| 731 FPDFAPI_FlateEnd(context); | |
| 732 } | |
| 733 | |
| 734 } // namespace | |
| 735 | |
| 607 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { | 736 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { |
| 608 public: | 737 public: |
| 609 CCodec_FlateScanlineDecoder(); | 738 CCodec_FlateScanlineDecoder(); |
| 610 ~CCodec_FlateScanlineDecoder() override; | 739 ~CCodec_FlateScanlineDecoder() override; |
| 611 | 740 |
| 612 void Create(const uint8_t* src_buf, | 741 void Create(const uint8_t* src_buf, |
| 613 FX_DWORD src_size, | 742 FX_DWORD src_size, |
| 614 int width, | 743 int width, |
| 615 int height, | 744 int height, |
| 616 int nComps, | 745 int nComps, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 752 } | 881 } |
| 753 } | 882 } |
| 754 } else { | 883 } else { |
| 755 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); | 884 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); |
| 756 } | 885 } |
| 757 return m_pScanline; | 886 return m_pScanline; |
| 758 } | 887 } |
| 759 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { | 888 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { |
| 760 return FPDFAPI_FlateGetTotalIn(m_pFlate); | 889 return FPDFAPI_FlateGetTotalIn(m_pFlate); |
| 761 } | 890 } |
| 762 static void FlateUncompress(const uint8_t* src_buf, | |
| 763 FX_DWORD src_size, | |
| 764 FX_DWORD orig_size, | |
| 765 uint8_t*& dest_buf, | |
| 766 FX_DWORD& dest_size, | |
| 767 FX_DWORD& offset) { | |
| 768 const FX_BOOL useOldImpl = src_size < 10240; | |
| 769 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; | |
| 770 FX_DWORD alloc_step = | |
| 771 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); | |
| 772 static const FX_DWORD kMaxInitialAllocSize = 10000000; | |
| 773 if (guess_size > kMaxInitialAllocSize) { | |
| 774 guess_size = kMaxInitialAllocSize; | |
| 775 alloc_step = kMaxInitialAllocSize; | |
| 776 } | |
| 777 FX_DWORD buf_size = guess_size; | |
| 778 FX_DWORD last_buf_size = buf_size; | |
| 779 void* context = nullptr; | |
| 780 | 891 |
| 781 uint8_t* guess_buf = FX_Alloc(uint8_t, guess_size + 1); | |
| 782 uint8_t* cur_buf = guess_buf; | |
| 783 guess_buf[guess_size] = '\0'; | |
| 784 context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 785 if (!context) | |
| 786 goto fail; | |
| 787 FPDFAPI_FlateInput(context, src_buf, src_size); | |
| 788 if (useOldImpl) { | |
| 789 while (1) { | |
| 790 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 791 if (ret != Z_OK) | |
| 792 break; | |
| 793 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 794 if (avail_buf_size != 0) | |
| 795 break; | |
| 796 | |
| 797 // |avail_buf_size| == 0 case. | |
| 798 FX_DWORD old_size = guess_size; | |
| 799 guess_size += alloc_step; | |
| 800 if (guess_size < old_size || guess_size + 1 < guess_size) | |
| 801 goto fail; | |
| 802 guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1); | |
| 803 if (!guess_buf) | |
| 804 goto fail; | |
| 805 guess_buf[guess_size] = '\0'; | |
| 806 cur_buf = guess_buf + old_size; | |
| 807 buf_size = guess_size - old_size; | |
| 808 } | |
| 809 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 810 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 811 if (guess_size / 2 > dest_size) { | |
| 812 guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1); | |
| 813 if (!guess_buf) | |
| 814 goto fail; | |
| 815 guess_size = dest_size; | |
| 816 guess_buf[guess_size] = '\0'; | |
| 817 } | |
| 818 dest_buf = guess_buf; | |
| 819 } else { | |
| 820 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; | |
| 821 while (1) { | |
| 822 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 823 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 824 if (ret != Z_OK) { | |
| 825 last_buf_size = buf_size - avail_buf_size; | |
| 826 result_tmp_bufs.Add(cur_buf); | |
| 827 break; | |
| 828 } | |
| 829 if (avail_buf_size != 0) { | |
| 830 last_buf_size = buf_size - avail_buf_size; | |
| 831 result_tmp_bufs.Add(cur_buf); | |
| 832 break; | |
| 833 } | |
| 834 | |
| 835 // |avail_buf_size| == 0 case. | |
| 836 result_tmp_bufs.Add(cur_buf); | |
| 837 cur_buf = FX_Alloc(uint8_t, buf_size + 1); | |
| 838 cur_buf[buf_size] = '\0'; | |
| 839 } | |
| 840 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 841 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 842 if (result_tmp_bufs.GetSize() == 1) { | |
| 843 dest_buf = result_tmp_bufs[0]; | |
| 844 } else { | |
| 845 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); | |
| 846 FX_DWORD result_pos = 0; | |
| 847 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { | |
| 848 uint8_t* tmp_buf = result_tmp_bufs[i]; | |
| 849 FX_DWORD tmp_buf_size = buf_size; | |
| 850 if (i == result_tmp_bufs.GetSize() - 1) { | |
| 851 tmp_buf_size = last_buf_size; | |
| 852 } | |
| 853 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); | |
| 854 result_pos += tmp_buf_size; | |
| 855 FX_Free(result_tmp_bufs[i]); | |
| 856 } | |
| 857 dest_buf = result_buf; | |
| 858 } | |
| 859 } | |
| 860 FPDFAPI_FlateEnd(context); | |
| 861 return; | |
| 862 | |
| 863 fail: | |
| 864 FX_Free(guess_buf); | |
| 865 dest_buf = nullptr; | |
| 866 dest_size = 0; | |
| 867 return; | |
| 868 } | |
| 869 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( | 892 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( |
| 870 const uint8_t* src_buf, | 893 const uint8_t* src_buf, |
| 871 FX_DWORD src_size, | 894 FX_DWORD src_size, |
| 872 int width, | 895 int width, |
| 873 int height, | 896 int height, |
| 874 int nComps, | 897 int nComps, |
| 875 int bpc, | 898 int bpc, |
| 876 int predictor, | 899 int predictor, |
| 877 int Colors, | 900 int Colors, |
| 878 int BitsPerComponent, | 901 int BitsPerComponent, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 FX_DWORD src_size, | 989 FX_DWORD src_size, |
| 967 uint8_t*& dest_buf, | 990 uint8_t*& dest_buf, |
| 968 FX_DWORD& dest_size) { | 991 FX_DWORD& dest_size) { |
| 969 dest_size = src_size + src_size / 1000 + 12; | 992 dest_size = src_size + src_size / 1000 + 12; |
| 970 dest_buf = FX_Alloc(uint8_t, dest_size); | 993 dest_buf = FX_Alloc(uint8_t, dest_size); |
| 971 unsigned long temp_size = dest_size; | 994 unsigned long temp_size = dest_size; |
| 972 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 995 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 973 dest_size = (FX_DWORD)temp_size; | 996 dest_size = (FX_DWORD)temp_size; |
| 974 return TRUE; | 997 return TRUE; |
| 975 } | 998 } |
| OLD | NEW |