mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1062066 (Part 3) - Only mark BMP surfaces as transparent if they actually have alpha data. r=tn
This commit is contained in:
parent
1d9c6c1973
commit
4010153517
@ -122,15 +122,6 @@ nsBMPDecoder::GetCompressedImageSize() const
|
||||
return pixelArraySize;
|
||||
}
|
||||
|
||||
// Obtains whether or not a BMP file had alpha data in its 4th byte
|
||||
// for 32BPP bitmaps. Only use after the bitmap has been processed.
|
||||
bool
|
||||
nsBMPDecoder::HasAlphaData() const
|
||||
{
|
||||
return mHaveAlphaData;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsBMPDecoder::FinishInternal()
|
||||
{
|
||||
@ -147,7 +138,7 @@ nsBMPDecoder::FinishInternal()
|
||||
nsIntRect r(0, 0, mBIH.width, GetHeight());
|
||||
PostInvalidation(r);
|
||||
|
||||
if (mUseAlphaData) {
|
||||
if (mUseAlphaData && mHaveAlphaData) {
|
||||
PostFrameStop(Opacity::SOME_TRANSPARENCY);
|
||||
} else {
|
||||
PostFrameStop(Opacity::OPAQUE);
|
||||
@ -664,28 +655,11 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
case 32:
|
||||
while (lpos > 0) {
|
||||
if (mUseAlphaData) {
|
||||
if (!mHaveAlphaData && p[3]) {
|
||||
// Non-zero alpha byte detected! Clear previous
|
||||
// pixels that we have already processed.
|
||||
// This works because we know that if we
|
||||
// are reaching here then the alpha data in byte
|
||||
// 4 has been right all along. And we know it
|
||||
// has been set to 0 the whole time, so that
|
||||
// means that everything is transparent so far.
|
||||
uint32_t* start = reinterpret_cast<uint32_t*>
|
||||
(mImageData) + GetWidth() *
|
||||
(mCurLine - 1);
|
||||
uint32_t heightDifference = GetHeight() -
|
||||
mCurLine + 1;
|
||||
uint32_t pixelCount = GetWidth() *
|
||||
heightDifference;
|
||||
|
||||
memset(start, 0, pixelCount * sizeof(uint32_t));
|
||||
|
||||
if (MOZ_UNLIKELY(!mHaveAlphaData && p[3])) {
|
||||
PostHasTransparency();
|
||||
mHaveAlphaData = true;
|
||||
}
|
||||
SetPixel(d, p[2], p[1], p[0], mHaveAlphaData ? p[3] : 0xFF);
|
||||
SetPixel(d, p[2], p[1], p[0], p[3]);
|
||||
} else {
|
||||
SetPixel(d, p[2], p[1], p[0]);
|
||||
}
|
||||
|
@ -46,7 +46,10 @@ public:
|
||||
|
||||
// Obtains whether or not a BMP file had alpha data in its 4th byte
|
||||
// for 32BPP bitmaps. Only use after the bitmap has been processed.
|
||||
bool HasAlphaData() const;
|
||||
bool HasAlphaData() const { return mHaveAlphaData; }
|
||||
|
||||
/// Marks this BMP as having alpha data (due to e.g. an ICO alpha mask).
|
||||
void SetHasAlphaData() { mHaveAlphaData = true; }
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer,
|
||||
uint32_t aCount) override;
|
||||
|
@ -532,14 +532,14 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// If the bitmap is fully processed, treat any left over data as the ICO's
|
||||
// 'AND buffer mask' which appears after the bitmap resource.
|
||||
if (!mIsPNG && mPos >= bmpDataEnd) {
|
||||
nsRefPtr<nsBMPDecoder> bmpDecoder =
|
||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get());
|
||||
|
||||
// There may be an optional AND bit mask after the data. This is
|
||||
// only used if the alpha data is not already set. The alpha data
|
||||
// is used for 32bpp bitmaps as per the comment in ICODecoder.h
|
||||
// The alpha mask should be checked in all other cases.
|
||||
if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
GetBitsPerPixel() != 32 ||
|
||||
!static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
HasAlphaData()) {
|
||||
if (bmpDecoder->GetBitsPerPixel() != 32 || !bmpDecoder->HasAlphaData()) {
|
||||
uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
|
||||
if (mPos == bmpDataEnd) {
|
||||
mPos++;
|
||||
@ -573,9 +573,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
mCurLine--;
|
||||
mRowBytes = 0;
|
||||
|
||||
uint32_t* imageData =
|
||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
GetImageData();
|
||||
uint32_t* imageData = bmpDecoder->GetImageData();
|
||||
if (!imageData) {
|
||||
PostDataError();
|
||||
return;
|
||||
@ -601,7 +599,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// If any bits are set in sawTransparency, then we know at least one
|
||||
// pixel was transparent.
|
||||
if (sawTransparency) {
|
||||
PostHasTransparency();
|
||||
PostHasTransparency();
|
||||
bmpDecoder->SetHasAlphaData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user