]>
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 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler
,wxImageHandler
)
46 static tsize_t LINKAGEMODE
47 _tiffNullProc(thandle_t
WXUNUSED(handle
),
48 tdata_t
WXUNUSED(buf
),
49 tsize_t
WXUNUSED(size
))
54 static tsize_t LINKAGEMODE
55 _tiffReadProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
57 wxInputStream
*stream
= (wxInputStream
*) handle
;
58 stream
->Read( (void*) buf
, (size_t) size
);
59 return stream
->LastRead();
62 static tsize_t LINKAGEMODE
63 _tiffWriteProc(thandle_t handle
, tdata_t buf
, tsize_t size
)
65 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
66 stream
->Write( (void*) buf
, (size_t) size
);
67 return stream
->LastWrite();
70 static toff_t LINKAGEMODE
71 _tiffSeekIProc(thandle_t handle
, toff_t off
, int whence
)
73 wxInputStream
*stream
= (wxInputStream
*) handle
;
77 case SEEK_SET
: mode
= wxFromStart
; break;
78 case SEEK_CUR
: mode
= wxFromCurrent
; break;
79 case SEEK_END
: mode
= wxFromEnd
; break;
80 default: mode
= wxFromCurrent
; break;
83 return (toff_t
)stream
->SeekI( (off_t
)off
, mode
);
86 static toff_t LINKAGEMODE
87 _tiffSeekOProc(thandle_t handle
, toff_t off
, int whence
)
89 wxOutputStream
*stream
= (wxOutputStream
*) handle
;
93 case SEEK_SET
: mode
= wxFromStart
; break;
94 case SEEK_CUR
: mode
= wxFromCurrent
; break;
95 case SEEK_END
: mode
= wxFromEnd
; break;
96 default: mode
= wxFromCurrent
; break;
99 return (toff_t
)stream
->SeekO( (off_t
)off
, mode
);
102 static int LINKAGEMODE
103 _tiffCloseProc(thandle_t
WXUNUSED(handle
))
108 static toff_t LINKAGEMODE
109 _tiffSizeProc(thandle_t handle
)
111 wxStreamBase
*stream
= (wxStreamBase
*) handle
;
112 return (toff_t
) stream
->GetSize();
115 static int LINKAGEMODE
116 _tiffMapProc(thandle_t
WXUNUSED(handle
),
117 tdata_t
* WXUNUSED(pbase
),
118 toff_t
* WXUNUSED(psize
))
123 static void LINKAGEMODE
124 _tiffUnmapProc(thandle_t
WXUNUSED(handle
),
125 tdata_t
WXUNUSED(base
),
126 toff_t
WXUNUSED(size
))
131 TIFFwxOpen(wxInputStream
&stream
, const char* name
, const char* mode
)
133 TIFF
* tif
= TIFFClientOpen(name
, mode
,
135 _tiffReadProc
, _tiffNullProc
,
136 _tiffSeekIProc
, _tiffCloseProc
, _tiffSizeProc
,
137 _tiffMapProc
, _tiffUnmapProc
);
143 TIFFwxOpen(wxOutputStream
&stream
, const char* name
, const char* mode
)
145 TIFF
* tif
= TIFFClientOpen(name
, mode
,
147 _tiffNullProc
, _tiffWriteProc
,
148 _tiffSeekOProc
, _tiffCloseProc
, _tiffSizeProc
,
149 _tiffMapProc
, _tiffUnmapProc
);
154 bool wxTIFFHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
, bool verbose
, int index
)
158 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
163 wxLogError( _("TIFF: Error loading image.") );
168 if (!TIFFSetDirectory( tif
, (tdir_t
)index
))
171 wxLogError( _("Invalid TIFF image index.") );
182 TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &w
);
183 TIFFGetField( tif
, TIFFTAG_IMAGELENGTH
, &h
);
187 raster
= (uint32
*) _TIFFmalloc( npixels
* sizeof(uint32
) );
192 wxLogError( _("TIFF: Couldn't allocate memory.") );
199 image
->Create( (int)w
, (int)h
);
203 wxLogError( _("TIFF: Couldn't allocate memory.") );
211 if (!TIFFReadRGBAImage( tif
, w
, h
, raster
, 0 ))
214 wxLogError( _("TIFF: Error reading image.") );
223 bool hasmask
= FALSE
;
225 unsigned char *ptr
= image
->GetData();
229 for (uint32 i
= 0; i
< h
; i
++)
231 for (uint32 j
= 0; j
< w
; j
++)
233 unsigned char alpha
= (unsigned char)TIFFGetA(raster
[pos
]);
237 ptr
[0] = image
->GetMaskRed();
239 ptr
[0] = image
->GetMaskGreen();
241 ptr
[0] = image
->GetMaskBlue();
246 ptr
[0] = (unsigned char)TIFFGetR(raster
[pos
]);
248 ptr
[0] = (unsigned char)TIFFGetG(raster
[pos
]);
250 ptr
[0] = (unsigned char)TIFFGetB(raster
[pos
]);
255 ptr
-= 2*w
*3; // subtract line we just added plus one line
262 image
->SetMask( hasmask
);
267 int wxTIFFHandler::GetImageCount( wxInputStream
& stream
)
269 TIFF
*tif
= TIFFwxOpen( stream
, "image", "r" );
274 int dircount
= 0; // according to the libtiff docs, dircount should be set to 1 here???
277 } while (TIFFReadDirectory(tif
));
284 bool wxTIFFHandler::SaveFile( wxImage
*image
, wxOutputStream
& stream
, bool verbose
)
286 TIFF
*tif
= TIFFwxOpen( stream
, "image", "w" );
291 wxLogError( _("TIFF: Error saving image.") );
296 TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, (uint32
)image
->GetWidth());
297 TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, (uint32
)image
->GetHeight());
298 TIFFSetField(tif
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
);
299 TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 3);
300 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8);
301 TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
);
302 TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
);
303 TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_LZW
);
305 tsize_t linebytes
= (tsize_t
)image
->GetWidth() * 3;
308 if (TIFFScanlineSize(tif
) > linebytes
)
310 buf
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif
));
314 wxLogError( _("TIFF: Couldn't allocate memory.") );
326 TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
,
327 TIFFDefaultStripSize(tif
, (uint32
) -1));
329 unsigned char *ptr
= image
->GetData();
330 for (int row
= 0; row
< image
->GetHeight(); row
++)
333 memcpy(buf
, ptr
, image
->GetWidth());
335 if (TIFFWriteScanline(tif
, buf
? buf
: ptr
, (uint32
)row
, 0) < 0)
338 wxLogError( _("TIFF: Error writing image.") );
346 ptr
+= image
->GetWidth()*3;
349 (void) TIFFClose(tif
);
357 bool wxTIFFHandler::DoCanRead( wxInputStream
& stream
)
359 unsigned char hdr
[2];
361 stream
.Read(&hdr
, 2);
362 stream
.SeekI(-2, wxFromCurrent
);
364 return ((hdr
[0] == 0x49 && hdr
[1] == 0x49) ||
365 (hdr
[0] == 0x4D && hdr
[1] == 0x4D));