]> git.saurik.com Git - wxWidgets.git/blame - src/common/imagtiff.cpp
wxSoundFileStream doc updates (indeed, first write)
[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
479cd5de 166 image->Create( (int)w, (int)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 190 unsigned char *ptr = image->GetData();
5c5ab9eb 191 ptr += w*3*(h-1);
257bcf28 192 uint32 pos = 0;
13111b2a 193
257bcf28
RR
194 for (uint32 i = 0; i < h; i++)
195 {
ff7c6c9c 196 for (uint32 j = 0; j < w; j++)
13111b2a 197 {
5c5ab9eb 198 unsigned char alpha = (unsigned char)TIFFGetA(raster[pos]);
13111b2a
VZ
199 if (alpha < 127)
200 {
201 hasmask = TRUE;
202 ptr[0] = image->GetMaskRed();
203 ptr++;
204 ptr[0] = image->GetMaskGreen();
205 ptr++;
206 ptr[0] = image->GetMaskBlue();
207 ptr++;
208 }
209 else
210 {
5c5ab9eb 211 ptr[0] = (unsigned char)TIFFGetR(raster[pos]);
13111b2a 212 ptr++;
5c5ab9eb 213 ptr[0] = (unsigned char)TIFFGetG(raster[pos]);
13111b2a 214 ptr++;
5c5ab9eb 215 ptr[0] = (unsigned char)TIFFGetB(raster[pos]);
13111b2a
VZ
216 ptr++;
217 }
218 pos++;
219 }
5c5ab9eb 220 ptr -= 2*w*3; // subtract line we just added plus one line
257bcf28 221 }
13111b2a 222
257bcf28 223 _TIFFfree( raster );
13111b2a 224
257bcf28 225 TIFFClose( tif );
13111b2a 226
257bcf28 227 image->SetMask( hasmask );
13111b2a 228
257bcf28
RR
229 return TRUE;
230}
231
700ec454
RR
232int wxTIFFHandler::GetImageCount( wxInputStream& stream )
233{
234 TIFF *tif = TIFFwxOpen( stream, "image", "r" );
13111b2a 235
700ec454 236 if (!tif)
13111b2a 237 return 0;
257bcf28 238
700ec454
RR
239 int dircount = 0; // according to the libtiff docs, dircount should be set to 1 here???
240 do {
241 dircount++;
242 } while (TIFFReadDirectory(tif));
13111b2a 243
700ec454 244 TIFFClose( tif );
13111b2a 245
700ec454
RR
246 return dircount;
247}
257bcf28 248
700ec454 249bool wxTIFFHandler::SaveFile( wxImage *WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool WXUNUSED(verbose) )
257bcf28
RR
250{
251 return FALSE;
252}
253
254bool wxTIFFHandler::DoCanRead( wxInputStream& stream )
255{
0b72db08 256 unsigned char hdr[2];
257bcf28 257
0b72db08
RR
258 stream.Read(&hdr, 2);
259 stream.SeekI(-2, wxFromCurrent);
13111b2a 260
0b72db08
RR
261 return ((hdr[0] == 0x49 && hdr[1] == 0x49) ||
262 (hdr[0] == 0x4D && hdr[1] == 0x4D));
257bcf28
RR
263}
264
265
266#endif
267 // wxUSE_LIBTIFF
268
269
270
271
272
273