From 74d63c5511dc70593421b9262b077e85bcf868cc Mon Sep 17 00:00:00 2001 From: "vladimir%pobox.com" Date: Tue, 21 Feb 2006 23:19:20 +0000 Subject: [PATCH] b=327580, fix image decoder endianness & pixel format bits [mainly cairo], r=stuart git-svn-id: svn://10.0.0.236/trunk@190765 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/src/thebes/nsThebesImage.cpp | 29 +++++++------------ .../libpr0n/decoders/bmp/nsBMPDecoder.h | 6 ++-- .../libpr0n/decoders/bmp/nsICODecoder.cpp | 4 +-- .../libpr0n/decoders/gif/imgContainerGIF.cpp | 2 +- .../libpr0n/decoders/gif/nsGIFDecoder2.cpp | 12 ++++---- .../libpr0n/decoders/jpeg/nsJPEGDecoder.cpp | 8 ++--- .../libpr0n/decoders/png/nsPNGDecoder.cpp | 12 ++++---- 7 files changed, 32 insertions(+), 41 deletions(-) diff --git a/mozilla/gfx/src/thebes/nsThebesImage.cpp b/mozilla/gfx/src/thebes/nsThebesImage.cpp index 260a662f5a3..0704c64c24e 100644 --- a/mozilla/gfx/src/thebes/nsThebesImage.cpp +++ b/mozilla/gfx/src/thebes/nsThebesImage.cpp @@ -551,7 +551,7 @@ nsThebesImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt3 dst->Scale(double(aDWidth)/mWidth, double(aDHeight)/mHeight); dst->SetSource(ThebesSurface()); - dst->Fill(); + dst->Paint(); return NS_OK; } @@ -563,10 +563,17 @@ static PRUint8 Unpremultiply(PRUint8 aVal, PRUint8 aAlpha) { } static void ARGBToThreeChannel(PRUint32* aARGB, PRUint8* aData) { +#ifdef IS_LITTLE_ENDIAN PRUint8 a = (PRUint8)(*aARGB >> 24); PRUint8 r = (PRUint8)(*aARGB >> 16); PRUint8 g = (PRUint8)(*aARGB >> 8); PRUint8 b = (PRUint8)(*aARGB >> 0); +#else + PRUint8 a = (PRUint8)(*aARGB >> 0); + PRUint8 r = (PRUint8)(*aARGB >> 8); + PRUint8 g = (PRUint8)(*aARGB >> 16); + PRUint8 b = (PRUint8)(*aARGB >> 24); +#endif if (a != 0xFF) { if (a == 0) { @@ -580,17 +587,8 @@ static void ARGBToThreeChannel(PRUint32* aARGB, PRUint8* aData) { } } -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) - // BGR format; assume little-endian system -#ifndef IS_LITTLE_ENDIAN -#error Strange big-endian/OS combination -#endif - // BGR, blue byte first - aData[0] = b; aData[1] = g; aData[2] = r; -#else // RGB, red byte first aData[0] = r; aData[1] = g; aData[2] = b; -#endif } static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha) { @@ -601,17 +599,8 @@ static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha) { static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha) { PRUint8 r, g, b; -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) - // BGR format; assume little-endian system -#ifndef IS_LITTLE_ENDIAN -#error Strange big-endian/OS combination -#endif - // BGR, blue byte first - b = aData[0]; g = aData[1]; r = aData[2]; -#else // RGB, red byte first r = aData[0]; g = aData[1]; b = aData[2]; -#endif if (aAlpha != 0xFF) { if (aAlpha == 0) { r = 0; @@ -623,5 +612,7 @@ static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha) { b = Premultiply(b, aAlpha); } } + + // Output is always ARGB with A in the high byte of a dword return (aAlpha << 24) | (r << 16) | (g << 8) | b; } diff --git a/mozilla/modules/libpr0n/decoders/bmp/nsBMPDecoder.h b/mozilla/modules/libpr0n/decoders/bmp/nsBMPDecoder.h index 238c6cf496e..302af66f923 100644 --- a/mozilla/modules/libpr0n/decoders/bmp/nsBMPDecoder.h +++ b/mozilla/modules/libpr0n/decoders/bmp/nsBMPDecoder.h @@ -116,7 +116,7 @@ struct bitFields { #define LITTLE_TO_NATIVE32(x) x #endif -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) #define BMP_GFXFORMAT gfxIFormats::BGR #define RLE_GFXFORMAT_ALPHA gfxIFormats::BGR_A1 #else @@ -125,7 +125,7 @@ struct bitFields { #define RLE_GFXFORMAT_ALPHA gfxIFormats::RGB_A1 #endif -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) #define GFXBYTESPERPIXEL 4 #else #define GFXBYTESPERPIXEL 3 @@ -232,7 +232,7 @@ private: * The variable passed in as aDecoded will be moved on 3 bytes! */ inline void SetPixel(PRUint8*& aDecoded, PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue) { -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) *aDecoded++ = 0; // Mac needs this padding byte #endif #ifdef USE_RGB diff --git a/mozilla/modules/libpr0n/decoders/bmp/nsICODecoder.cpp b/mozilla/modules/libpr0n/decoders/bmp/nsICODecoder.cpp index 0d0d30285ac..9fc8750205e 100644 --- a/mozilla/modules/libpr0n/decoders/bmp/nsICODecoder.cpp +++ b/mozilla/modules/libpr0n/decoders/bmp/nsICODecoder.cpp @@ -73,7 +73,7 @@ nsresult nsICODecoder::SetImageData() // 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(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) PRUint32 decodedLineLen = mDirEntry.mWidth * 4; #else PRUint32 decodedLineLen = mDirEntry.mWidth * 3; @@ -400,7 +400,7 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) { if (mPos == (mImageOffset + BITMAPINFOSIZE + mNumColors*4)) { // Increment mPos to avoid reprocessing the info header. mPos++; -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) mDecodedBuffer = (PRUint8*)malloc(mDirEntry.mHeight*mDirEntry.mWidth*4); #else mDecodedBuffer = (PRUint8*)malloc(mDirEntry.mHeight*mDirEntry.mWidth*3); diff --git a/mozilla/modules/libpr0n/decoders/gif/imgContainerGIF.cpp b/mozilla/modules/libpr0n/decoders/gif/imgContainerGIF.cpp index e5327dc87d1..332529c3206 100644 --- a/mozilla/modules/libpr0n/decoders/gif/imgContainerGIF.cpp +++ b/mozilla/modules/libpr0n/decoders/gif/imgContainerGIF.cpp @@ -994,7 +994,7 @@ void imgContainerGIF::BlackenFrame(gfxIImageFrame *aFrame, PRUint32 bpr; // Bytes Per Row aFrame->GetImageBytesPerRow(&bpr); -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) const PRUint8 bpp = 4; #else const PRUint8 bpp = 3; diff --git a/mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp b/mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp index ecb959cce63..02fbfd9d289 100644 --- a/mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp +++ b/mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp @@ -424,7 +424,7 @@ int nsGIFDecoder2::HaveDecodedRow( format = gfxIFormats::RGB_A1; } -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_ENABLE_CAIRO) || (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) // XXX this works... format += 1; // RGB to BGR #endif @@ -509,12 +509,12 @@ int nsGIFDecoder2::HaveDecodedRow( case gfxIFormats::BGR: { while (rowBufIndex != decoder->mGIFStruct->rowend) { -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) *rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad #endif if (*rowBufIndex < cmapsize) { PRUint32 colorIndex = *rowBufIndex * 3; -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) *rgbRowIndex++ = cmap[colorIndex + 2]; // blue *rgbRowIndex++ = cmap[colorIndex + 1]; // green *rgbRowIndex++ = cmap[colorIndex]; // red @@ -543,12 +543,12 @@ int nsGIFDecoder2::HaveDecodedRow( memset(decoder->mAlphaLine, 0, abpr); for (PRUint32 x = 0; x < (PRUint32)width; ++x) { if (*rowBufIndex != decoder->mGIFStruct->tpixel) { -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) *rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad #endif if (*rowBufIndex < cmapsize) { PRUint32 colorIndex = *rowBufIndex * 3; -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) *rgbRowIndex++ = cmap[colorIndex + 2]; // blue *rgbRowIndex++ = cmap[colorIndex + 1]; // green *rgbRowIndex++ = cmap[colorIndex]; // red @@ -564,7 +564,7 @@ int nsGIFDecoder2::HaveDecodedRow( } decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7); } else { -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) rgbRowIndex+=4; #else rgbRowIndex+=3; diff --git a/mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp b/mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp index e7a1532b7e0..bbacf976e53 100644 --- a/mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +++ b/mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp @@ -353,7 +353,7 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR // Note! row_stride here must match the row_stride in // nsJPEGDecoder::OutputScanlines -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) row_stride = mInfo.output_width * 4; #else row_stride = mInfo.output_width * 3; @@ -517,7 +517,7 @@ nsJPEGDecoder::OutputScanlines() break; } -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) PRUint8 *ptrOutputBuf = mRGBRow; JSAMPLE *j1 = mSamples[0]; @@ -529,7 +529,7 @@ nsJPEGDecoder::OutputScanlines() } samples = mRGBRow; -#elif defined(XP_MAC) || defined(XP_MACOSX) +#elif !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) PRUint8 *ptrOutputBuf = mRGBRow; JSAMPLE *j1 = mSamples[0]; @@ -548,7 +548,7 @@ nsJPEGDecoder::OutputScanlines() // Note! row_stride here must match the row_stride in // nsJPEGDecoder::WriteFrom -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) int row_stride = mInfo.output_width * 4; #else int row_stride = mInfo.output_width * 3; diff --git a/mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp b/mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp index 7c783bea33a..c0690d1d676 100644 --- a/mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp +++ b/mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp @@ -250,7 +250,7 @@ info_callback(png_structp png_ptr, png_infop info_ptr) png_set_gray_to_rgb(png_ptr); -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) // windows likes BGR png_set_bgr(png_ptr); #endif @@ -333,7 +333,7 @@ info_callback(png_structp png_ptr, png_infop info_ptr) } } -#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)) // XXX this works... format += 1; // RGB to BGR #endif @@ -435,7 +435,7 @@ row_callback(png_structp png_ptr, png_bytep new_row, switch (format) { case gfxIFormats::RGB: case gfxIFormats::BGR: -#if defined(XP_MAC) || defined(XP_MACOSX) +#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX)) cptr = decoder->colorLine; for (PRUint32 x=0; xalphaLine; memset(aptr, 0, abpr); for (PRUint32 x=0; xcolorLine; aptr = decoder->alphaLine; for (PRUint32 x=0; xcolorLine; aptr = decoder->alphaLine;