]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/imagtiff.cpp
some != NULL checks
[wxWidgets.git] / src / common / imagtiff.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: imagtiff.cpp
3// Purpose: wxImage TIFF handler
4// Author: Robert Roebling
5// RCS-ID: $Id$
6// Copyright: (c) Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "imagtiff.h"
12#endif
13
14// For compilers that support precompilation, includes "wx.h".
15#include "wx/wxprec.h"
16
17#ifdef __BORLANDC__
18#pragma hdrstop
19#endif
20
21#include "wx/defs.h"
22
23#if wxUSE_LIBTIFF
24
25#include "wx/imagtiff.h"
26#include "wx/bitmap.h"
27#include "wx/debug.h"
28#include "wx/log.h"
29#include "wx/app.h"
30extern "C"
31{
32 #include "tiff.h"
33 #include "tiffio.h"
34}
35#include "wx/filefn.h"
36#include "wx/wfstream.h"
37#include "wx/intl.h"
38#include "wx/module.h"
39
40//-----------------------------------------------------------------------------
41// wxTIFFHandler
42//-----------------------------------------------------------------------------
43
44IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler,wxImageHandler)
45
46static tsize_t
47_tiffReadProc(thandle_t handle, tdata_t buf, tsize_t size)
48{
49 wxInputStream *stream = (wxInputStream*) handle;
50 stream->Read( (void*) buf, (size_t) size );
51 return stream->LastRead();
52}
53
54static tsize_t
55_tiffWriteProc(thandle_t handle, tdata_t buf, tsize_t size)
56{
57 wxOutputStream *stream = (wxOutputStream*) handle;
58 stream->Write( (void*) buf, (size_t) size );
59 return stream->LastWrite();
60}
61
62static toff_t
63_tiffSeekProc(thandle_t handle, toff_t off, int whence)
64{
65 wxInputStream *stream = (wxInputStream*) handle;
66 wxSeekMode mode;
67 switch (whence)
68 {
69 case SEEK_SET: mode = wxFromStart; break;
70 case SEEK_CUR: mode = wxFromCurrent; break;
71 case SEEK_END: mode = wxFromEnd; break;
72 default: mode = wxFromCurrent; break;
73 }
74
75 return (toff_t)stream->SeekI( (off_t)off, mode );
76}
77
78static int
79_tiffCloseProc(thandle_t WXUNUSED(handle))
80{
81 return 0; // ?
82}
83
84static toff_t
85_tiffSizeProc(thandle_t handle)
86{
87 wxInputStream *stream = (wxInputStream*) handle;
88 return (toff_t) stream->GetSize();
89}
90
91static int
92_tiffMapProc(thandle_t WXUNUSED(handle),
93 tdata_t* WXUNUSED(pbase),
94 toff_t* WXUNUSED(psize))
95{
96 return 0;
97}
98
99static void
100_tiffUnmapProc(thandle_t WXUNUSED(handle),
101 tdata_t WXUNUSED(base),
102 toff_t WXUNUSED(size))
103{
104}
105
106TIFF*
107TIFFwxOpen(wxInputStream &stream, const char* name, const char* mode)
108{
109 TIFF* tif = TIFFClientOpen(name, mode,
110 (thandle_t) &stream,
111 _tiffReadProc, _tiffWriteProc,
112 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
113 _tiffMapProc, _tiffUnmapProc);
114
115 return tif;
116}
117
118
119bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int index )
120{
121 image->Destroy();
122
123 TIFF *tif = TIFFwxOpen( stream, "image", "r" );
124
125 if (!tif)
126 {
127 if (verbose)
128 wxLogError( _("TIFF: Error loading image.") );
129
130 return FALSE;
131 }
132
133 if (!TIFFSetDirectory( tif, (tdir_t)index ))
134 {
135 if (verbose)
136 wxLogError( _("Invalid TIFF image index.") );
137
138 TIFFClose( tif );
139
140 return FALSE;
141 }
142
143 uint32 w, h;
144 uint32 npixels;
145 uint32 *raster;
146
147 TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &w );
148 TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &h );
149
150 npixels = w * h;
151
152 raster = (uint32*) _TIFFmalloc( npixels * sizeof(uint32) );
153
154 if (!raster)
155 {
156 if (verbose)
157 wxLogError( _("TIFF: Couldn't allocate memory.") );
158
159 return FALSE;
160 }
161
162 image->Create( (int)w, (int)h );
163 if (!image->Ok())
164 {
165 if (verbose)
166 wxLogError( _("TIFF: Couldn't allocate memory.") );
167
168 _TIFFfree( raster );
169
170 return FALSE;
171 }
172
173 if (!TIFFReadRGBAImage( tif, w, h, raster, 0 ))
174 {
175 if (verbose)
176 wxLogError( _("TIFF: Error reading image.") );
177
178 _TIFFfree( raster );
179 image->Destroy();
180
181 return FALSE;
182 }
183
184 bool hasmask = FALSE;
185
186 unsigned char *ptr = image->GetData();
187 ptr += w*3*(h-1);
188 uint32 pos = 0;
189
190 for (uint32 i = 0; i < h; i++)
191 {
192 for (uint32 j = 0; j < w; j++)
193 {
194 unsigned char alpha = (unsigned char)TIFFGetA(raster[pos]);
195 if (alpha < 127)
196 {
197 hasmask = TRUE;
198 ptr[0] = image->GetMaskRed();
199 ptr++;
200 ptr[0] = image->GetMaskGreen();
201 ptr++;
202 ptr[0] = image->GetMaskBlue();
203 ptr++;
204 }
205 else
206 {
207 ptr[0] = (unsigned char)TIFFGetR(raster[pos]);
208 ptr++;
209 ptr[0] = (unsigned char)TIFFGetG(raster[pos]);
210 ptr++;
211 ptr[0] = (unsigned char)TIFFGetB(raster[pos]);
212 ptr++;
213 }
214 pos++;
215 }
216 ptr -= 2*w*3; // subtract line we just added plus one line
217 }
218
219 _TIFFfree( raster );
220
221 TIFFClose( tif );
222
223 image->SetMask( hasmask );
224
225 return TRUE;
226}
227
228int wxTIFFHandler::GetImageCount( wxInputStream& stream )
229{
230 TIFF *tif = TIFFwxOpen( stream, "image", "r" );
231
232 if (!tif)
233 return 0;
234
235 int dircount = 0; // according to the libtiff docs, dircount should be set to 1 here???
236 do {
237 dircount++;
238 } while (TIFFReadDirectory(tif));
239
240 TIFFClose( tif );
241
242 return dircount;
243}
244
245bool wxTIFFHandler::SaveFile( wxImage *WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool WXUNUSED(verbose) )
246{
247 return FALSE;
248}
249
250bool wxTIFFHandler::DoCanRead( wxInputStream& stream )
251{
252 unsigned char hdr[2];
253
254 stream.Read(&hdr, 2);
255 stream.SeekI(-2, wxFromCurrent);
256
257 return ((hdr[0] == 0x49 && hdr[1] == 0x49) ||
258 (hdr[0] == 0x4D && hdr[1] == 0x4D));
259}
260
261
262#endif
263 // wxUSE_LIBTIFF
264
265
266
267
268
269