]>
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"
40 #ifndef TIFFLINKAGEMODE
41 #define TIFFLINKAGEMODE LINKAGEMODE
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler
,wxImageHandler
)
50 static tsize_t TIFFLINKAGEMODE
51 _tiffNullProc(thandle_t
WXUNUSED(handle
),
52 tdata_t
WXUNUSED(buf
),
53 tsize_t
WXUNUSED(size
))
58 static tsize_t TIFFLINKAGEMODE
59 _tiffReadProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
61 wxInputStream
*stream
= (wxInputStream
*) handle
;
62 stream
->Read( (void*) buf
, (size_t) size
);
63 return stream
->LastRead();
66 static tsize_t TIFFLINKAGEMODE
67 _tiffWriteProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
69 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
70 stream
->Write( (void*) buf
, (size_t) size
);
71 return stream
->LastWrite();
74 static toff_t TIFFLINKAGEMODE
75 _tiffSeekIProc(thandle_t handle
, toff_t off
, int whence
)
77 wxInputStream
*stream
= (wxInputStream
*) handle
;
81 case SEEK_SET
: mode
= wxFromStart
; break;
82 case SEEK_CUR
: mode
= wxFromCurrent
; break;
83 case SEEK_END
: mode
= wxFromEnd
; break;
84 default: mode
= wxFromCurrent
; break;
87 return (toff_t
)stream
->SeekI( (off_t
)off
, mode
);
90 static toff_t TIFFLINKAGEMODE
91 _tiffSeekOProc(thandle_t handle
, toff_t off
, int whence
)
93 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
97 case SEEK_SET
: mode
= wxFromStart
; break;
98 case SEEK_CUR
: mode
= wxFromCurrent
; break;
99 case SEEK_END
: mode
= wxFromEnd
; break;
100 default: mode
= wxFromCurrent
; break;
103 return (toff_t
)stream
->SeekO( (off_t
)off
, mode
);
106 static int TIFFLINKAGEMODE
107 _tiffCloseProc(thandle_t
WXUNUSED(handle
))
112 static toff_t TIFFLINKAGEMODE
113 _tiffSizeProc(thandle_t handle
)
115 wxStreamBase
*stream
= (wxStreamBase
*) handle
;
116 return (toff_t
) stream
->GetSize();
119 static int TIFFLINKAGEMODE
120 _tiffMapProc(thandle_t
WXUNUSED(handle
),
121 tdata_t
* WXUNUSED(pbase
),
122 toff_t
* WXUNUSED(psize
))
127 static void TIFFLINKAGEMODE
128 _tiffUnmapProc(thandle_t
WXUNUSED(handle
),
129 tdata_t
WXUNUSED(base
),
130 toff_t
WXUNUSED(size
))
135 TIFFwxOpen(wxInputStream
&stream
, const char* name
, const char* mode
)
137 TIFF
* tif
= TIFFClientOpen(name
, mode
,
139 _tiffReadProc
, _tiffNullProc
,
140 _tiffSeekIProc
, _tiffCloseProc
, _tiffSizeProc
,
141 _tiffMapProc
, _tiffUnmapProc
);
147 TIFFwxOpen(wxOutputStream
&stream
, const char* name
, const char* mode
)
149 TIFF
* tif
= TIFFClientOpen(name
, mode
,
151 _tiffNullProc
, _tiffWriteProc
,
152 _tiffSeekOProc
, _tiffCloseProc
, _tiffSizeProc
,
153 _tiffMapProc
, _tiffUnmapProc
);
158 bool wxTIFFHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
, bool verbose
, int index
)
165 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
170 wxLogError( _("TIFF: Error loading image.") );
175 if (!TIFFSetDirectory( tif
, (tdir_t
)index
))
178 wxLogError( _("Invalid TIFF image index.") );
189 TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &w
);
190 TIFFGetField( tif
, TIFFTAG_IMAGELENGTH
, &h
);
194 raster
= (uint32
*) _TIFFmalloc( npixels
* sizeof(uint32
) );
199 wxLogError( _("TIFF: Couldn't allocate memory.") );
206 image
->Create( (int)w
, (int)h
);
210 wxLogError( _("TIFF: Couldn't allocate memory.") );
218 if (!TIFFReadRGBAImage( tif
, w
, h
, raster
, 0 ))
221 wxLogError( _("TIFF: Error reading image.") );
230 bool hasmask
= FALSE
;
232 unsigned char *ptr
= image
->GetData();
236 for (uint32 i
= 0; i
< h
; i
++)
238 for (uint32 j
= 0; j
< w
; j
++)
240 unsigned char alpha
= (unsigned char)TIFFGetA(raster
[pos
]);
244 ptr
[0] = image
->GetMaskRed();
246 ptr
[0] = image
->GetMaskGreen();
248 ptr
[0] = image
->GetMaskBlue();
253 ptr
[0] = (unsigned char)TIFFGetR(raster
[pos
]);
255 ptr
[0] = (unsigned char)TIFFGetG(raster
[pos
]);
257 ptr
[0] = (unsigned char)TIFFGetB(raster
[pos
]);
262 ptr
-= 2*w
*3; // subtract line we just added plus one line
269 image
->SetMask( hasmask
);
274 int wxTIFFHandler::GetImageCount( wxInputStream
& stream
)
276 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
281 int dircount
= 0; // according to the libtiff docs, dircount should be set to 1 here???
284 } while (TIFFReadDirectory(tif
));
291 bool wxTIFFHandler::SaveFile( wxImage
*image
, wxOutputStream
& stream
, bool verbose
)
293 TIFF
*tif
= TIFFwxOpen( stream
, "image", "w" );
298 wxLogError( _("TIFF: Error saving image.") );
303 TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, (uint32
)image
->GetWidth());
304 TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, (uint32
)image
->GetHeight());
305 TIFFSetField(tif
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
);
306 TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 3);
307 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8);
308 TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
);
309 TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
);
310 TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_LZW
);
312 tsize_t linebytes
= (tsize_t
)image
->GetWidth() * 3;
315 if (TIFFScanlineSize(tif
) > linebytes
)
317 buf
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif
));
321 wxLogError( _("TIFF: Couldn't allocate memory.") );
333 TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
,
334 TIFFDefaultStripSize(tif
, (uint32
) -1));
336 unsigned char *ptr
= image
->GetData();
337 for (int row
= 0; row
< image
->GetHeight(); row
++)
340 memcpy(buf
, ptr
, image
->GetWidth());
342 if (TIFFWriteScanline(tif
, buf
? buf
: ptr
, (uint32
)row
, 0) < 0)
345 wxLogError( _("TIFF: Error writing image.") );
353 ptr
+= image
->GetWidth()*3;
356 (void) TIFFClose(tif
);
364 bool wxTIFFHandler::DoCanRead( wxInputStream
& stream
)
366 unsigned char hdr
[2];
368 stream
.Read(&hdr
, 2);
369 stream
.SeekI(-2, wxFromCurrent
);
371 return ((hdr
[0] == 0x49 && hdr
[1] == 0x49) ||
372 (hdr
[0] == 0x4D && hdr
[1] == 0x4D));