Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Side by Side Diff: core/fxcodec/codec/fx_codec_tiff.cpp

Issue 2053573003: Clean up fx_codec_tiff.cpp. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: address comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "core/fxcodec/codec/codec_int.h" 7 #include "core/fxcodec/codec/codec_int.h"
8 #include "core/fxcodec/include/fx_codec.h" 8 #include "core/fxcodec/include/fx_codec.h"
9 #include "core/fxge/include/fx_dib.h" 9 #include "core/fxge/include/fx_dib.h"
10 10
11 extern "C" { 11 extern "C" {
12 #include "third_party/libtiff/tiffiop.h" 12 #include "third_party/libtiff/tiffiop.h"
13 } 13 }
14 14
15 void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData,
16 unsigned int dwProfileSize,
17 int nComponents,
18 int intent,
19 uint32_t dwSrcFormat = Icc_FORMAT_DEFAULT);
20 void IccLib_TranslateImage(void* pTransform,
21 unsigned char* pDest,
22 const unsigned char* pSrc,
23 int pixels);
24 void IccLib_DestroyTransform(void* pTransform);
25 class CCodec_TiffContext { 15 class CCodec_TiffContext {
26 public: 16 public:
27 CCodec_TiffContext(); 17 CCodec_TiffContext();
28 ~CCodec_TiffContext(); 18 ~CCodec_TiffContext();
29 19
30 FX_BOOL InitDecoder(IFX_FileRead* file_ptr); 20 bool InitDecoder(IFX_FileRead* file_ptr);
31 void GetFrames(int32_t& frames); 21 bool LoadFrameInfo(int32_t frame,
32 FX_BOOL LoadFrameInfo(int32_t frame, 22 int32_t* width,
33 uint32_t& width, 23 int32_t* height,
34 uint32_t& height, 24 int32_t* comps,
35 uint32_t& comps, 25 int32_t* bpc,
36 uint32_t& bpc, 26 CFX_DIBAttribute* pAttribute);
37 CFX_DIBAttribute* pAttribute); 27 bool Decode(CFX_DIBitmap* pDIBitmap);
38 FX_BOOL Decode(CFX_DIBitmap* pDIBitmap);
39 28
40 union { 29 IFX_FileRead* io_in() const { return m_io_in; }
41 IFX_FileRead* in; 30 uint32_t offset() const { return m_offset; }
42 IFX_FileStream* out; 31 void set_offset(uint32_t offset) { m_offset = offset; }
43 } io; 32 void increment_offset(uint32_t offset) { m_offset += offset; }
44
45 uint32_t offset;
46
47 TIFF* tif_ctx;
48 void* icc_ctx;
49 int32_t frame_num;
50 int32_t frame_cur;
51 FX_BOOL isDecoder;
52 33
53 private: 34 private:
54 FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap); 35 bool IsSupport(const CFX_DIBitmap* pDIBitmap) const;
55 void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); 36 void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps);
56 FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap, 37 bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
57 int32_t height, 38 int32_t height,
58 int32_t width, 39 int32_t width,
59 uint16_t bps, 40 uint16_t bps,
60 uint16_t spp); 41 uint16_t spp);
61 FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap, 42 bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
62 int32_t height, 43 int32_t height,
63 int32_t width, 44 int32_t width,
64 uint16_t bps, 45 uint16_t bps,
65 uint16_t spp); 46 uint16_t spp);
66 FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap, 47 bool Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
67 int32_t height, 48 int32_t height,
68 int32_t width, 49 int32_t width,
69 uint16_t bps, 50 uint16_t bps,
70 uint16_t spp); 51 uint16_t spp);
52
53 IFX_FileRead* m_io_in;
54 uint32_t m_offset;
55 TIFF* m_tif_ctx;
71 }; 56 };
72 CCodec_TiffContext::CCodec_TiffContext() { 57
73 offset = 0;
74 frame_num = 0;
75 frame_cur = 0;
76 io.in = nullptr;
77 tif_ctx = nullptr;
78 icc_ctx = nullptr;
79 isDecoder = TRUE;
80 }
81 CCodec_TiffContext::~CCodec_TiffContext() {
82 if (icc_ctx) {
83 IccLib_DestroyTransform(icc_ctx);
84 icc_ctx = nullptr;
85 }
86 if (tif_ctx) {
87 TIFFClose(tif_ctx);
88 }
89 }
90 static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length) {
91 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
92 FX_BOOL ret = FALSE;
93 if (pTiffContext->isDecoder) {
94 ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length);
95 } else {
96 ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length);
97 }
98 if (!ret) {
99 return 0;
100 }
101 pTiffContext->offset += (uint32_t)length;
102 return length;
103 }
104 static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length) {
105 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
106 ASSERT(!pTiffContext->isDecoder);
107 if (!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) {
108 return 0;
109 }
110 pTiffContext->offset += (uint32_t)length;
111 return length;
112 }
113 static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence) {
114 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
115 switch (whence) {
116 case 0:
117 pTiffContext->offset = (uint32_t)offset;
118 break;
119 case 1:
120 pTiffContext->offset += (uint32_t)offset;
121 break;
122 case 2:
123 if (pTiffContext->isDecoder) {
124 if (pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) {
125 return static_cast<toff_t>(-1);
126 }
127 pTiffContext->offset =
128 (uint32_t)(pTiffContext->io.in->GetSize() - offset);
129 } else {
130 if (pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) {
131 return static_cast<toff_t>(-1);
132 }
133 pTiffContext->offset =
134 (uint32_t)(pTiffContext->io.out->GetSize() - offset);
135 }
136 break;
137 default:
138 return static_cast<toff_t>(-1);
139 }
140 ASSERT(pTiffContext->isDecoder ? (pTiffContext->offset <=
141 (uint32_t)pTiffContext->io.in->GetSize())
142 : TRUE);
143 return pTiffContext->offset;
144 }
145 static int _tiff_close(thandle_t context) {
146 return 0;
147 }
148 static toff_t _tiff_get_size(thandle_t context) {
149 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
150 return pTiffContext->isDecoder ? (toff_t)pTiffContext->io.in->GetSize()
151 : (toff_t)pTiffContext->io.out->GetSize();
152 }
153 static int _tiff_map(thandle_t context, tdata_t*, toff_t*) {
154 return 0;
155 }
156 static void _tiff_unmap(thandle_t context, tdata_t, toff_t) {}
157 TIFF* _tiff_open(void* context, const char* mode) {
158 TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, _tiff_read,
159 _tiff_write, _tiff_seek, _tiff_close,
160 _tiff_get_size, _tiff_map, _tiff_unmap);
161 if (tif) {
162 tif->tif_fd = (int)(intptr_t)context;
163 }
164 return tif;
165 }
166 void* _TIFFmalloc(tmsize_t size) { 58 void* _TIFFmalloc(tmsize_t size) {
167 return FXMEM_DefaultAlloc(size, 0); 59 return FXMEM_DefaultAlloc(size, 0);
168 } 60 }
61
169 void _TIFFfree(void* ptr) { 62 void _TIFFfree(void* ptr) {
170 FXMEM_DefaultFree(ptr, 0); 63 FXMEM_DefaultFree(ptr, 0);
171 } 64 }
65
172 void* _TIFFrealloc(void* ptr, tmsize_t size) { 66 void* _TIFFrealloc(void* ptr, tmsize_t size) {
173 return FXMEM_DefaultRealloc(ptr, size, 0); 67 return FXMEM_DefaultRealloc(ptr, size, 0);
174 } 68 }
69
175 void _TIFFmemset(void* ptr, int val, tmsize_t size) { 70 void _TIFFmemset(void* ptr, int val, tmsize_t size) {
176 FXSYS_memset(ptr, val, (size_t)size); 71 FXSYS_memset(ptr, val, (size_t)size);
177 } 72 }
73
178 void _TIFFmemcpy(void* des, const void* src, tmsize_t size) { 74 void _TIFFmemcpy(void* des, const void* src, tmsize_t size) {
179 FXSYS_memcpy(des, src, (size_t)size); 75 FXSYS_memcpy(des, src, (size_t)size);
180 } 76 }
77
181 int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) { 78 int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) {
182 return FXSYS_memcmp(ptr1, ptr2, (size_t)size); 79 return FXSYS_memcmp(ptr1, ptr2, (size_t)size);
183 } 80 }
184 81
185 TIFFErrorHandler _TIFFwarningHandler = nullptr; 82 TIFFErrorHandler _TIFFwarningHandler = nullptr;
186 TIFFErrorHandler _TIFFerrorHandler = nullptr; 83 TIFFErrorHandler _TIFFerrorHandler = nullptr;
187 84
188 int TIFFCmyk2Rgb(thandle_t context, 85 namespace {
189 uint8 c, 86
190 uint8 m, 87 tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) {
191 uint8 y, 88 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
192 uint8 k, 89 if (!pTiffContext->io_in()->ReadBlock(buf, pTiffContext->offset(), length))
193 uint8* r,
194 uint8* g,
195 uint8* b) {
196 if (!context)
197 return 0; 90 return 0;
198 91
199 CCodec_TiffContext* p = (CCodec_TiffContext*)context; 92 pTiffContext->increment_offset(length);
200 if (p->icc_ctx) { 93 return length;
201 unsigned char cmyk[4], bgr[3]; 94 }
202 cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k; 95
203 IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1); 96 tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) {
204 *r = bgr[2], *g = bgr[1], *b = bgr[0]; 97 ASSERT(false);
205 } else { 98 return 0;
206 AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b); 99 }
100
101 toff_t tiff_seek(thandle_t context, toff_t offset, int whence) {
102 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
103 switch (whence) {
104 case 0:
105 pTiffContext->set_offset(offset);
106 break;
107 case 1:
108 pTiffContext->increment_offset(offset);
109 break;
110 case 2:
111 if (pTiffContext->io_in()->GetSize() < (FX_FILESIZE)offset)
112 return static_cast<toff_t>(-1);
113 pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - offset);
114 break;
115 default:
116 return static_cast<toff_t>(-1);
207 } 117 }
208 return 1; 118 ASSERT(pTiffContext->offset() <= (uint32_t)pTiffContext->io_in()->GetSize());
119 return pTiffContext->offset();
209 } 120 }
210 FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) { 121
211 io.in = file_ptr; 122 int tiff_close(thandle_t context) {
212 return !!_tiff_open(this, "r"); 123 return 0;
213 } 124 }
214 void CCodec_TiffContext::GetFrames(int32_t& frames) { 125
215 frames = frame_num = TIFFNumberOfDirectories(tif_ctx); 126 toff_t tiff_get_size(thandle_t context) {
127 CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
128 return (toff_t)pTiffContext->io_in()->GetSize();
216 } 129 }
217 #define TIFF_EXIF_GETINFO(key, T, tag) \
218 { \
219 T val = (T)0; \
220 TIFFGetField(tif_ctx, tag, &val); \
221 if (val) { \
222 (key) = FX_Alloc(uint8_t, sizeof(T)); \
223 if ((key)) { \
224 T* ptr = (T*)(key); \
225 *ptr = val; \
226 pExif->m_TagVal.SetAt(tag, (key)); \
227 } \
228 } \
229 } \
230 (key) = nullptr;
231 #define TIFF_EXIF_GETSTRINGINFO(key, tag) \
232 { \
233 uint32_t size = 0; \
234 uint8_t* buf = nullptr; \
235 TIFFGetField(tif_ctx, tag, &size, &buf); \
236 if (size && buf) { \
237 (key) = FX_Alloc(uint8_t, size); \
238 if ((key)) { \
239 FXSYS_memcpy((key), buf, size); \
240 pExif->m_TagVal.SetAt(tag, (key)); \
241 } \
242 } \
243 } \
244 (key) = nullptr;
245 130
246 namespace { 131 int tiff_map(thandle_t context, tdata_t*, toff_t*) {
132 return 0;
133 }
134
135 void tiff_unmap(thandle_t context, tdata_t, toff_t) {}
136
137 TIFF* tiff_open(void* context, const char* mode) {
138 TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read,
139 tiff_write, tiff_seek, tiff_close, tiff_get_size,
140 tiff_map, tiff_unmap);
141 if (tif) {
142 tif->tif_fd = (int)(intptr_t)context;
143 }
144 return tif;
145 }
247 146
248 template <class T> 147 template <class T>
249 FX_BOOL Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) { 148 bool Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) {
250 T val = 0; 149 T val = 0;
251 TIFFGetField(tif_ctx, tag, &val); 150 TIFFGetField(tif_ctx, tag, &val);
252 if (!val) 151 if (!val)
253 return FALSE; 152 return false;
254 T* ptr = FX_Alloc(T, 1); 153 T* ptr = FX_Alloc(T, 1);
255 *ptr = val; 154 *ptr = val;
256 pAttr->m_Exif[tag] = (void*)ptr; 155 pAttr->m_Exif[tag] = (void*)ptr;
257 return TRUE; 156 return true;
258 } 157 }
158
259 void Tiff_Exif_GetStringInfo(TIFF* tif_ctx, 159 void Tiff_Exif_GetStringInfo(TIFF* tif_ctx,
260 ttag_t tag, 160 ttag_t tag,
261 CFX_DIBAttribute* pAttr) { 161 CFX_DIBAttribute* pAttr) {
262 FX_CHAR* buf = nullptr; 162 FX_CHAR* buf = nullptr;
263 TIFFGetField(tif_ctx, tag, &buf); 163 TIFFGetField(tif_ctx, tag, &buf);
264 if (!buf) 164 if (!buf)
265 return; 165 return;
266 FX_STRSIZE size = FXSYS_strlen(buf); 166 FX_STRSIZE size = FXSYS_strlen(buf);
267 uint8_t* ptr = FX_Alloc(uint8_t, size + 1); 167 uint8_t* ptr = FX_Alloc(uint8_t, size + 1);
268 FXSYS_memcpy(ptr, buf, size); 168 FXSYS_memcpy(ptr, buf, size);
269 ptr[size] = 0; 169 ptr[size] = 0;
270 pAttr->m_Exif[tag] = ptr; 170 pAttr->m_Exif[tag] = ptr;
271 } 171 }
272 172
273 } // namespace 173 void TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) {
274
275 FX_BOOL CCodec_TiffContext::LoadFrameInfo(int32_t frame,
276 uint32_t& width,
277 uint32_t& height,
278 uint32_t& comps,
279 uint32_t& bpc,
280 CFX_DIBAttribute* pAttribute) {
281 if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) {
282 return FALSE;
283 }
284 uint16_t tif_cs;
285 uint32_t tif_icc_size = 0;
286 uint8_t* tif_icc_buf = nullptr;
287 uint16_t tif_bpc = 0;
288 uint16_t tif_cps;
289 uint32_t tif_rps;
290 width = height = comps = 0;
291 TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
292 TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height);
293 TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps);
294 TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc);
295 TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs);
296 TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps);
297 TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps);
298 TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf);
299 if (pAttribute) {
300 pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH;
301 if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT,
302 &pAttribute->m_wDPIUnit)) {
303 pAttribute->m_wDPIUnit -= 1;
304 }
305 Tiff_Exif_GetInfo<uint16_t>(tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
306 if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) {
307 void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
308 FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
309 pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
310 }
311 if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) {
312 void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
313 FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
314 pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f);
315 }
316 Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute);
317 Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pAttribute);
318 Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pAttribute);
319 }
320 bpc = tif_bpc;
321 if (tif_rps > height) {
322 TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height);
323 }
324 return TRUE;
325 }
326 void _TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) {
327 for (int32_t n = 0; n < pixel; n++) { 174 for (int32_t n = 0; n < pixel; n++) {
328 uint8_t tmp = pBuf[0]; 175 uint8_t tmp = pBuf[0];
329 pBuf[0] = pBuf[2]; 176 pBuf[0] = pBuf[2];
330 pBuf[2] = tmp; 177 pBuf[2] = tmp;
331 pBuf += spp; 178 pBuf += spp;
332 } 179 }
333 } 180 }
334 FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap) { 181
335 if (TIFFIsTiled(tif_ctx)) { 182 } // namespace
336 return FALSE; 183
184 CCodec_TiffContext::CCodec_TiffContext()
185 : m_io_in(nullptr), m_offset(0), m_tif_ctx(nullptr) {}
186
187 CCodec_TiffContext::~CCodec_TiffContext() {
188 if (m_tif_ctx)
189 TIFFClose(m_tif_ctx);
190 }
191
192 bool CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) {
193 m_io_in = file_ptr;
194 m_tif_ctx = tiff_open(this, "r");
195 return !!m_tif_ctx;
196 }
197
198 bool CCodec_TiffContext::LoadFrameInfo(int32_t frame,
199 int32_t* width,
200 int32_t* height,
201 int32_t* comps,
202 int32_t* bpc,
203 CFX_DIBAttribute* pAttribute) {
204 if (!TIFFSetDirectory(m_tif_ctx, (uint16)frame))
205 return false;
206
207 uint32_t tif_width = 0;
208 uint32_t tif_height = 0;
209 uint16_t tif_comps = 0;
210 uint16_t tif_bpc = 0;
211 uint32_t tif_rps = 0;
212 TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &tif_width);
213 TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &tif_height);
214 TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &tif_comps);
215 TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc);
216 TIFFGetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps);
217
218 if (pAttribute) {
219 pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH;
220 if (TIFFGetField(m_tif_ctx, TIFFTAG_RESOLUTIONUNIT,
221 &pAttribute->m_wDPIUnit)) {
222 pAttribute->m_wDPIUnit--;
223 }
224 Tiff_Exif_GetInfo<uint16_t>(m_tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
225 if (Tiff_Exif_GetInfo<FX_FLOAT>(m_tif_ctx, TIFFTAG_XRESOLUTION,
226 pAttribute)) {
227 void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
228 FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
229 pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
230 }
231 if (Tiff_Exif_GetInfo<FX_FLOAT>(m_tif_ctx, TIFFTAG_YRESOLUTION,
232 pAttribute)) {
233 void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
234 FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
235 pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f);
236 }
237 Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute);
238 Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MAKE, pAttribute);
239 Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MODEL, pAttribute);
337 } 240 }
241 *width = pdfium::base::checked_cast<int32_t>(tif_width);
242 *height = pdfium::base::checked_cast<int32_t>(tif_height);
243 *comps = tif_comps;
244 *bpc = tif_bpc;
245 if (tif_rps > tif_height) {
246 tif_rps = tif_height;
247 TIFFSetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps);
248 }
249 return true;
250 }
251
252 bool CCodec_TiffContext::IsSupport(const CFX_DIBitmap* pDIBitmap) const {
253 if (TIFFIsTiled(m_tif_ctx))
254 return false;
255
338 uint16_t photometric; 256 uint16_t photometric;
339 if (!TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) { 257 if (!TIFFGetField(m_tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric))
340 return FALSE; 258 return false;
341 } 259
342 switch (pDIBitmap->GetBPP()) { 260 switch (pDIBitmap->GetBPP()) {
343 case 1: 261 case 1:
344 case 8: 262 case 8:
345 if (photometric != PHOTOMETRIC_PALETTE) { 263 if (photometric != PHOTOMETRIC_PALETTE) {
346 return FALSE; 264 return false;
347 } 265 }
348 break; 266 break;
349 case 24: 267 case 24:
350 if (photometric != PHOTOMETRIC_RGB) { 268 if (photometric != PHOTOMETRIC_RGB) {
351 return FALSE; 269 return false;
352 } 270 }
353 break; 271 break;
354 default: 272 default:
355 return FALSE; 273 return false;
356 } 274 }
357 uint16_t planarconfig; 275 uint16_t planarconfig;
358 if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) { 276 if (!TIFFGetFieldDefaulted(m_tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig))
359 return FALSE; 277 return false;
360 } 278
361 if (planarconfig == PLANARCONFIG_SEPARATE) { 279 return planarconfig != PLANARCONFIG_SEPARATE;
362 return FALSE;
363 }
364 return TRUE;
365 } 280 }
281
366 void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { 282 void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) {
367 uint16_t *red_orig, *green_orig, *blue_orig; 283 uint16_t* red_orig;
368 TIFFGetField(tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig); 284 uint16_t* green_orig;
285 uint16_t* blue_orig;
286 TIFFGetField(m_tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig);
369 for (int32_t i = (1L << bps) - 1; i >= 0; i--) { 287 for (int32_t i = (1L << bps) - 1; i >= 0; i--) {
370 #define CVT(x) ((uint16_t)((x) >> 8)) 288 #define CVT(x) ((uint16_t)((x) >> 8))
371 red_orig[i] = CVT(red_orig[i]); 289 red_orig[i] = CVT(red_orig[i]);
372 green_orig[i] = CVT(green_orig[i]); 290 green_orig[i] = CVT(green_orig[i]);
373 blue_orig[i] = CVT(blue_orig[i]); 291 blue_orig[i] = CVT(blue_orig[i]);
374 #undef CVT 292 #undef CVT
375 } 293 }
376 int32_t len = 1 << bps; 294 int32_t len = 1 << bps;
377 for (int32_t index = 0; index < len; index++) { 295 for (int32_t index = 0; index < len; index++) {
378 uint32_t r = red_orig[index] & 0xFF; 296 uint32_t r = red_orig[index] & 0xFF;
379 uint32_t g = green_orig[index] & 0xFF; 297 uint32_t g = green_orig[index] & 0xFF;
380 uint32_t b = blue_orig[index] & 0xFF; 298 uint32_t b = blue_orig[index] & 0xFF;
381 uint32_t color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | 299 uint32_t color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) |
382 (((uint32)0xffL) << 24); 300 (((uint32)0xffL) << 24);
383 pDIBitmap->SetPaletteEntry(index, color); 301 pDIBitmap->SetPaletteEntry(index, color);
384 } 302 }
385 } 303 }
386 FX_BOOL CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap, 304
387 int32_t height, 305 bool CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
388 int32_t width, 306 int32_t height,
389 uint16_t bps, 307 int32_t width,
390 uint16_t spp) { 308 uint16_t bps,
309 uint16_t spp) {
391 if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 || 310 if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 ||
392 !isSupport(pDIBitmap)) { 311 !IsSupport(pDIBitmap)) {
393 return FALSE; 312 return false;
394 } 313 }
395 SetPalette(pDIBitmap, bps); 314 SetPalette(pDIBitmap, bps);
396 int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); 315 int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
397 uint8_t* buf = (uint8_t*)_TIFFmalloc(size); 316 uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
398 if (!buf) { 317 if (!buf) {
399 TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); 318 TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
400 return FALSE; 319 return false;
401 } 320 }
402 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); 321 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
403 uint32_t pitch = pDIBitmap->GetPitch(); 322 uint32_t pitch = pDIBitmap->GetPitch();
404 for (int32_t row = 0; row < height; row++) { 323 for (int32_t row = 0; row < height; row++) {
405 TIFFReadScanline(tif_ctx, buf, row, 0); 324 TIFFReadScanline(m_tif_ctx, buf, row, 0);
406 for (int32_t j = 0; j < size; j++) { 325 for (int32_t j = 0; j < size; j++) {
407 bitMapbuffer[row * pitch + j] = buf[j]; 326 bitMapbuffer[row * pitch + j] = buf[j];
408 } 327 }
409 } 328 }
410 _TIFFfree(buf); 329 _TIFFfree(buf);
411 return TRUE; 330 return true;
412 } 331 }
413 FX_BOOL CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap, 332
414 int32_t height, 333 bool CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
415 int32_t width, 334 int32_t height,
416 uint16_t bps, 335 int32_t width,
417 uint16_t spp) { 336 uint16_t bps,
337 uint16_t spp) {
418 if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) || 338 if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) ||
419 !isSupport(pDIBitmap)) { 339 !IsSupport(pDIBitmap)) {
420 return FALSE; 340 return false;
421 } 341 }
422 SetPalette(pDIBitmap, bps); 342 SetPalette(pDIBitmap, bps);
423 int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); 343 int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
424 uint8_t* buf = (uint8_t*)_TIFFmalloc(size); 344 uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
425 if (!buf) { 345 if (!buf) {
426 TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); 346 TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
427 return FALSE; 347 return false;
428 } 348 }
429 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); 349 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
430 uint32_t pitch = pDIBitmap->GetPitch(); 350 uint32_t pitch = pDIBitmap->GetPitch();
431 for (int32_t row = 0; row < height; row++) { 351 for (int32_t row = 0; row < height; row++) {
432 TIFFReadScanline(tif_ctx, buf, row, 0); 352 TIFFReadScanline(m_tif_ctx, buf, row, 0);
433 for (int32_t j = 0; j < size; j++) { 353 for (int32_t j = 0; j < size; j++) {
434 switch (bps) { 354 switch (bps) {
435 case 4: 355 case 4:
436 bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4; 356 bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4;
437 bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0; 357 bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0;
438 break; 358 break;
439 case 8: 359 case 8:
440 bitMapbuffer[row * pitch + j] = buf[j]; 360 bitMapbuffer[row * pitch + j] = buf[j];
441 break; 361 break;
442 } 362 }
443 } 363 }
444 } 364 }
445 _TIFFfree(buf); 365 _TIFFfree(buf);
446 return TRUE; 366 return true;
447 } 367 }
448 FX_BOOL CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap, 368
449 int32_t height, 369 bool CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
450 int32_t width, 370 int32_t height,
451 uint16_t bps, 371 int32_t width,
452 uint16_t spp) { 372 uint16_t bps,
453 if (pDIBitmap->GetBPP() != 24 || !isSupport(pDIBitmap)) { 373 uint16_t spp) {
454 return FALSE; 374 if (pDIBitmap->GetBPP() != 24 || !IsSupport(pDIBitmap))
455 } 375 return false;
456 int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); 376
377 int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
457 uint8_t* buf = (uint8_t*)_TIFFmalloc(size); 378 uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
458 if (!buf) { 379 if (!buf) {
459 TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); 380 TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
460 return FALSE; 381 return false;
461 } 382 }
462 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); 383 uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
463 uint32_t pitch = pDIBitmap->GetPitch(); 384 uint32_t pitch = pDIBitmap->GetPitch();
464 for (int32_t row = 0; row < height; row++) { 385 for (int32_t row = 0; row < height; row++) {
465 TIFFReadScanline(tif_ctx, buf, row, 0); 386 TIFFReadScanline(m_tif_ctx, buf, row, 0);
466 for (int32_t j = 0; j < size - 2; j += 3) { 387 for (int32_t j = 0; j < size - 2; j += 3) {
467 bitMapbuffer[row * pitch + j + 0] = buf[j + 2]; 388 bitMapbuffer[row * pitch + j + 0] = buf[j + 2];
468 bitMapbuffer[row * pitch + j + 1] = buf[j + 1]; 389 bitMapbuffer[row * pitch + j + 1] = buf[j + 1];
469 bitMapbuffer[row * pitch + j + 2] = buf[j + 0]; 390 bitMapbuffer[row * pitch + j + 2] = buf[j + 0];
470 } 391 }
471 } 392 }
472 _TIFFfree(buf); 393 _TIFFfree(buf);
473 return TRUE; 394 return true;
474 } 395 }
475 FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { 396
397 bool CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) {
476 uint32_t img_wid = pDIBitmap->GetWidth(); 398 uint32_t img_wid = pDIBitmap->GetWidth();
477 uint32_t img_hei = pDIBitmap->GetHeight(); 399 uint32_t img_hei = pDIBitmap->GetHeight();
478 uint32_t width = 0; 400 uint32_t width = 0;
479 uint32_t height = 0; 401 uint32_t height = 0;
480 TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); 402 TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
481 TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); 403 TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &height);
482 if (img_wid != width || img_hei != height) { 404 if (img_wid != width || img_hei != height)
483 return FALSE; 405 return false;
484 } 406
485 if (pDIBitmap->GetBPP() == 32) { 407 if (pDIBitmap->GetBPP() == 32) {
486 uint16_t rotation = ORIENTATION_TOPLEFT; 408 uint16_t rotation = ORIENTATION_TOPLEFT;
487 TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation); 409 TIFFGetField(m_tif_ctx, TIFFTAG_ORIENTATION, &rotation);
488 if (TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei, 410 if (TIFFReadRGBAImageOriented(m_tif_ctx, img_wid, img_hei,
489 (uint32*)pDIBitmap->GetBuffer(), rotation, 411 (uint32*)pDIBitmap->GetBuffer(), rotation,
490 1)) { 412 1)) {
491 for (uint32_t row = 0; row < img_hei; row++) { 413 for (uint32_t row = 0; row < img_hei; row++) {
492 uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row); 414 uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row);
493 _TiffBGRA2RGBA(row_buf, img_wid, 4); 415 TiffBGRA2RGBA(row_buf, img_wid, 4);
494 } 416 }
495 return TRUE; 417 return true;
496 } 418 }
497 } 419 }
498 uint16_t spp, bps; 420 uint16_t spp;
499 TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); 421 uint16_t bps;
500 TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); 422 TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp);
423 TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps);
501 uint32_t bpp = bps * spp; 424 uint32_t bpp = bps * spp;
502 if (bpp == 1) { 425 if (bpp == 1)
503 return Decode1bppRGB(pDIBitmap, height, width, bps, spp); 426 return Decode1bppRGB(pDIBitmap, height, width, bps, spp);
504 } else if (bpp <= 8) { 427 if (bpp <= 8)
505 return Decode8bppRGB(pDIBitmap, height, width, bps, spp); 428 return Decode8bppRGB(pDIBitmap, height, width, bps, spp);
506 } else if (bpp <= 24) { 429 if (bpp <= 24)
507 return Decode24bppRGB(pDIBitmap, height, width, bps, spp); 430 return Decode24bppRGB(pDIBitmap, height, width, bps, spp);
508 } 431 return false;
509 return FALSE;
510 } 432 }
511 433
512 CCodec_TiffContext* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) { 434 CCodec_TiffContext* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) {
513 CCodec_TiffContext* pDecoder = new CCodec_TiffContext; 435 CCodec_TiffContext* pDecoder = new CCodec_TiffContext;
514 if (!pDecoder->InitDecoder(file_ptr)) { 436 if (!pDecoder->InitDecoder(file_ptr)) {
515 delete pDecoder; 437 delete pDecoder;
516 return nullptr; 438 return nullptr;
517 } 439 }
518 return pDecoder; 440 return pDecoder;
519 } 441 }
520 442
521 void CCodec_TiffModule::GetFrames(CCodec_TiffContext* ctx, int32_t& frames) { 443 bool CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx,
522 ctx->GetFrames(frames); 444 int32_t frame,
523 } 445 int32_t* width,
524 446 int32_t* height,
525 FX_BOOL CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx, 447 int32_t* comps,
526 int32_t frame, 448 int32_t* bpc,
527 uint32_t& width, 449 CFX_DIBAttribute* pAttribute) {
528 uint32_t& height,
529 uint32_t& comps,
530 uint32_t& bpc,
531 CFX_DIBAttribute* pAttribute) {
532 return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); 450 return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute);
533 } 451 }
534 452
535 FX_BOOL CCodec_TiffModule::Decode(CCodec_TiffContext* ctx, 453 bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx,
536 class CFX_DIBitmap* pDIBitmap) { 454 class CFX_DIBitmap* pDIBitmap) {
537 return ctx->Decode(pDIBitmap); 455 return ctx->Decode(pDIBitmap);
538 } 456 }
539 457
540 void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) { 458 void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) {
541 delete ctx; 459 delete ctx;
542 } 460 }
OLDNEW
« no previous file with comments | « core/fxcodec/codec/fx_codec_progress.cpp ('k') | core/fxcodec/codec/include/ccodec_progressivedecoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698