#include "wx/colour.h"
#endif
-#include "wx/filefn.h"
#include "wx/wfstream.h"
#include "wx/xpmdecod.h"
}
unsigned char *data = image.GetData();
- const unsigned char *source_data = M_IMGDATA->m_data;
unsigned char *target_data;
- unsigned char *alpha_data = image.GetAlpha();
- const unsigned char *source_alpha = M_IMGDATA->m_alpha;
- unsigned char *target_alpha = 0 ;
- for (long j = 0; j < height; j++)
+ // we rotate the image in 21-pixel (63-byte) wide strips
+ // to make better use of cpu cache - memory transfers
+ // (note: while much better than single-pixel "strips",
+ // our vertical strips will still generally straddle cachelines)
+ for (long ii = 0; ii < width; )
{
- for (long i = 0; i < width; i++)
+ long next_ii = wxMin(ii + 21, width);
+
+ for (long j = 0; j < height; j++)
{
- if (clockwise)
+ const unsigned char *source_data
+ = M_IMGDATA->m_data + (j*width + ii)*3;
+
+ for (long i = ii; i < next_ii; i++)
{
- target_data = data + (((i+1)*height) - j - 1)*3;
- if (source_alpha)
- target_alpha = alpha_data + (((i+1)*height) - j - 1);
+ if ( clockwise )
+ {
+ target_data = data + (((i+1)*height) - j - 1)*3;
+ }
+ else
+ {
+ target_data = data + ((height*(width - 1 - i)) + j)*3;
+ }
+ memcpy( target_data, source_data, 3 );
+ source_data += 3;
}
- else
+ }
+
+ ii = next_ii;
+ }
+
+ const unsigned char *source_alpha = M_IMGDATA->m_alpha;
+
+ if ( source_alpha )
+ {
+ unsigned char *alpha_data = image.GetAlpha();
+ unsigned char *target_alpha = 0 ;
+
+ for (long j = 0; j < height; j++)
+ {
+ for (long i = 0; i < width; i++)
{
- target_data = data + ((height*(width-1)) + j - (i*height))*3;
- if (source_alpha)
+ if ( clockwise )
+ {
+ target_alpha = alpha_data + (((i+1)*height) - j - 1);
+ }
+ else
+ {
target_alpha = alpha_data + ((height*(width-1)) + j - (i*height));
- }
- memcpy( target_data, source_data, 3 );
- source_data += 3;
+ }
- if (source_alpha)
- {
- memcpy( target_alpha, source_alpha, 1 );
- source_alpha += 1;
+ *target_alpha = *source_alpha++;
}
}
}
int WXUNUSED_UNLESS_STREAMS(index) )
{
#if HAS_FILE_STREAMS
- if (wxFileExists(filename))
+ wxImageFileInputStream stream(filename);
+ if ( stream.IsOk() )
{
- wxImageFileInputStream stream(filename);
wxBufferedInputStream bstream( stream );
- return LoadFile(bstream, type, index);
+ if ( LoadFile(bstream, type, index) )
+ return true;
}
- else
- {
- wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
- return false;
- }
-#else // !HAS_FILE_STREAMS
- return false;
+ wxLogError(_("Failed to load image from file \"%s\"."), filename);
#endif // HAS_FILE_STREAMS
+
+ return false;
}
bool wxImage::LoadFile( const wxString& WXUNUSED_UNLESS_STREAMS(filename),
int WXUNUSED_UNLESS_STREAMS(index) )
{
#if HAS_FILE_STREAMS
- if (wxFileExists(filename))
+ wxImageFileInputStream stream(filename);
+ if ( stream.IsOk() )
{
- wxImageFileInputStream stream(filename);
wxBufferedInputStream bstream( stream );
- return LoadFile(bstream, mimetype, index);
+ if ( LoadFile(bstream, mimetype, index) )
+ return true;
}
- else
- {
- wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
- return false;
- }
-#else // !HAS_FILE_STREAMS
- return false;
+ wxLogError(_("Failed to load image from file \"%s\"."), filename);
#endif // HAS_FILE_STREAMS
+
+ return false;
}
const unsigned maxWidth = GetOptionInt(wxIMAGE_OPTION_MAX_WIDTH),
maxHeight = GetOptionInt(wxIMAGE_OPTION_MAX_HEIGHT);
+ // Preserve the original stream position if possible to rewind back to it
+ // if we failed to load the file -- maybe the next handler that we try can
+ // succeed after us then.
+ wxFileOffset posOld = wxInvalidOffset;
+ if ( stream.IsSeekable() )
+ posOld = stream.TellI();
+
if ( !handler.LoadFile(this, stream, true/*verbose*/, index) )
+ {
+ if ( posOld != wxInvalidOffset )
+ stream.SeekI(posOld);
+
return false;
+ }
// rescale the image to the specified size if needed
if ( maxWidth || maxHeight )
if ( type == wxBITMAP_TYPE_ANY )
{
+ if ( !stream.IsSeekable() )
+ {
+ // The error message about image data format being unknown below
+ // would be misleading in this case as we are not even going to try
+ // any handlers because CanRead() never does anything for not
+ // seekable stream, so try to be more precise here.
+ wxLogError(_("Can't automatically determine the image format "
+ "for non-seekable input."));
+ return false;
+ }
+
const wxList& list = GetHandlers();
for ( wxList::compatibility_iterator node = list.GetFirst();
node;
return true;
}
- wxLogWarning( _("No handler found for image type.") );
+ wxLogWarning( _("Unknown image data format.") );
return false;
}
if ( stream.IsSeekable() && !handler->CanRead(stream) )
{
- wxLogError(_("Image file is not of type %d."), type);
+ wxLogError(_("This is not a %s."), handler->GetName());
return false;
}
if ( stream.IsSeekable() && !handler->CanRead(stream) )
{
- wxLogError(_("Image file is not of type %s."), mimetype);
+ wxLogError(_("Image is not of type %s."), mimetype);
return false;
}
bool wxImageHandler::CanRead( const wxString& name )
{
- if (wxFileExists(name))
+ wxImageFileInputStream stream(name);
+ if ( !stream.IsOk() )
{
- wxImageFileInputStream stream(name);
- return CanRead(stream);
- }
+ wxLogError(_("Failed to check format of image file \"%s\"."), name);
- wxLogError( _("Can't check image format of file '%s': file does not exist."), name.c_str() );
+ return false;
+ }
- return false;
+ return CanRead(stream);
}
bool wxImageHandler::CallDoCanRead(wxInputStream& stream)