X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/03647350fc7cd141953c72e0284e928847d30f44..2e49a8074e7c9179b642852ff00ed8fdf0768bb1:/src/common/imagbmp.cpp?ds=inline diff --git a/src/common/imagbmp.cpp b/src/common/imagbmp.cpp index 3e7a128d10..bc6f47c858 100644 --- a/src/common/imagbmp.cpp +++ b/src/common/imagbmp.cpp @@ -39,6 +39,16 @@ // For memcpy #include +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +#if wxUSE_ICO_CUR + +static bool CanReadICOOrCUR(wxInputStream *stream, wxUint16 resourceType); + +#endif // wxUSE_ICO_CUR + //----------------------------------------------------------------------------- // wxBMPHandler //----------------------------------------------------------------------------- @@ -684,6 +694,14 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, 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-- ) { @@ -895,6 +913,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { temp = (unsigned char)((aDword & amask) >> ashift); alpha[line * width + column] = temp; + + if ( temp != wxALPHA_TRANSPARENT ) + hasValidAlpha = true; } column++; } @@ -910,6 +931,13 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, 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; } @@ -1406,12 +1434,8 @@ int wxICOHandler::DoGetImageCount(wxInputStream& stream) 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 @@ -1427,12 +1451,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxCURHandler, wxICOHandler) 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 @@ -1471,6 +1490,19 @@ int wxANIHandler::DoGetImageCount(wxInputStream& stream) 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