X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9a83f860948059b0273b5cc6d9e43fadad3ebfca..bc9666c99939f6f1a6fc11fd10fa2db3deb747ae:/src/common/imagbmp.cpp diff --git a/src/common/imagbmp.cpp b/src/common/imagbmp.cpp index bf232cd51a..41edf784b4 100644 --- a/src/common/imagbmp.cpp +++ b/src/common/imagbmp.cpp @@ -599,7 +599,7 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { if ( comp == BI_BITFIELDS ) { - int bit = 0; + int bit; stream.Read(dbuf, 4 * 3); rmask = wxINT32_SWAP_ON_BE(dbuf[0]); gmask = wxINT32_SWAP_ON_BE(dbuf[1]); @@ -661,8 +661,10 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { // NOTE: seeking a positive amount in wxFromCurrent mode allows us to // load even non-seekable streams (see wxInputStream::SeekI docs)! - if (stream.SeekI(bmpOffset, wxFromCurrent) == wxInvalidOffset) - return false; + const wxFileOffset pos = stream.TellI(); + if (pos != wxInvalidOffset && bmpOffset > pos) + if (stream.SeekI(bmpOffset - pos, wxFromCurrent) == wxInvalidOffset) + return false; //else: icon, just carry on } @@ -682,6 +684,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-- ) { @@ -776,7 +786,7 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { for (int nibble = 0; nibble < 2 && column < width; nibble++) { - int index = ((aByte & (0xF0 >> nibble * 4)) >> (!nibble * 4)); + int index = ((aByte & (0xF0 >> (nibble * 4))) >> (!nibble * 4)); if ( index >= 16 ) index = 15; ptr[poffset] = cmap[index].r; @@ -865,15 +875,15 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, stream.Read(&aWord, 2); aWord = wxUINT16_SWAP_ON_BE(aWord); linepos += 2; - /* use the masks and calculated amonut of shift + /* Use the masks and calculated amount of shift to retrieve the color data out of the word. Then shift it left by (8 - number of bits) such that the image has the proper dynamic range */ - temp = (unsigned char)((aWord & rmask) >> rshift << (8-rbits)); + temp = (unsigned char)(((aWord & rmask) >> rshift) << (8-rbits)); ptr[poffset] = temp; - temp = (unsigned char)((aWord & gmask) >> gshift << (8-gbits)); + temp = (unsigned char)(((aWord & gmask) >> gshift) << (8-gbits)); ptr[poffset + 1] = temp; - temp = (unsigned char)((aWord & bmask) >> bshift << (8-bbits)); + temp = (unsigned char)(((aWord & bmask) >> bshift) << (8-bbits)); ptr[poffset + 2] = temp; column++; } @@ -893,6 +903,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++; } @@ -908,6 +921,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; } @@ -1318,7 +1338,7 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream, 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); @@ -1331,11 +1351,11 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream, // 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 ) { @@ -1349,7 +1369,7 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream, colmax = pCurrentEntry->bColorCount; } } - + pCurrentEntry++; } @@ -1369,13 +1389,13 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream, { // 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 ) @@ -1385,9 +1405,9 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream, image->SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, wxUINT16_SWAP_ON_BE(pCurrentEntry->wBitCount)); } } - + delete [] pIconDirEntry; - + return bResult; } @@ -1398,7 +1418,7 @@ int wxICOHandler::DoGetImageCount(wxInputStream& stream) 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); }