fix bug 367275 - download manager file folder icon is black
(regression from 360000) Only do premultiplication when the 32bit ico really has alpha - move premultiplication to SetImageData from SetPixel and only premultiply if mHaveAlpha is true. The 'premultiplication' function has been copied from libpixman. r=pavlov git-svn-id: svn://10.0.0.236/trunk@218888 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
050a755a27
commit
839e716f61
@ -233,16 +233,6 @@ private:
|
||||
inline void SetPixel(PRUint8*& aDecoded, PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue, PRUint8 aAlpha = 0xFF)
|
||||
{
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
// This is not skipping for pixels where aAlpha happen to be 0xFF
|
||||
// This will also make the compiler skip this part completely when
|
||||
// inlining SetPixel when aAlpha is not specified
|
||||
if (aAlpha != 0xFF) {
|
||||
#define DO_PREMULTIPLY(c_) ((PRUint16(c_) * PRUint16(aAlpha) + 127) / 255)
|
||||
aBlue = DO_PREMULTIPLY(aBlue);
|
||||
aGreen = DO_PREMULTIPLY(aGreen);
|
||||
aRed = DO_PREMULTIPLY(aRed);
|
||||
#undef DO_PREMULTIPLY
|
||||
}
|
||||
*(PRUint32*)aDecoded = (aAlpha << 24) | (aRed << 16) | (aGreen << 8) | aBlue;
|
||||
aDecoded += 4;
|
||||
#else // MOZ_CAIRO_GFX
|
||||
|
||||
@ -66,14 +66,43 @@ NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
|
||||
// Actual Data Processing
|
||||
// ----------------------------------------
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
static PRUint32 premultiply(PRUint32 x)
|
||||
{
|
||||
PRUint32 a = x >> 24;
|
||||
PRUint32 t = (x & 0xff00ff) * a + 0x800080;
|
||||
t = (t + ((t >> 8) & 0xff00ff)) >> 8;
|
||||
t &= 0xff00ff;
|
||||
|
||||
x = ((x >> 8) & 0xff) * a + 0x80;
|
||||
x = (x + ((x >> 8) & 0xff));
|
||||
x &= 0xff00;
|
||||
x |= t | (a << 24);
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult nsICODecoder::SetImageData()
|
||||
{
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
if (mHaveAlphaData) {
|
||||
// We have premultiply the pixels when we have alpha transparency
|
||||
PRUint32* p = (PRUint32*)mDecodedBuffer;
|
||||
for (PRUint32 c = mDirEntry.mWidth * mDirEntry.mHeight; c > 0; --c) {
|
||||
*p = premultiply(*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
// In Cairo we can set the whole image in one go
|
||||
PRUint32 dataLen = mDirEntry.mHeight * mDirEntry.mWidth * 4;
|
||||
mFrame->SetImageData(mDecodedBuffer, dataLen, 0);
|
||||
#else
|
||||
PRUint32 bpr;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
|
||||
// Since the ICO is decoded into an exact sized array, the frame may use
|
||||
// more bytes per row of pixels than the decoding array.
|
||||
#if defined(MOZ_CAIRO_GFX) || defined(XP_MAC) || defined(XP_MACOSX)
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
PRUint32 decodedLineLen = mDirEntry.mWidth * 4;
|
||||
#else
|
||||
PRUint32 decodedLineLen = mDirEntry.mWidth * 3;
|
||||
@ -87,6 +116,7 @@ nsresult nsICODecoder::SetImageData()
|
||||
++i, frameOffset += bpr, decodeBufferPos += decodedLineLen) {
|
||||
mFrame->SetImageData(decodeBufferPos, decodedLineLen, frameOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsIntRect r(0, 0, 0, 0);
|
||||
mFrame->GetWidth(&r.width);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user