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:
asqueella%gmail.com 2007-01-25 11:39:48 +00:00
parent 050a755a27
commit 839e716f61
2 changed files with 31 additions and 11 deletions

View File

@ -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

View File

@ -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);