// For memcpy
#include <string.h>
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+#if wxUSE_ICO_CUR
+
+static bool CanReadICOOrCUR(wxInputStream *stream, wxUint16 resourceType);
+
+#endif // wxUSE_ICO_CUR
+
//-----------------------------------------------------------------------------
// wxBMPHandler
//-----------------------------------------------------------------------------
int linesize = ((width * bpp + 31) / 32) * 4;
+ // flag indicating if we have any not fully transparent alpha values: this
+ // is used to account for the bitmaps which use 32bpp format (normally
+ // meaning that they have alpha channel) but have only zeroes in it so that
+ // without this hack they appear fully transparent -- and as this is
+ // unlikely intentional, we consider that they don't have alpha at all in
+ // this case (see #10915)
+ bool hasValidAlpha = false;
+
/* BMPs are stored upside down */
for ( int line = (height - 1); line >= 0; line-- )
{
{
temp = (unsigned char)((aDword & amask) >> ashift);
alpha[line * width + column] = temp;
+
+ if ( temp != wxALPHA_TRANSPARENT )
+ hasValidAlpha = true;
}
column++;
}
image->SetMask(false);
+ // check if we had any valid alpha values in this bitmap
+ if ( alpha && !hasValidAlpha )
+ {
+ // we didn't, so finally discard the alpha channel completely
+ image->ClearAlpha();
+ }
+
const wxStreamError err = stream.GetLastError();
return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
}
stream.Read(&IconDir, sizeof(IconDir));
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
-
+
// nType is 1 for Icons, 2 for Cursors:
wxUint16 nType = wxUINT16_SWAP_ON_BE(IconDir.idType);
// remember how many bytes we read from the stream:
wxFileOffset alreadySeeked = sizeof(IconDir);
-
+
for (unsigned int i = 0; i < nIcons; i++ )
{
alreadySeeked += stream.Read(pCurrentEntry, sizeof(ICONDIRENTRY)).LastRead();
-
+
// bHeight and bColorCount are wxUint8
if ( pCurrentEntry->bWidth >= wMax )
{
colmax = pCurrentEntry->bColorCount;
}
}
-
+
pCurrentEntry++;
}
{
// seek to selected icon:
pCurrentEntry = pIconDirEntry + iSel;
-
+
// NOTE: seeking a positive amount in wxFromCurrent mode allows us to
// load even non-seekable streams (see wxInputStream::SeekI docs)!
wxFileOffset offset = wxUINT32_SWAP_ON_BE(pCurrentEntry->dwImageOffset) - alreadySeeked;
if (offset != 0 && stream.SeekI(offset, wxFromCurrent) == wxInvalidOffset)
return false;
-
+
bResult = LoadDib(image, stream, true, IsBmp);
bool bIsCursorType = (this->GetType() == wxBITMAP_TYPE_CUR) || (this->GetType() == wxBITMAP_TYPE_ANI);
if ( bResult && bIsCursorType && nType == 2 )
image->SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, wxUINT16_SWAP_ON_BE(pCurrentEntry->wBitCount));
}
}
-
+
delete [] pIconDirEntry;
-
+
return bResult;
}
if (stream.Read(&IconDir, sizeof(IconDir)).LastRead() != sizeof(IconDir))
// it's ok to modify the stream position here
return 0;
-
+
return (int)wxUINT16_SWAP_ON_BE(IconDir.idCount);
}
bool wxICOHandler::DoCanRead(wxInputStream& stream)
{
- unsigned char hdr[4];
- if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) // it's ok to modify the stream position here
- return false;
+ return CanReadICOOrCUR(&stream, 1 /*for identifying an icon*/);
- // hdr[2] is one for an icon and two for a cursor
- return hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\1' && hdr[3] == '\0';
}
#endif // wxUSE_STREAMS
bool wxCURHandler::DoCanRead(wxInputStream& stream)
{
- unsigned char hdr[4];
- if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) // it's ok to modify the stream position here
- return false;
-
- // hdr[2] is one for an icon and two for a cursor
- return hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\2' && hdr[3] == '\0';
+ return CanReadICOOrCUR(&stream, 2 /*for identifying a cursor*/);
}
#endif // wxUSE_STREAMS
return decoder.GetFrameCount();
}
+static bool CanReadICOOrCUR(wxInputStream *stream, wxUint16 resourceType)
+{
+ ICONDIR iconDir;
+ if ( !stream->Read(&iconDir, sizeof(iconDir)) ) // it's ok to modify the stream position here
+ {
+ return false;
+ }
+
+ return !iconDir.idReserved // reserved, must be 0
+ && wxUINT16_SWAP_ON_BE(iconDir.idType) == resourceType // either 1 or 2
+ && iconDir.idCount; // must contain at least one image
+}
+
#endif // wxUSE_STREAMS
#endif // wxUSE_ICO_CUR