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