bug 198293 r=tor sr=scott@scott-macgregor.org support ICOs with alpha channel

This commit is contained in:
cbiesinger%web.de 2003-07-23 18:39:11 +00:00
Родитель 50b3c7b9a4
Коммит 7def17cf52
2 изменённых файлов: 31 добавлений и 6 удалений

Просмотреть файл

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