]> git.saurik.com Git - wxWidgets.git/blame - src/common/imagtiff.cpp
added compression ratio argument to wxZlibOutputStream ctor
[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"
257bcf28
RR
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
257bcf28 44IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler,wxImageHandler)
257bcf28
RR
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 );
0b72db08 51 return stream->LastRead();
257bcf28
RR
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 );
0b72db08 59 return stream->LastWrite();
257bcf28
RR
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 }
13111b2a 74
257bcf28
RR
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;
0b72db08 88 return (toff_t) stream->GetSize();
257bcf28
RR
89}
90
91static int
13111b2a
VZ
92_tiffMapProc(thandle_t WXUNUSED(handle),
93 tdata_t* WXUNUSED(pbase),
94 toff_t* WXUNUSED(psize))
257bcf28
RR
95{
96 return 0;
97}
98
99static void
13111b2a
VZ
100_tiffUnmapProc(thandle_t WXUNUSED(handle),
101 tdata_t WXUNUSED(base),
102 toff_t WXUNUSED(size))
257bcf28
RR
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
257bcf28
RR
115 return tif;
116}
117
118
700ec454 119bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int index )
257bcf28
RR
120{
121 image->Destroy();
13111b2a 122
0b72db08 123 TIFF *tif = TIFFwxOpen( stream, "image", "r" );
13111b2a 124
257bcf28
RR
125 if (!tif)
126 {
127 if (verbose)
58c837a4 128 wxLogError( _("TIFF: Error loading image.") );
13111b2a
VZ
129
130 return FALSE;
257bcf28 131 }
13111b2a 132
700ec454
RR
133 if (!TIFFSetDirectory( tif, (tdir_t)index ))
134 {
135 if (verbose)
136 wxLogError( _("Invalid TIFF image index.") );
13111b2a 137
700ec454 138 TIFFClose( tif );
13111b2a
VZ
139
140 return FALSE;
700ec454 141 }
257bcf28
RR
142
143 uint32 w, h;
13111b2a 144 uint32 npixels;
257bcf28 145 uint32 *raster;
13111b2a 146
257bcf28
RR
147 TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &w );
148 TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &h );
13111b2a 149
257bcf28 150 npixels = w * h;
13111b2a 151
257bcf28 152 raster = (uint32*) _TIFFmalloc( npixels * sizeof(uint32) );
13111b2a 153
257bcf28
RR
154 if (!raster)
155 {
156 if (verbose)
58c837a4 157 wxLogError( _("TIFF: Couldn't allocate memory.") );
13111b2a
VZ
158
159 return FALSE;
257bcf28
RR
160 }
161
479cd5de 162 image->Create( (int)w, (int)h );
13111b2a 163 if (!image->Ok())
257bcf28
RR
164 {
165 if (verbose)
58c837a4 166 wxLogError( _("TIFF: Couldn't allocate memory.") );
13111b2a
VZ
167
168 _TIFFfree( raster );
169
257bcf28
RR
170 return FALSE;
171 }
13111b2a 172
257bcf28
RR
173 if (!TIFFReadRGBAImage( tif, w, h, raster, 0 ))
174 {
175 if (verbose)
58c837a4 176 wxLogError( _("TIFF: Error reading image.") );
13111b2a
VZ
177
178 _TIFFfree( raster );
179 image->Destroy();
180
181 return FALSE;
257bcf28 182 }
13111b2a 183
257bcf28 184 bool hasmask = FALSE;
13111b2a 185
257bcf28 186 unsigned char *ptr = image->GetData();
5c5ab9eb 187 ptr += w*3*(h-1);
257bcf28 188 uint32 pos = 0;
13111b2a 189
257bcf28
RR
190 for (uint32 i = 0; i < h; i++)
191 {
ff7c6c9c 192 for (uint32 j = 0; j < w; j++)
13111b2a 193 {
5c5ab9eb 194 unsigned char alpha = (unsigned char)TIFFGetA(raster[pos]);
13111b2a
VZ
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 {
5c5ab9eb 207 ptr[0] = (unsigned char)TIFFGetR(raster[pos]);
13111b2a 208 ptr++;
5c5ab9eb 209 ptr[0] = (unsigned char)TIFFGetG(raster[pos]);
13111b2a 210 ptr++;
5c5ab9eb 211 ptr[0] = (unsigned char)TIFFGetB(raster[pos]);
13111b2a
VZ
212 ptr++;
213 }
214 pos++;
215 }
5c5ab9eb 216 ptr -= 2*w*3; // subtract line we just added plus one line
257bcf28 217 }
13111b2a 218
257bcf28 219 _TIFFfree( raster );
13111b2a 220
257bcf28 221 TIFFClose( tif );
13111b2a 222
257bcf28 223 image->SetMask( hasmask );
13111b2a 224
257bcf28
RR
225 return TRUE;
226}
227
700ec454
RR
228int wxTIFFHandler::GetImageCount( wxInputStream& stream )
229{
230 TIFF *tif = TIFFwxOpen( stream, "image", "r" );
13111b2a 231
700ec454 232 if (!tif)
13111b2a 233 return 0;
257bcf28 234
700ec454
RR
235 int dircount = 0; // according to the libtiff docs, dircount should be set to 1 here???
236 do {
237 dircount++;
238 } while (TIFFReadDirectory(tif));
13111b2a 239
700ec454 240 TIFFClose( tif );
13111b2a 241
700ec454
RR
242 return dircount;
243}
257bcf28 244
700ec454 245bool wxTIFFHandler::SaveFile( wxImage *WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool WXUNUSED(verbose) )
257bcf28
RR
246{
247 return FALSE;
248}
249
250bool wxTIFFHandler::DoCanRead( wxInputStream& stream )
251{
0b72db08 252 unsigned char hdr[2];
257bcf28 253
0b72db08
RR
254 stream.Read(&hdr, 2);
255 stream.SeekI(-2, wxFromCurrent);
13111b2a 256
0b72db08
RR
257 return ((hdr[0] == 0x49 && hdr[1] == 0x49) ||
258 (hdr[0] == 0x4D && hdr[1] == 0x4D));
257bcf28
RR
259}
260
261
262#endif
263 // wxUSE_LIBTIFF
264
265
266
267
268
269