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 |