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

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

Powered by Google App Engine
This is Rietveld 408576698