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 "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
| 8 #include "../../../include/fpdfapi/fpdf_pageobj.h" | 9 #include "../../../include/fpdfapi/fpdf_pageobj.h" |
| 9 #include "../../../include/fpdfapi/fpdf_render.h" | 10 #include "../../../include/fpdfapi/fpdf_render.h" |
| 10 #include "../../../include/fxcodec/fx_codec.h" | 11 #include "../../../include/fxcodec/fx_codec.h" |
| 11 #include "../../../include/fxcrt/fx_safe_types.h" | 12 #include "../../../include/fxcrt/fx_safe_types.h" |
| 12 #include "../../../include/fxge/fx_ge.h" | 13 #include "../../../include/fxge/fx_ge.h" |
| 13 #include "../fpdf_page/pageint.h" | 14 #include "../fpdf_page/pageint.h" |
| 14 #include "render_int.h" | 15 #include "render_int.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 | 49 |
| 49 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) | 50 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) |
| 50 { | 51 { |
| 51 FX_SAFE_DWORD pitch = bpp; | 52 FX_SAFE_DWORD pitch = bpp; |
| 52 pitch *= width; | 53 pitch *= width; |
| 53 pitch += 31; | 54 pitch += 31; |
| 54 pitch /= 8; | 55 pitch /= 8; |
| 55 return pitch; | 56 return pitch; |
| 56 } | 57 } |
| 57 | 58 |
| 59 // Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(), | |
| 60 // because nonstd::unique_ptr does not support custom deleters yet. | |
| 61 class JpxBitMapContext | |
| 62 { | |
| 63 public: | |
| 64 explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) | |
| 65 : jpx_module_(jpx_module), | |
| 66 ctx_(nullptr), | |
| 67 output_offsets_(nullptr) {} | |
| 68 | |
| 69 ~JpxBitMapContext() { | |
| 70 FX_Free(output_offsets_); | |
| 71 jpx_module_->DestroyDecoder(ctx_); | |
| 72 } | |
| 73 | |
| 74 // Takes ownership of |ctx|. | |
| 75 void set_context(void* ctx) { | |
| 76 ctx_ = ctx; | |
| 77 } | |
| 78 | |
| 79 void* context() { | |
| 80 return ctx_; | |
| 81 } | |
| 82 | |
| 83 // Takes ownership of |output_offsets|. | |
| 84 void set_output_offsets(FX_LPBYTE output_offsets) { | |
|
Tom Sepez
2015/06/06 19:05:04
nit: prefer void* to LPBYTE in new code.
Lei Zhang
2015/06/08 19:35:20
LPBYTE is unsigned char*.
| |
| 85 output_offsets_ = output_offsets; | |
| 86 } | |
| 87 | |
| 88 FX_LPBYTE output_offsets() { | |
| 89 return output_offsets_; | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 ICodec_JpxModule* jpx_module_; // Weak pointer. | |
| 94 void* ctx_; // Decoder context, owned. | |
| 95 FX_LPBYTE output_offsets_; // Output offets for decoding, owned. | |
| 96 | |
| 97 // Disallow evil constructors | |
| 98 JpxBitMapContext(const JpxBitMapContext&); | |
| 99 void operator=(const JpxBitMapContext&); | |
| 100 }; | |
| 101 | |
| 58 } // namespace | 102 } // namespace |
| 59 | 103 |
| 60 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatt eColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const | 104 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatt eColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const |
| 61 { | 105 { |
| 62 CPDF_DIBSource* pSource = new CPDF_DIBSource; | 106 CPDF_DIBSource* pSource = new CPDF_DIBSource; |
| 63 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteCo lor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { | 107 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteCo lor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { |
| 64 return pSource; | 108 return pSource; |
| 65 } | 109 } |
| 66 delete pSource; | 110 delete pSource; |
| 67 return NULL; | 111 return NULL; |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 return 0; | 666 return 0; |
| 623 } | 667 } |
| 624 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { | 668 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { |
| 625 return 0; | 669 return 0; |
| 626 } | 670 } |
| 627 return 1; | 671 return 1; |
| 628 } | 672 } |
| 629 void CPDF_DIBSource::LoadJpxBitmap() | 673 void CPDF_DIBSource::LoadJpxBitmap() |
| 630 { | 674 { |
| 631 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); | 675 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); |
| 632 if (pJpxModule == NULL) { | 676 if (!pJpxModule) |
| 633 return; | 677 return; |
| 634 } | 678 |
| 635 FX_LPVOID ctx = pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), m_pStream Acc->GetSize(), m_pColorSpace != NULL); | 679 nonstd::unique_ptr<JpxBitMapContext> context( |
| 636 if (ctx == NULL) { | 680 new JpxBitMapContext(pJpxModule)); |
| 681 context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), | |
| 682 m_pStreamAcc->GetSize(), | |
| 683 m_pColorSpace != nullptr)); | |
| 684 if (!context->context()) | |
| 637 return; | 685 return; |
| 638 } | 686 |
| 639 FX_DWORD width = 0, height = 0, codestream_nComps = 0, image_nComps = 0; | 687 FX_DWORD width = 0; |
| 640 pJpxModule->GetImageInfo(ctx, width, height, codestream_nComps, image_nComps ); | 688 FX_DWORD height = 0; |
| 641 if ((int)width < m_Width || (int)height < m_Height) { | 689 FX_DWORD codestream_nComps = 0; |
| 642 pJpxModule->DestroyDecoder(ctx); | 690 FX_DWORD image_nComps = 0; |
| 691 pJpxModule->GetImageInfo(context->context(), width, height, | |
| 692 codestream_nComps, image_nComps); | |
| 693 if ((int)width < m_Width || (int)height < m_Height) | |
| 643 return; | 694 return; |
| 644 } | 695 |
| 645 int output_nComps; | 696 int output_nComps; |
| 646 FX_BOOL bTranslateColor, bSwapRGB = FALSE; | 697 FX_BOOL bTranslateColor; |
| 698 FX_BOOL bSwapRGB = FALSE; | |
| 647 if (m_pColorSpace) { | 699 if (m_pColorSpace) { |
| 648 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) { | 700 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) |
| 649 return; | 701 return; |
| 650 } | |
| 651 output_nComps = codestream_nComps; | 702 output_nComps = codestream_nComps; |
| 652 bTranslateColor = FALSE; | 703 bTranslateColor = FALSE; |
| 653 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { | 704 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { |
| 654 bSwapRGB = TRUE; | 705 bSwapRGB = TRUE; |
| 655 m_pColorSpace = NULL; | 706 m_pColorSpace = nullptr; |
| 656 } | 707 } |
| 657 } else { | 708 } else { |
| 658 bTranslateColor = TRUE; | 709 bTranslateColor = TRUE; |
| 659 if (image_nComps) { | 710 if (image_nComps) { |
| 660 output_nComps = image_nComps; | 711 output_nComps = image_nComps; |
| 661 } else { | 712 } else { |
| 662 output_nComps = codestream_nComps; | 713 output_nComps = codestream_nComps; |
| 663 } | 714 } |
| 664 if (output_nComps == 3) { | 715 if (output_nComps == 3) { |
| 665 bSwapRGB = TRUE; | 716 bSwapRGB = TRUE; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 676 format = FXDIB_Rgb; | 727 format = FXDIB_Rgb; |
| 677 } else if (output_nComps == 4) { | 728 } else if (output_nComps == 4) { |
| 678 format = FXDIB_Rgb32; | 729 format = FXDIB_Rgb32; |
| 679 } else { | 730 } else { |
| 680 width = (width * output_nComps + 2) / 3; | 731 width = (width * output_nComps + 2) / 3; |
| 681 format = FXDIB_Rgb; | 732 format = FXDIB_Rgb; |
| 682 } | 733 } |
| 683 m_pCachedBitmap = new CFX_DIBitmap; | 734 m_pCachedBitmap = new CFX_DIBitmap; |
| 684 if (!m_pCachedBitmap->Create(width, height, format)) { | 735 if (!m_pCachedBitmap->Create(width, height, format)) { |
| 685 delete m_pCachedBitmap; | 736 delete m_pCachedBitmap; |
| 686 m_pCachedBitmap = NULL; | 737 m_pCachedBitmap = nullptr; |
| 687 return; | 738 return; |
| 688 } | 739 } |
| 689 m_pCachedBitmap->Clear(0xFFFFFFFF); | 740 m_pCachedBitmap->Clear(0xFFFFFFFF); |
| 690 FX_LPBYTE output_offsets = FX_Alloc(FX_BYTE, output_nComps); | 741 context->set_output_offsets(FX_Alloc(FX_BYTE, output_nComps)); |
| 691 for (int i = 0; i < output_nComps; i ++) { | 742 for (int i = 0; i < output_nComps; ++i) |
| 692 output_offsets[i] = i; | 743 context->output_offsets()[i] = i; |
| 744 if (bSwapRGB) { | |
| 745 context->output_offsets()[0] = 2; | |
| 746 context->output_offsets()[2] = 0; | |
| 693 } | 747 } |
| 694 if (bSwapRGB) { | 748 if (!pJpxModule->Decode(context->context(), |
| 695 output_offsets[0] = 2; | 749 m_pCachedBitmap->GetBuffer(), |
| 696 output_offsets[2] = 0; | 750 m_pCachedBitmap->GetPitch(), |
| 697 } | 751 bTranslateColor, |
| 698 if (!pJpxModule->Decode(ctx, m_pCachedBitmap->GetBuffer(), m_pCachedBitmap-> GetPitch(), bTranslateColor, output_offsets)) { | 752 context->output_offsets())) { |
| 699 delete m_pCachedBitmap; | 753 delete m_pCachedBitmap; |
|
Tom Sepez
2015/06/06 19:05:04
nit: can m_pCachedBitmap be a unique_ptr?
Lei Zhang
2015/06/08 19:35:20
Done.
| |
| 700 m_pCachedBitmap = NULL; | 754 m_pCachedBitmap = nullptr; |
| 701 return; | 755 return; |
|
Tom Sepez
2015/06/06 19:05:04
Nit: presumably this is the return that leaks, rig
Lei Zhang
2015/06/08 19:35:20
The failures are on line 700 above. "if (codestrea
| |
| 702 } | 756 } |
| 703 FX_Free(output_offsets); | 757 if (m_pColorSpace && |
| 704 pJpxModule->DestroyDecoder(ctx); | 758 m_pColorSpace->GetFamily() == PDFCS_INDEXED && |
| 705 if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && m_bpc < 8) { | 759 m_bpc < 8) { |
| 706 int scale = 8 - m_bpc; | 760 int scale = 8 - m_bpc; |
| 707 for (FX_DWORD row = 0; row < height; row ++) { | 761 for (FX_DWORD row = 0; row < height; ++row) { |
| 708 FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row); | 762 FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row); |
| 709 for (FX_DWORD col = 0; col < width; col ++) { | 763 for (FX_DWORD col = 0; col < width; ++col) { |
| 710 *scanline = (*scanline) >> scale; | 764 *scanline = (*scanline) >> scale; |
| 711 scanline++; | 765 ++scanline; |
| 712 } | 766 } |
| 713 } | 767 } |
| 714 } | 768 } |
| 715 m_bpc = 8; | 769 m_bpc = 8; |
| 716 } | 770 } |
| 717 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) | 771 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) |
| 718 { | 772 { |
| 719 MatteColor = 0xffffffff; | 773 MatteColor = 0xffffffff; |
| 720 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); | 774 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); |
| 721 if (pSoftMask) { | 775 if (pSoftMask) { |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1504 { | 1558 { |
| 1505 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); | 1559 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); |
| 1506 } | 1560 } |
| 1507 CPDF_ImageLoader::~CPDF_ImageLoader() | 1561 CPDF_ImageLoader::~CPDF_ImageLoader() |
| 1508 { | 1562 { |
| 1509 if (!m_bCached) { | 1563 if (!m_bCached) { |
| 1510 delete m_pBitmap; | 1564 delete m_pBitmap; |
| 1511 delete m_pMask; | 1565 delete m_pMask; |
| 1512 } | 1566 } |
| 1513 } | 1567 } |
| OLD | NEW |