]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imagtiff.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxImage TIFF handler
4 // Author: Robert Roebling
6 // Copyright: (c) Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "imagtiff.h"
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
23 #if wxUSE_IMAGE && wxUSE_LIBTIFF
25 #include "wx/imagtiff.h"
26 #include "wx/bitmap.h"
35 #include "wx/filefn.h"
36 #include "wx/wfstream.h"
38 #include "wx/module.h"
43 #define LINKAGEMODE __cdecl
46 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
50 IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler
,wxImageHandler
)
52 static tsize_t LINKAGEMODE
53 _tiffNullProc(thandle_t
WXUNUSED(handle
),
54 tdata_t
WXUNUSED(buf
),
55 tsize_t
WXUNUSED(size
))
60 static tsize_t LINKAGEMODE
61 _tiffReadProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
63 wxInputStream
*stream
= (wxInputStream
*) handle
;
64 stream
->Read( (void*) buf
, (size_t) size
);
65 return stream
->LastRead();
68 static tsize_t LINKAGEMODE
69 _tiffWriteProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
71 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
72 stream
->Write( (void*) buf
, (size_t) size
);
73 return stream
->LastWrite();
76 static toff_t LINKAGEMODE
77 _tiffSeekIProc(thandle_t handle
, toff_t off
, int whence
)
79 wxInputStream
*stream
= (wxInputStream
*) handle
;
83 case SEEK_SET
: mode
= wxFromStart
; break;
84 case SEEK_CUR
: mode
= wxFromCurrent
; break;
85 case SEEK_END
: mode
= wxFromEnd
; break;
86 default: mode
= wxFromCurrent
; break;
89 return (toff_t
)stream
->SeekI( (off_t
)off
, mode
);
92 static toff_t LINKAGEMODE
93 _tiffSeekOProc(thandle_t handle
, toff_t off
, int whence
)
95 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
99 case SEEK_SET
: mode
= wxFromStart
; break;
100 case SEEK_CUR
: mode
= wxFromCurrent
; break;
101 case SEEK_END
: mode
= wxFromEnd
; break;
102 default: mode
= wxFromCurrent
; break;
105 return (toff_t
)stream
->SeekO( (off_t
)off
, mode
);
108 static int LINKAGEMODE
109 _tiffCloseProc(thandle_t
WXUNUSED(handle
))
114 static toff_t LINKAGEMODE
115 _tiffSizeProc(thandle_t handle
)
117 wxStreamBase
*stream
= (wxStreamBase
*) handle
;
118 return (toff_t
) stream
->GetSize();
121 static int LINKAGEMODE
122 _tiffMapProc(thandle_t
WXUNUSED(handle
),
123 tdata_t
* WXUNUSED(pbase
),
124 toff_t
* WXUNUSED(psize
))
129 static void LINKAGEMODE
130 _tiffUnmapProc(thandle_t
WXUNUSED(handle
),
131 tdata_t
WXUNUSED(base
),
132 toff_t
WXUNUSED(size
))
137 TIFFwxOpen(wxInputStream
&stream
, const char* name
, const char* mode
)
139 TIFF
* tif
= TIFFClientOpen(name
, mode
,
141 _tiffReadProc
, _tiffNullProc
,
142 _tiffSeekIProc
, _tiffCloseProc
, _tiffSizeProc
,
143 _tiffMapProc
, _tiffUnmapProc
);
149 TIFFwxOpen(wxOutputStream
&stream
, const char* name
, const char* mode
)
151 TIFF
* tif
= TIFFClientOpen(name
, mode
,
153 _tiffNullProc
, _tiffWriteProc
,
154 _tiffSeekOProc
, _tiffCloseProc
, _tiffSizeProc
,
155 _tiffMapProc
, _tiffUnmapProc
);
160 bool wxTIFFHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
, bool verbose
, int index
)
164 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
169 wxLogError( _("TIFF: Error loading image.") );
174 if (!TIFFSetDirectory( tif
, (tdir_t
)index
))
177 wxLogError( _("Invalid TIFF image index.") );
188 TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &w
);
189 TIFFGetField( tif
, TIFFTAG_IMAGELENGTH
, &h
);
193 raster
= (uint32
*) _TIFFmalloc( npixels
* sizeof(uint32
) );
198 wxLogError( _("TIFF: Couldn't allocate memory.") );
205 image
->Create( (int)w
, (int)h
);
209 wxLogError( _("TIFF: Couldn't allocate memory.") );
217 if (!TIFFReadRGBAImage( tif
, w
, h
, raster
, 0 ))
220 wxLogError( _("TIFF: Error reading image.") );
229 bool hasmask
= FALSE
;
231 unsigned char *ptr
= image
->GetData();
235 for (uint32 i
= 0; i
< h
; i
++)
237 for (uint32 j
= 0; j
< w
; j
++)
239 unsigned char alpha
= (unsigned char)TIFFGetA(raster
[pos
]);
243 ptr
[0] = image
->GetMaskRed();
245 ptr
[0] = image
->GetMaskGreen();
247 ptr
[0] = image
->GetMaskBlue();
252 ptr
[0] = (unsigned char)TIFFGetR(raster
[pos
]);
254 ptr
[0] = (unsigned char)TIFFGetG(raster
[pos
]);
256 ptr
[0] = (unsigned char)TIFFGetB(raster
[pos
]);
261 ptr
-= 2*w
*3; // subtract line we just added plus one line
268 image
->SetMask( hasmask
);
273 int wxTIFFHandler::GetImageCount( wxInputStream
& stream
)
275 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
280 int dircount
= 0; // according to the libtiff docs, dircount should be set to 1 here???
283 } while (TIFFReadDirectory(tif
));
290 bool wxTIFFHandler::SaveFile( wxImage
*image
, wxOutputStream
& stream
, bool verbose
)
292 TIFF
*tif
= TIFFwxOpen( stream
, "image", "w" );
297 wxLogError( _("TIFF: Error saving image.") );
302 TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, (uint32
)image
->GetWidth());
303 TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, (uint32
)image
->GetHeight());
304 TIFFSetField(tif
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
);
305 TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 3);
306 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8);
307 TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
);
308 TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
);
309 TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_LZW
);
311 tsize_t linebytes
= (tsize_t
)image
->GetWidth() * 3;
314 if (TIFFScanlineSize(tif
) > linebytes
)
316 buf
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif
));
320 wxLogError( _("TIFF: Couldn't allocate memory.") );
332 TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
,
333 TIFFDefaultStripSize(tif
, (uint32
) -1));
335 unsigned char *ptr
= image
->GetData();
336 for (int row
= 0; row
< image
->GetHeight(); row
++)
339 memcpy(buf
, ptr
, image
->GetWidth());
341 if (TIFFWriteScanline(tif
, buf
? buf
: ptr
, (uint32
)row
, 0) < 0)
344 wxLogError( _("TIFF: Error writing image.") );
352 ptr
+= image
->GetWidth()*3;
355 (void) TIFFClose(tif
);
363 bool wxTIFFHandler::DoCanRead( wxInputStream
& stream
)
365 unsigned char hdr
[2];
367 stream
.Read(&hdr
, 2);
368 stream
.SeekI(-2, wxFromCurrent
);
370 return ((hdr
[0] == 0x49 && hdr
[1] == 0x49) ||
371 (hdr
[0] == 0x4D && hdr
[1] == 0x4D));