X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/37ba70a520519fd2fe4f11400f1383fa37ae7cd9..8ddda15ba50407de79f9749ab840d8c9ba0dde39:/src/common/imagtiff.cpp?ds=sidebyside diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 49c76fba7c..0e90db2a5f 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -7,6 +7,14 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -24,10 +32,14 @@ #include "wx/intl.h" #include "wx/bitmap.h" #include "wx/module.h" + #include "wx/wxcrtvararg.h" #endif extern "C" { +#ifdef __DMC__ + #include "tif_config.h" +#endif #include "tiff.h" #include "tiffio.h" } @@ -42,12 +54,67 @@ extern "C" #endif #endif +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// TIFF library error/warning handlers +// ---------------------------------------------------------------------------- + +static wxString +FormatTiffMessage(const char *module, const char *fmt, va_list ap) +{ + char buf[512]; + if ( wxCRT_VsnprintfA(buf, WXSIZEOF(buf), fmt, ap) <= 0 ) + { + // this isn't supposed to happen, but if it does, it's better + // than nothing + strcpy(buf, "Incorrectly formatted TIFF message"); + } + buf[WXSIZEOF(buf)-1] = 0; // make sure it is always NULL-terminated + + wxString msg(buf); + if ( module ) + msg += wxString::Format(_(" (in module \"%s\")"), module); + + return msg; +} + +extern "C" +{ + +static void +TIFFwxWarningHandler(const char* module, const char *fmt, va_list ap) +{ + wxLogWarning("%s", FormatTiffMessage(module, fmt, ap)); +} + +static void +TIFFwxErrorHandler(const char* module, const char *fmt, va_list ap) +{ + wxLogError("%s", FormatTiffMessage(module, fmt, ap)); +} + +} // extern "C" + //----------------------------------------------------------------------------- // wxTIFFHandler //----------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler,wxImageHandler) +wxTIFFHandler::wxTIFFHandler() +{ + 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); + TIFFSetErrorHandler((TIFFErrorHandler) TIFFwxErrorHandler); +} + #if wxUSE_STREAMS // helper to translate our, possibly 64 bit, wxFileOffset to TIFF, always 32 @@ -59,7 +126,7 @@ static toff_t wxFileOffsetToTIFF(wxFileOffset ofs) 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; } @@ -165,38 +232,6 @@ wxTIFFUnmapProc(thandle_t WXUNUSED(handle), { } -static void -TIFFwxWarningHandler(const char* module, - const char* WXUNUSED_IN_UNICODE(fmt), - va_list WXUNUSED_IN_UNICODE(ap)) -{ - if (module != NULL) - wxLogWarning(_("tiff module: %s"), wxString::FromAscii(module).c_str()); - - // FIXME: this is not terrible informative but better than crashing! -#if wxUSE_UNICODE - wxLogWarning(_("TIFF library warning.")); -#else - wxVLogWarning(fmt, ap); -#endif -} - -static void -TIFFwxErrorHandler(const char* module, - const char* WXUNUSED_IN_UNICODE(fmt), - va_list WXUNUSED_IN_UNICODE(ap)) -{ - if (module != NULL) - wxLogError(_("tiff module: %s"), wxString::FromAscii(module).c_str()); - - // FIXME: as above -#if wxUSE_UNICODE - wxLogError(_("TIFF library error.")); -#else - wxVLogError(fmt, ap); -#endif -} - } // extern "C" TIFF* @@ -223,16 +258,6 @@ TIFFwxOpen(wxOutputStream &stream, const char* name, const char* mode) return tif; } -wxTIFFHandler::wxTIFFHandler() -{ - m_name = wxT("TIFF file"); - m_extension = wxT("tif"); - m_type = wxBITMAP_TYPE_TIF; - m_mime = wxT("image/tiff"); - TIFFSetWarningHandler((TIFFErrorHandler) TIFFwxWarningHandler); - TIFFSetErrorHandler((TIFFErrorHandler) TIFFwxErrorHandler); -} - bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int index ) { if (index == -1) @@ -245,7 +270,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!tif) { if (verbose) + { wxLogError( _("TIFF: Error loading image.") ); + } return false; } @@ -253,7 +280,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!TIFFSetDirectory( tif, (tdir_t)index )) { if (verbose) + { wxLogError( _("Invalid TIFF image index.") ); + } TIFFClose( tif ); @@ -261,7 +290,6 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos } uint32 w, h; - uint32 npixels; uint32 *raster; TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &w ); @@ -275,14 +303,29 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos (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.") ); + } + + TIFFClose(tif); + + return false; + } - raster = (uint32*) _TIFFmalloc( npixels * sizeof(uint32) ); + raster = (uint32*) _TIFFmalloc( (uint32)bytesNeeded ); if (!raster) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } TIFFClose( tif ); @@ -293,7 +336,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!image->Ok()) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } _TIFFfree( raster ); TIFFClose( tif ); @@ -307,7 +352,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!TIFFReadRGBAImage( tif, w, h, raster, 0 )) { if (verbose) + { wxLogError( _("TIFF: Error reading image.") ); + } _TIFFfree( raster ); image->Destroy(); @@ -373,10 +420,10 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos { float xres, yres; if ( TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) ) - image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, xres); + image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, wxRound(xres)); if ( TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) ) - image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, yres); + image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, wxRound(yres)); } } @@ -388,7 +435,7 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos return true; } -int wxTIFFHandler::GetImageCount( wxInputStream& stream ) +int wxTIFFHandler::DoGetImageCount( wxInputStream& stream ) { TIFF *tif = TIFFwxOpen( stream, "image", "r" ); @@ -402,6 +449,9 @@ int wxTIFFHandler::GetImageCount( wxInputStream& stream ) TIFFClose( tif ); + // NOTE: this function modifies the current stream position but it's ok + // (see wxImageHandler::GetImageCount) + return dircount; } @@ -412,7 +462,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if (!tif) { if (verbose) + { wxLogError( _("TIFF: Error saving image.") ); + } return false; } @@ -430,7 +482,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo switch ( res ) { default: - wxFAIL_MSG( _T("unknown image resolution units") ); + wxFAIL_MSG( wxT("unknown image resolution units") ); // fall through case wxIMAGE_RESOLUTION_NONE: @@ -492,7 +544,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if (!buf) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } TIFFClose( tif ); @@ -538,7 +592,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if ( TIFFWriteScanline(tif, buf ? buf : ptr, (uint32)row, 0) < 0 ) { if (verbose) + { wxLogError( _("TIFF: Error writing image.") ); + } TIFFClose( tif ); if (buf) @@ -562,7 +618,7 @@ bool wxTIFFHandler::DoCanRead( wxInputStream& stream ) { 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') ||