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 <limits> |
| 8 |
7 #include "core/fxcodec/codec/codec_int.h" | 9 #include "core/fxcodec/codec/codec_int.h" |
8 #include "core/fxcodec/fx_codec.h" | 10 #include "core/fxcodec/fx_codec.h" |
| 11 #include "core/fxcrt/fx_safe_types.h" |
9 #include "core/fxge/fx_dib.h" | 12 #include "core/fxge/fx_dib.h" |
10 | 13 |
11 extern "C" { | 14 extern "C" { |
12 #include "third_party/libtiff/tiffiop.h" | 15 #include "third_party/libtiff/tiffiop.h" |
13 } | 16 } |
14 | 17 |
15 class CCodec_TiffContext { | 18 class CCodec_TiffContext { |
16 public: | 19 public: |
17 CCodec_TiffContext(); | 20 CCodec_TiffContext(); |
18 ~CCodec_TiffContext(); | 21 ~CCodec_TiffContext(); |
19 | 22 |
20 bool InitDecoder(IFX_SeekableReadStream* file_ptr); | 23 bool InitDecoder(IFX_SeekableReadStream* file_ptr); |
21 bool LoadFrameInfo(int32_t frame, | 24 bool LoadFrameInfo(int32_t frame, |
22 int32_t* width, | 25 int32_t* width, |
23 int32_t* height, | 26 int32_t* height, |
24 int32_t* comps, | 27 int32_t* comps, |
25 int32_t* bpc, | 28 int32_t* bpc, |
26 CFX_DIBAttribute* pAttribute); | 29 CFX_DIBAttribute* pAttribute); |
27 bool Decode(CFX_DIBitmap* pDIBitmap); | 30 bool Decode(CFX_DIBitmap* pDIBitmap); |
28 | 31 |
29 IFX_SeekableReadStream* io_in() const { return m_io_in; } | 32 IFX_SeekableReadStream* io_in() const { return m_io_in; } |
30 uint32_t offset() const { return m_offset; } | 33 uint32_t offset() const { return m_offset; } |
31 void set_offset(uint32_t offset) { m_offset = offset; } | 34 void set_offset(uint32_t offset) { m_offset = offset; } |
32 void increment_offset(uint32_t offset) { m_offset += offset; } | |
33 | 35 |
34 private: | 36 private: |
35 bool IsSupport(const CFX_DIBitmap* pDIBitmap) const; | 37 bool IsSupport(const CFX_DIBitmap* pDIBitmap) const; |
36 void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); | 38 void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); |
37 bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap, | 39 bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap, |
38 int32_t height, | 40 int32_t height, |
39 int32_t width, | 41 int32_t width, |
40 uint16_t bps, | 42 uint16_t bps, |
41 uint16_t spp); | 43 uint16_t spp); |
42 bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap, | 44 bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 int _TIFFIfMultiplicationOverflow(tmsize_t op1, tmsize_t op2) { | 84 int _TIFFIfMultiplicationOverflow(tmsize_t op1, tmsize_t op2) { |
83 return op1 > std::numeric_limits<tmsize_t>::max() / op2; | 85 return op1 > std::numeric_limits<tmsize_t>::max() / op2; |
84 } | 86 } |
85 | 87 |
86 TIFFErrorHandler _TIFFwarningHandler = nullptr; | 88 TIFFErrorHandler _TIFFwarningHandler = nullptr; |
87 TIFFErrorHandler _TIFFerrorHandler = nullptr; | 89 TIFFErrorHandler _TIFFerrorHandler = nullptr; |
88 | 90 |
89 namespace { | 91 namespace { |
90 | 92 |
91 tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) { | 93 tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) { |
92 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; | 94 CCodec_TiffContext* pTiffContext = |
| 95 reinterpret_cast<CCodec_TiffContext*>(context); |
| 96 FX_SAFE_UINT32 increment = pTiffContext->offset(); |
| 97 increment += length; |
| 98 if (!increment.IsValid()) |
| 99 return 0; |
| 100 |
93 if (!pTiffContext->io_in()->ReadBlock(buf, pTiffContext->offset(), length)) | 101 if (!pTiffContext->io_in()->ReadBlock(buf, pTiffContext->offset(), length)) |
94 return 0; | 102 return 0; |
95 | 103 |
96 pTiffContext->increment_offset(length); | 104 pTiffContext->set_offset(increment.ValueOrDie()); |
97 return length; | 105 return length; |
98 } | 106 } |
99 | 107 |
100 tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) { | 108 tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) { |
101 ASSERT(false); | 109 ASSERT(false); |
102 return 0; | 110 return 0; |
103 } | 111 } |
104 | 112 |
105 toff_t tiff_seek(thandle_t context, toff_t offset, int whence) { | 113 toff_t tiff_seek(thandle_t context, toff_t offset, int whence) { |
106 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; | 114 CCodec_TiffContext* pTiffContext = |
| 115 reinterpret_cast<CCodec_TiffContext*>(context); |
| 116 FX_SAFE_FILESIZE safe_offset = offset; |
| 117 if (!safe_offset.IsValid()) |
| 118 return static_cast<toff_t>(-1); |
| 119 FX_FILESIZE file_offset = safe_offset.ValueOrDie(); |
| 120 |
107 switch (whence) { | 121 switch (whence) { |
108 case 0: | 122 case 0: { |
109 pTiffContext->set_offset(offset); | 123 if (file_offset > pTiffContext->io_in()->GetSize()) |
110 break; | |
111 case 1: | |
112 pTiffContext->increment_offset(offset); | |
113 break; | |
114 case 2: | |
115 if (pTiffContext->io_in()->GetSize() < (FX_FILESIZE)offset) | |
116 return static_cast<toff_t>(-1); | 124 return static_cast<toff_t>(-1); |
117 pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - offset); | 125 pTiffContext->set_offset(file_offset); |
118 break; | 126 return pTiffContext->offset(); |
| 127 } |
| 128 case 1: { |
| 129 FX_SAFE_UINT32 new_increment = pTiffContext->offset(); |
| 130 new_increment += file_offset; |
| 131 if (!new_increment.IsValid()) |
| 132 return static_cast<toff_t>(-1); |
| 133 pTiffContext->set_offset(new_increment.ValueOrDie()); |
| 134 return pTiffContext->offset(); |
| 135 } |
| 136 case 2: { |
| 137 if (pTiffContext->io_in()->GetSize() < file_offset) |
| 138 return static_cast<toff_t>(-1); |
| 139 pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - file_offset); |
| 140 return pTiffContext->offset(); |
| 141 } |
119 default: | 142 default: |
120 return static_cast<toff_t>(-1); | 143 return static_cast<toff_t>(-1); |
121 } | 144 } |
122 ASSERT(pTiffContext->offset() <= (uint32_t)pTiffContext->io_in()->GetSize()); | |
123 return pTiffContext->offset(); | |
124 } | 145 } |
125 | 146 |
126 int tiff_close(thandle_t context) { | 147 int tiff_close(thandle_t context) { |
127 return 0; | 148 return 0; |
128 } | 149 } |
129 | 150 |
130 toff_t tiff_get_size(thandle_t context) { | 151 toff_t tiff_get_size(thandle_t context) { |
131 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; | 152 CCodec_TiffContext* pTiffContext = |
132 return (toff_t)pTiffContext->io_in()->GetSize(); | 153 reinterpret_cast<CCodec_TiffContext*>(context); |
| 154 return static_cast<toff_t>(pTiffContext->io_in()->GetSize()); |
133 } | 155 } |
134 | 156 |
135 int tiff_map(thandle_t context, tdata_t*, toff_t*) { | 157 int tiff_map(thandle_t context, tdata_t*, toff_t*) { |
136 return 0; | 158 return 0; |
137 } | 159 } |
138 | 160 |
139 void tiff_unmap(thandle_t context, tdata_t, toff_t) {} | 161 void tiff_unmap(thandle_t context, tdata_t, toff_t) {} |
140 | 162 |
141 TIFF* tiff_open(void* context, const char* mode) { | 163 TIFF* tiff_open(void* context, const char* mode) { |
142 TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read, | 164 TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read, |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 } | 478 } |
457 | 479 |
458 bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx, | 480 bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx, |
459 class CFX_DIBitmap* pDIBitmap) { | 481 class CFX_DIBitmap* pDIBitmap) { |
460 return ctx->Decode(pDIBitmap); | 482 return ctx->Decode(pDIBitmap); |
461 } | 483 } |
462 | 484 |
463 void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) { | 485 void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) { |
464 delete ctx; | 486 delete ctx; |
465 } | 487 } |
OLD | NEW |