зеркало из https://github.com/mozilla/gecko-dev.git
bug 198293 r=tor sr=scott@scott-macgregor.org support ICOs with alpha channel
This commit is contained in:
Родитель
50b3c7b9a4
Коммит
7def17cf52
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* David Hyatt <hyatt@netscape.com> (Original Author)
|
* David Hyatt <hyatt@netscape.com> (Original Author)
|
||||||
|
* Christian Biesinger <cbiesinger@web.de>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -47,6 +48,8 @@
|
||||||
|
|
||||||
#include "imgILoad.h"
|
#include "imgILoad.h"
|
||||||
|
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
|
NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
|
||||||
|
|
||||||
#define ICONCOUNTOFFSET 4
|
#define ICONCOUNTOFFSET 4
|
||||||
|
@ -90,6 +93,10 @@ nsresult nsICODecoder::SetImageData()
|
||||||
|
|
||||||
nsresult nsICODecoder::SetAlphaData()
|
nsresult nsICODecoder::SetAlphaData()
|
||||||
{
|
{
|
||||||
|
// Alpha data was already set if bpp == 32
|
||||||
|
if (mBIH.bpp == 32)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
PRUint32 bpr;
|
PRUint32 bpr;
|
||||||
mFrame->GetAlphaBytesPerRow(&bpr);
|
mFrame->GetAlphaBytesPerRow(&bpr);
|
||||||
|
|
||||||
|
@ -303,7 +310,10 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
if (!mRow)
|
if (!mRow)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA, 24);
|
if (mBIH.bpp == 32)
|
||||||
|
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA8, 24);
|
||||||
|
else
|
||||||
|
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA, 24);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mImage->AppendFrame(mFrame);
|
rv = mImage->AppendFrame(mFrame);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -338,8 +348,8 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDecodingAndMask && (mPos >= (mImageOffset + BITMAPINFOSIZE + mNumColors*4))) {
|
if (!mDecodingAndMask && (mPos >= (mImageOffset + BITMAPINFOSIZE + mNumColors*4))) {
|
||||||
// Increment mPos to avoid reprocessing the info header.
|
|
||||||
if (mPos == (mImageOffset + BITMAPINFOSIZE + mNumColors*4)) {
|
if (mPos == (mImageOffset + BITMAPINFOSIZE + mNumColors*4)) {
|
||||||
|
// Increment mPos to avoid reprocessing the info header.
|
||||||
mPos++;
|
mPos++;
|
||||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||||
mDecodedBuffer = new PRUint8[mDirEntry.mHeight*mDirEntry.mWidth*4];
|
mDecodedBuffer = new PRUint8[mDirEntry.mHeight*mDirEntry.mWidth*4];
|
||||||
|
@ -349,6 +359,14 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
if (!mDecodedBuffer)
|
if (!mDecodedBuffer)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
PRUint32 alphaRowSize;
|
||||||
|
mFrame->GetAlphaBytesPerRow(&alphaRowSize);
|
||||||
|
nsAutoArrayPtr<PRUint8> alphaRow; // Will only be used if bpp == 32
|
||||||
|
if (mBIH.bpp == 32) {
|
||||||
|
alphaRow = new PRUint8[alphaRowSize];
|
||||||
|
if (!alphaRow)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
PRUint32 rowSize = (mBIH.bpp * mDirEntry.mWidth + 7) / 8; // +7 to round up
|
PRUint32 rowSize = (mBIH.bpp * mDirEntry.mWidth + 7) / 8; // +7 to round up
|
||||||
if (rowSize % 4)
|
if (rowSize % 4)
|
||||||
|
@ -369,6 +387,7 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
PRUint8* decoded = mDecodedBuffer + (mCurLine * mDirEntry.mWidth * GFXBYTESPERPIXEL);
|
PRUint8* decoded = mDecodedBuffer + (mCurLine * mDirEntry.mWidth * GFXBYTESPERPIXEL);
|
||||||
PRUint8* p = mRow;
|
PRUint8* p = mRow;
|
||||||
PRUint8* d = decoded;
|
PRUint8* d = decoded;
|
||||||
|
PRUint8* alphaPos = alphaRow; // only used if bpp == 32
|
||||||
PRUint32 lpos = mDirEntry.mWidth;
|
PRUint32 lpos = mDirEntry.mWidth;
|
||||||
switch (mBIH.bpp) {
|
switch (mBIH.bpp) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -411,11 +430,10 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
case 24:
|
case 24:
|
||||||
while (lpos > 0) {
|
while (lpos > 0) {
|
||||||
SetPixel(d, p[2], p[1], p[0]);
|
SetPixel(d, p[2], p[1], p[0]);
|
||||||
p += 2;
|
p += 3;
|
||||||
--lpos;
|
--lpos;
|
||||||
if (mBIH.bpp == 32)
|
if (mBIH.bpp == 32)
|
||||||
p++; // Padding byte
|
*alphaPos++ = *p++; // Alpha value
|
||||||
++p;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -427,11 +445,16 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||||
mDecodingAndMask = PR_TRUE;
|
mDecodingAndMask = PR_TRUE;
|
||||||
|
|
||||||
mRowBytes = 0;
|
mRowBytes = 0;
|
||||||
|
|
||||||
|
// If 32 bit image, gotta set the alpha data here
|
||||||
|
if (mBIH.bpp == 32)
|
||||||
|
mFrame->SetAlphaData(alphaRow, alphaRowSize, mCurLine * alphaRowSize);
|
||||||
}
|
}
|
||||||
} while (!mDecodingAndMask && aCount > 0);
|
} while (!mDecodingAndMask && aCount > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDecodingAndMask) {
|
if (mDecodingAndMask && mBIH.bpp != 32) {
|
||||||
PRUint32 rowSize = CalcAlphaRowSize();
|
PRUint32 rowSize = CalcAlphaRowSize();
|
||||||
|
|
||||||
if (mPos == (1 + mImageOffset + BITMAPINFOSIZE + mNumColors*4)) {
|
if (mPos == (1 + mImageOffset + BITMAPINFOSIZE + mNumColors*4)) {
|
||||||
|
|
|
@ -53,9 +53,11 @@
|
||||||
|
|
||||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||||
#define GFXFORMATALPHA gfxIFormats::BGR_A1
|
#define GFXFORMATALPHA gfxIFormats::BGR_A1
|
||||||
|
#define GFXFORMATALPHA8 gfxIFormats::BGR_A8
|
||||||
#else
|
#else
|
||||||
#define USE_RGBA1
|
#define USE_RGBA1
|
||||||
#define GFXFORMATALPHA gfxIFormats::RGB_A1
|
#define GFXFORMATALPHA gfxIFormats::RGB_A1
|
||||||
|
#define GFXFORMATALPHA8 gfxIFormats::RGB_A8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct IconDirEntry
|
struct IconDirEntry
|
||||||
|
|
Загрузка…
Ссылка в новой задаче