#if wxUSE_IMAGE && wxUSE_LIBTIFF
#include "wx/imagtiff.h"
+#include "wx/versioninfo.h"
#ifndef WX_PRECOMP
#include "wx/log.h"
{
m_name = wxT("TIFF file");
m_extension = wxT("tif");
+ m_altExtensions.Add(wxT("tiff"));
m_type = wxBITMAP_TYPE_TIF;
m_mime = wxT("image/tiff");
TIFFSetWarningHandler((TIFFErrorHandler) TIFFwxWarningHandler);
toff_t tofs = wx_truncate_cast(toff_t, ofs);
wxCHECK_MSG( (wxFileOffset)tofs == ofs, (toff_t)-1,
- _T("TIFF library doesn't support large files") );
+ wxT("TIFF library doesn't support large files") );
return tofs;
}
if (!tif)
{
if (verbose)
+ {
wxLogError( _("TIFF: Error loading image.") );
+ }
return false;
}
if (!TIFFSetDirectory( tif, (tdir_t)index ))
{
if (verbose)
+ {
wxLogError( _("Invalid TIFF image index.") );
+ }
TIFFClose( tif );
}
uint32 w, h;
- uint32 npixels;
uint32 *raster;
TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &w );
(samplesInfo[0] == EXTRASAMPLE_ASSOCALPHA ||
samplesInfo[0] == EXTRASAMPLE_UNASSALPHA));
- npixels = w * h;
+ // guard against integer overflow during multiplication which could result
+ // in allocating a too small buffer and then overflowing it
+ const double bytesNeeded = (double)w * (double)h * sizeof(uint32);
+ if ( bytesNeeded >= wxUINT32_MAX )
+ {
+ if ( verbose )
+ {
+ wxLogError( _("TIFF: Image size is abnormally big.") );
+ }
- raster = (uint32*) _TIFFmalloc( npixels * sizeof(uint32) );
+ TIFFClose(tif);
+
+ return false;
+ }
+
+ raster = (uint32*) _TIFFmalloc( (uint32)bytesNeeded );
if (!raster)
{
if (verbose)
+ {
wxLogError( _("TIFF: Couldn't allocate memory.") );
+ }
TIFFClose( tif );
if (!image->Ok())
{
if (verbose)
+ {
wxLogError( _("TIFF: Couldn't allocate memory.") );
+ }
_TIFFfree( raster );
TIFFClose( tif );
if (!TIFFReadRGBAImage( tif, w, h, raster, 0 ))
{
if (verbose)
+ {
wxLogError( _("TIFF: Error reading image.") );
+ }
_TIFFfree( raster );
image->Destroy();
return true;
}
-int wxTIFFHandler::GetImageCount( wxInputStream& stream )
+int wxTIFFHandler::DoGetImageCount( wxInputStream& stream )
{
TIFF *tif = TIFFwxOpen( stream, "image", "r" );
TIFFClose( tif );
+ // NOTE: this function modifies the current stream position but it's ok
+ // (see wxImageHandler::GetImageCount)
+
return dircount;
}
if (!tif)
{
if (verbose)
+ {
wxLogError( _("TIFF: Error saving image.") );
+ }
return false;
}
switch ( res )
{
default:
- wxFAIL_MSG( _T("unknown image resolution units") );
+ wxFAIL_MSG( wxT("unknown image resolution units") );
// fall through
case wxIMAGE_RESOLUTION_NONE:
if (!buf)
{
if (verbose)
+ {
wxLogError( _("TIFF: Couldn't allocate memory.") );
+ }
TIFFClose( tif );
if ( TIFFWriteScanline(tif, buf ? buf : ptr, (uint32)row, 0) < 0 )
{
if (verbose)
+ {
wxLogError( _("TIFF: Error writing image.") );
+ }
TIFFClose( tif );
if (buf)
{
unsigned char hdr[2];
- if ( !stream.Read(&hdr[0], WXSIZEOF(hdr)) )
+ if ( !stream.Read(&hdr[0], WXSIZEOF(hdr)) ) // it's ok to modify the stream position here
return false;
return (hdr[0] == 'I' && hdr[1] == 'I') ||
#endif // wxUSE_STREAMS
+/*static*/ wxVersionInfo wxTIFFHandler::GetLibraryVersionInfo()
+{
+ int major,
+ minor,
+ micro;
+
+ const wxString ver(::TIFFGetVersion());
+ if ( wxSscanf(ver, "LIBTIFF, Version %d.%d.%d", &major, &minor, µ) != 3 )
+ {
+ wxLogDebug("Unrecognized libtiff version string \"%s\"", ver);
+
+ major =
+ minor =
+ micro = 0;
+ }
+
+ wxString copyright;
+ const wxString desc = ver.BeforeFirst('\n', ©right);
+ copyright.Replace("\n", "");
+
+ return wxVersionInfo("libtiff", major, minor, micro, desc, copyright);
+}
+
#endif // wxUSE_LIBTIFF