зеркало из https://github.com/mozilla/pjs.git
speed up image drawing by decoding directly in to 32bpp buffers. bug 331298. r=vlad
This commit is contained in:
Родитель
fb365662e6
Коммит
44f55dc046
|
@ -42,6 +42,10 @@
|
|||
#include "nsIRenderingContext.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
class gfxASurface;
|
||||
#endif
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
struct nsColorMap
|
||||
|
@ -279,6 +283,10 @@ public:
|
|||
* @return error result
|
||||
*/
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels) = 0;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIImage, NS_IIMAGE_IID)
|
||||
|
|
|
@ -59,19 +59,12 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static PRUint8 Unpremultiply(PRUint8 aVal, PRUint8 aAlpha);
|
||||
static void ARGBToThreeChannel(PRUint32* aARGB, PRUint8* aData);
|
||||
static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha);
|
||||
static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha);
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesImage, nsIImage)
|
||||
|
||||
nsThebesImage::nsThebesImage()
|
||||
: mWidth(0),
|
||||
mHeight(0),
|
||||
mDecoded(0,0,0,0),
|
||||
mLockedData(nsnull),
|
||||
mLockedAlpha(nsnull),
|
||||
mAlphaDepth(0),
|
||||
mLocked(PR_FALSE),
|
||||
mHadAnyData(PR_FALSE),
|
||||
|
@ -82,57 +75,42 @@ nsThebesImage::nsThebesImage()
|
|||
nsresult
|
||||
nsThebesImage::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
NS_ASSERTION(aDepth == 24, "nsThebesImage::Init called with depth != 24");
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
switch(aMaskRequirements)
|
||||
{
|
||||
case nsMaskRequirements_kNeeds1Bit:
|
||||
format = gfxImageSurface::gfxImageFormat::ImageFormatARGB32;
|
||||
mAlphaDepth = 1;
|
||||
break;
|
||||
case nsMaskRequirements_kNeeds8Bit:
|
||||
format = gfxImageSurface::gfxImageFormat::ImageFormatARGB32;
|
||||
mAlphaDepth = 8;
|
||||
break;
|
||||
default:
|
||||
format = gfxImageSurface::gfxImageFormat::ImageFormatRGB24;
|
||||
mAlphaDepth = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mImageSurface = new gfxImageSurface(format, mWidth, mHeight);
|
||||
memset(mImageSurface->Data(), 0, mHeight * mImageSurface->Stride());
|
||||
|
||||
mStride = mImageSurface->Stride();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::EnsureImageSurface()
|
||||
{
|
||||
if (!mImageSurface) {
|
||||
// always read images as ARGB32
|
||||
mImageSurface = new gfxImageSurface (gfxImageSurface::ImageFormatARGB32, mWidth, mHeight);
|
||||
memset(mImageSurface->Data(), 0xFF, mHeight * mImageSurface->Stride());
|
||||
|
||||
if (mOptSurface) {
|
||||
nsRefPtr<gfxContext> tmpCtx(new gfxContext(mImageSurface));
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->SetSource(mOptSurface);
|
||||
tmpCtx->Paint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsThebesImage::~nsThebesImage()
|
||||
{
|
||||
if (mLockedData)
|
||||
nsMemory::Free(mLockedData);
|
||||
if (mLockedAlpha)
|
||||
nsMemory::Free(mLockedAlpha);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetBytesPix()
|
||||
{
|
||||
// not including alpha
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -156,14 +134,15 @@ nsThebesImage::GetHeight()
|
|||
PRUint8 *
|
||||
nsThebesImage::GetBits()
|
||||
{
|
||||
//NS_ASSERTION(mLocked == PR_TRUE, "GetBits called outside of Lock!");
|
||||
return mLockedData;
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Data();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetLineStride()
|
||||
{
|
||||
return mWidth * 3;
|
||||
return mStride;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -175,14 +154,13 @@ nsThebesImage::GetHasAlphaMask()
|
|||
PRUint8 *
|
||||
nsThebesImage::GetAlphaBits()
|
||||
{
|
||||
//NS_ASSERTION(mLocked == PR_TRUE, "GetAlphaBits called outside of Lock!");
|
||||
return (PRUint8 *) mLockedAlpha;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetAlphaLineStride()
|
||||
{
|
||||
return mAlphaDepth == 1 ? (mWidth+7)/8 : mWidth;
|
||||
return mStride;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -200,28 +178,12 @@ nsThebesImage::GetIsImageComplete()
|
|||
nsresult
|
||||
nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
EnsureImageSurface();
|
||||
if (mOptSurface)
|
||||
return NS_OK;
|
||||
|
||||
if (!mOptSurface) {
|
||||
gfxASurface::gfxImageFormat real_format;
|
||||
|
||||
if (mRealAlphaDepth == 0)
|
||||
real_format = gfxASurface::ImageFormatRGB24;
|
||||
else
|
||||
real_format = gfxASurface::ImageFormatARGB32;
|
||||
|
||||
mOptSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(mWidth, mHeight, real_format);
|
||||
}
|
||||
|
||||
if (mOptSurface) {
|
||||
nsRefPtr<gfxContext> tmpCtx(new gfxContext(mOptSurface));
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->SetSource(mImageSurface);
|
||||
tmpCtx->Paint();
|
||||
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface);
|
||||
|
||||
mImageSurface = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -247,173 +209,19 @@ nsThebesImage::GetBitInfo()
|
|||
NS_IMETHODIMP
|
||||
nsThebesImage::LockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
//NS_ASSERTION(!mLocked, "LockImagePixels called on already locked image!");
|
||||
PRUint32 tmpSize;
|
||||
|
||||
// if we already have locked data allocated,
|
||||
// and we have some data, and we're not up to date,
|
||||
// then don't bother updating frmo the image surface
|
||||
// to the 2 buffers -- the 2 buffers are more current,
|
||||
// because UpdateFromLockedData() hasn't been called yet.
|
||||
//
|
||||
// UpdateFromLockedData() is only called right before we
|
||||
// actually try to draw, because the image decoders
|
||||
// will call Lock/Unlock pretty frequently as they decode
|
||||
// rows of the image.
|
||||
|
||||
if (mLockedData && mHadAnyData && !mUpToDate)
|
||||
return NS_OK;
|
||||
|
||||
EnsureImageSurface();
|
||||
|
||||
if (mAlphaDepth > 0) {
|
||||
NS_ASSERTION(mAlphaDepth == 1 || mAlphaDepth == 8,
|
||||
"Bad alpha depth");
|
||||
tmpSize = mHeight*(mAlphaDepth == 1 ? ((mWidth+7)/8) : mWidth);
|
||||
if (!mLockedAlpha)
|
||||
mLockedAlpha = (PRUint8*)nsMemory::Alloc(tmpSize);
|
||||
if (!mLockedAlpha)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
tmpSize = mWidth * mHeight * 3;
|
||||
if (!mLockedData)
|
||||
mLockedData = (PRUint8*)nsMemory::Alloc(tmpSize);
|
||||
if (!mLockedData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (mAlphaDepth > 0 && mHadAnyData) {
|
||||
// fill from existing ARGB buffer
|
||||
if (mAlphaDepth == 8) {
|
||||
PRInt32 destCount = 0;
|
||||
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
mLockedAlpha[destCount++] = (PRUint8)(srcRow[col] >> 24);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PRInt32 i = 0;
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
PRUint8 alphaBits = 0;
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
PRUint8 mask = 1 << (7 - (col&7));
|
||||
|
||||
if (srcRow[col] & 0xFF000000) {
|
||||
alphaBits |= mask;
|
||||
}
|
||||
if (mask == 0x01) {
|
||||
// This mask byte is complete, write it back
|
||||
mLockedAlpha[i] = alphaBits;
|
||||
alphaBits = 0;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (mWidth & 7) {
|
||||
// write back the incomplete alpha mask
|
||||
mLockedAlpha[i] = alphaBits;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mHadAnyData) {
|
||||
int destCount = 0;
|
||||
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
ARGBToThreeChannel(&srcRow[col], &mLockedData[destCount*3]);
|
||||
destCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLocked = PR_TRUE;
|
||||
|
||||
mOptSurface = nsnull;
|
||||
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
//NS_ASSERTION(mLocked, "UnlockImagePixels called on unlocked image!");
|
||||
|
||||
mLocked = PR_FALSE;
|
||||
mUpToDate = PR_FALSE;
|
||||
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::UpdateFromLockedData()
|
||||
{
|
||||
if (!mLockedData || mUpToDate)
|
||||
return;
|
||||
|
||||
mUpToDate = PR_TRUE;
|
||||
|
||||
NS_ASSERTION(mAlphaDepth == 0 || mAlphaDepth == 1 || mAlphaDepth == 8,
|
||||
"Bad alpha depth");
|
||||
|
||||
mRealAlphaDepth = 0;
|
||||
|
||||
PRInt32 alphaIndex = 0;
|
||||
PRInt32 lockedBufIndex = 0;
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32 *destPtr = (PRUint32*) (mImageSurface->Data() + (row * mImageSurface->Stride()));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
PRUint8 alpha = 0xFF;
|
||||
|
||||
if (mAlphaDepth == 1) {
|
||||
PRUint8 mask = 1 << (7 - (col&7));
|
||||
if (!(mLockedAlpha[alphaIndex] & mask)) {
|
||||
alpha = 0;
|
||||
}
|
||||
if (mask == 0x01) {
|
||||
++alphaIndex;
|
||||
}
|
||||
} else if (mAlphaDepth == 8) {
|
||||
alpha = mLockedAlpha[lockedBufIndex];
|
||||
}
|
||||
|
||||
if (mRealAlphaDepth == 0 && alpha != 0xff)
|
||||
mRealAlphaDepth = mAlphaDepth;
|
||||
|
||||
*destPtr++ =
|
||||
ThreeChannelToARGB(&mLockedData[lockedBufIndex*3], alpha);
|
||||
|
||||
++lockedBufIndex;
|
||||
}
|
||||
if (mAlphaDepth == 1) {
|
||||
if (mWidth & 7) {
|
||||
++alphaIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PR_FALSE) { // Enabling this saves memory but can lead to pathologically bad
|
||||
// performance. Would also cause problems with premultiply/unpremultiply too
|
||||
nsMemory::Free(mLockedData);
|
||||
mLockedData = nsnull;
|
||||
if (mLockedAlpha) {
|
||||
nsMemory::Free(mLockedAlpha);
|
||||
mLockedAlpha = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
mHadAnyData = PR_TRUE;
|
||||
}
|
||||
|
||||
/* NB: These are pixels, not twips. */
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
|
||||
|
@ -429,8 +237,6 @@ nsThebesImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
|
|||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesRenderingContext *thebesRC = NS_STATIC_CAST(nsThebesRenderingContext*, &aContext);
|
||||
gfxContext *ctx = thebesRC->Thebes();
|
||||
|
||||
|
@ -469,8 +275,6 @@ nsThebesImage::DrawTile(nsIRenderingContext &aContext,
|
|||
PRInt32 aPadX, PRInt32 aPadY,
|
||||
const nsRect &aTileRect)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesRenderingContext *thebesRC = NS_STATIC_CAST(nsThebesRenderingContext*, &aContext);
|
||||
gfxContext *ctx = thebesRC->Thebes();
|
||||
|
||||
|
@ -537,8 +341,6 @@ nsThebesImage::DrawTile(nsIRenderingContext &aContext,
|
|||
NS_IMETHODIMP
|
||||
nsThebesImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesImage *dstThebesImage = NS_STATIC_CAST(nsThebesImage*, aDstImage);
|
||||
|
||||
nsRefPtr<gfxContext> dst = new gfxContext(dstThebesImage->ThebesSurface());
|
||||
|
@ -557,63 +359,3 @@ nsThebesImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt3
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/** Image conversion utils **/
|
||||
|
||||
static PRUint8 Unpremultiply(PRUint8 aVal, PRUint8 aAlpha) {
|
||||
return (aVal*255)/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) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} else {
|
||||
r = Unpremultiply(r, a);
|
||||
g = Unpremultiply(g, a);
|
||||
b = Unpremultiply(b, a);
|
||||
}
|
||||
}
|
||||
|
||||
// RGB, red byte first
|
||||
aData[0] = r; aData[1] = g; aData[2] = b;
|
||||
}
|
||||
|
||||
static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha) {
|
||||
PRUint32 r;
|
||||
FAST_DIVIDE_BY_255(r, aVal*aAlpha);
|
||||
return (PRUint8)r;
|
||||
}
|
||||
|
||||
static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha) {
|
||||
PRUint8 r, g, b;
|
||||
// RGB, red byte first
|
||||
r = aData[0]; g = aData[1]; b = aData[2];
|
||||
if (aAlpha != 0xFF) {
|
||||
if (aAlpha == 0) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} else {
|
||||
r = Premultiply(r, aAlpha);
|
||||
g = Premultiply(g, 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;
|
||||
}
|
||||
|
|
|
@ -88,31 +88,28 @@ public:
|
|||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
|
||||
|
||||
void UpdateFromLockedData();
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) {
|
||||
*aSurface = ThebesSurface();
|
||||
NS_ADDREF(*aSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface() {
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
|
||||
EnsureImageSurface();
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void EnsureImageSurface();
|
||||
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
PRInt32 mStride;
|
||||
nsRect mDecoded;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
nsRefPtr<gfxASurface> mOptSurface;
|
||||
|
||||
// temporary buffers for Lock()
|
||||
PRUint8* mLockedData;
|
||||
PRUint8* mLockedAlpha;
|
||||
|
||||
PRUint8 mAlphaDepth;
|
||||
PRUint8 mRealAlphaDepth;
|
||||
PRPackedBool mLocked;
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
virtual ~gfxImageSurface();
|
||||
|
||||
// ImageSurface methods
|
||||
int Format() const { return mFormat; }
|
||||
gfxImageFormat Format() const { return mFormat; }
|
||||
long Width() const { return mWidth; }
|
||||
long Height() const { return mHeight; }
|
||||
/**
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
|
||||
private:
|
||||
unsigned char *mData;
|
||||
int mFormat;
|
||||
gfxImageFormat mFormat;
|
||||
long mWidth;
|
||||
long mHeight;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "gfxTypes.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
class gfxImageSurface;
|
||||
|
||||
class NS_EXPORT gfxPlatform {
|
||||
public:
|
||||
/**
|
||||
|
@ -69,10 +71,13 @@ public:
|
|||
* create a surface that is optimized for rapid pixel
|
||||
* changing.
|
||||
*/
|
||||
virtual gfxASurface *CreateOffscreenSurface(PRUint32 width,
|
||||
virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat) = 0;
|
||||
|
||||
|
||||
virtual already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface);
|
||||
|
||||
/*
|
||||
* Font bits
|
||||
*/
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
return (gfxWindowsPlatform*) gfxPlatform::GetPlatform();
|
||||
}
|
||||
|
||||
gfxASurface *CreateOffscreenSurface(PRUint32 width,
|
||||
already_AddRefed<gfxASurface> CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat);
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "gfxPlatformGtk.h"
|
||||
#endif
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -92,6 +95,27 @@ gfxPlatform::SetUseGlitz(PRBool use)
|
|||
gGlitzState = (use ? 1 : 0);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxPlatform::OptimizeImage(gfxImageSurface* aSurface)
|
||||
{
|
||||
nsRefPtr<gfxASurface> optSurface;
|
||||
optSurface = CreateOffscreenSurface(aSurface->Width(),
|
||||
aSurface->Height(),
|
||||
aSurface->Format());
|
||||
|
||||
if (!optSurface)
|
||||
return nsnull;
|
||||
|
||||
nsRefPtr<gfxContext> tmpCtx(new gfxContext(optSurface));
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->SetSource(aSurface);
|
||||
tmpCtx->Paint();
|
||||
|
||||
gfxASurface *ret = optSurface;
|
||||
NS_ADDREF(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatform::GetFontList(const nsACString& aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
|
|
|
@ -70,7 +70,7 @@ gfxPlatformGtk::gfxPlatformGtk()
|
|||
#endif
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxPlatformGtk::CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat)
|
||||
|
@ -178,6 +178,7 @@ gfxPlatformGtk::CreateOffscreenSurface(PRUint32 width,
|
|||
#endif
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(newSurface);
|
||||
return newSurface;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ gfxPlatformMac::gfxPlatformMac()
|
|||
#endif
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxPlatformMac::CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat)
|
||||
|
@ -129,5 +129,6 @@ gfxPlatformMac::CreateOffscreenSurface(PRUint32 width,
|
|||
#endif
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(newSurface);
|
||||
return newSurface;
|
||||
}
|
||||
|
|
|
@ -79,12 +79,14 @@ gfxWindowsPlatform::Init()
|
|||
mFontList->Compact();
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxWindowsPlatform::CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat)
|
||||
{
|
||||
return new gfxWindowsSurface(nsnull, width, height, imageFormat);
|
||||
gfxASurface *surf = new gfxWindowsSurface(nsnull, width, height, imageFormat);
|
||||
NS_IF_ADDREF(surf);
|
||||
return surf;
|
||||
}
|
||||
|
||||
int CALLBACK
|
||||
|
|
|
@ -89,6 +89,7 @@ SHARED_LIBRARY_LIBS = \
|
|||
|
||||
EXTRA_DSO_LIBS = \
|
||||
gkgfx \
|
||||
thebes \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
|
@ -159,6 +159,13 @@ nsresult nsBMPDecoder::WriteRLERows(PRUint32 rows)
|
|||
for (bit = 128; bit; bit >>= 1)
|
||||
byte |= *pos++ & bit;
|
||||
mAlpha[cnt] = byte;
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
mDecoded[(cnt * 4) + 3] = byte ? 255 : 0;
|
||||
#else
|
||||
mDecoded[(cnt * 4)] = byte ? 255 : 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < rows; cnt++) {
|
||||
|
|
|
@ -125,7 +125,7 @@ struct bitFields {
|
|||
#define RLE_GFXFORMAT_ALPHA gfxIFormats::RGB_A1
|
||||
#endif
|
||||
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#if defined(MOZ_CAIRO_GFX) || defined(XP_MAC) || defined(XP_MACOSX)
|
||||
#define GFXBYTESPERPIXEL 4
|
||||
#else
|
||||
#define GFXBYTESPERPIXEL 3
|
||||
|
@ -230,9 +230,26 @@ private:
|
|||
|
||||
/** Sets the pixel data in aDecoded to the given values.
|
||||
* The variable passed in as aDecoded will be moved on 3 bytes! */
|
||||
inline void SetPixel(PRUint8*& aDecoded, PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue)
|
||||
inline void SetPixel(PRUint8*& aDecoded, PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue, PRUint8 aAlpha = 0xFF)
|
||||
{
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*aDecoded++ = aBlue;
|
||||
*aDecoded++ = aGreen;
|
||||
*aDecoded++ = aRed;
|
||||
*aDecoded++ = aAlpha;
|
||||
#else
|
||||
// XRGB
|
||||
*aDecoded++ = aAlpha;
|
||||
*aDecoded++ = aRed;
|
||||
*aDecoded++ = aGreen;
|
||||
*aDecoded++ = aBlue;
|
||||
#endif
|
||||
|
||||
#else // MOZ_CAIRO_GFX
|
||||
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*aDecoded++ = 0; // Mac needs this padding byte
|
||||
#endif
|
||||
#ifdef USE_RGB
|
||||
|
@ -244,6 +261,7 @@ inline void SetPixel(PRUint8*& aDecoded, PRUint8 aRed, PRUint8 aGreen, PRUint8 a
|
|||
*aDecoded++ = aGreen;
|
||||
*aDecoded++ = aRed;
|
||||
#endif
|
||||
#endif // MOZ_CAIRO_GFX
|
||||
}
|
||||
|
||||
inline void SetPixel(PRUint8*& aDecoded, PRUint8 idx, colorTable* aColors)
|
||||
|
|
|
@ -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(MOZ_CAIRO_GFX) && (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(MOZ_CAIRO_GFX) && (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);
|
||||
|
|
|
@ -51,6 +51,8 @@ LIBXUL_LIBRARY = 1
|
|||
REQUIRES = xpcom \
|
||||
string \
|
||||
gfx \
|
||||
thebes \
|
||||
cairo \
|
||||
imglib2 \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsMemory.h"
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
#include "gfxContext.h"
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS2(imgContainerGIF, imgIContainer, nsITimerCallback)
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -951,11 +955,28 @@ void imgContainerGIF::SetMaskVisibility(gfxIImageFrame *aFrame, PRBool aVisible)
|
|||
PRUint32 alphaDataLength;
|
||||
const PRUint8 setMaskTo = aVisible ? 0xFF : 0x00;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
aFrame->LockImageData();
|
||||
nsresult res = aFrame->GetImageData(&alphaData, &alphaDataLength);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
for (PRUint32 i = 0; i < alphaDataLength; i+=4) {
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
alphaData[i+3] = setMaskTo;
|
||||
#else
|
||||
alphaData[i] = setMaskTo;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
aFrame->UnlockImageData();
|
||||
|
||||
#else
|
||||
|
||||
aFrame->LockAlphaData();
|
||||
nsresult res = aFrame->GetAlphaData(&alphaData, &alphaDataLength);
|
||||
if (NS_SUCCEEDED(res) && alphaData && alphaDataLength)
|
||||
memset(alphaData, setMaskTo, alphaDataLength);
|
||||
aFrame->UnlockAlphaData();
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -964,11 +985,23 @@ void imgContainerGIF::BlackenFrame(gfxIImageFrame *aFrame)
|
|||
{
|
||||
if (!aFrame)
|
||||
return;
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(aFrame));
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
img->GetSurface(getter_AddRefs(surf));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
ctx->SetColor(gfxRGBA(0, 0, 0));
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Paint();
|
||||
#else
|
||||
PRUint32 aDataLength;
|
||||
|
||||
aFrame->GetImageDataLength(&aDataLength);
|
||||
aFrame->SetImageData(nsnull, aDataLength, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -994,7 +1027,7 @@ void imgContainerGIF::BlackenFrame(gfxIImageFrame *aFrame,
|
|||
PRUint32 bpr; // Bytes Per Row
|
||||
aFrame->GetImageBytesPerRow(&bpr);
|
||||
|
||||
#if !defined(MOZ_CAIRO_GFX) && (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;
|
||||
|
@ -1035,6 +1068,7 @@ PRBool imgContainerGIF::CopyFrameImage(gfxIImageFrame *aSrcFrame,
|
|||
memcpy(aDataDest, aDataSrc, aDataLengthSrc);
|
||||
aDstFrame->UnlockImageData();
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// Copy Alpha/Mask Over
|
||||
// If no mask, lockAlpha will tell us
|
||||
if (NS_SUCCEEDED(aDstFrame->LockAlphaData())) {
|
||||
|
@ -1047,6 +1081,7 @@ PRBool imgContainerGIF::CopyFrameImage(gfxIImageFrame *aSrcFrame,
|
|||
|
||||
aDstFrame->UnlockAlphaData();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tell the image that it's data has been updated
|
||||
nsCOMPtr<nsIInterfaceRequestor> ireq(do_QueryInterface(aDstFrame));
|
||||
|
|
|
@ -504,17 +504,54 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
PRUint8* rgbRowIndex = decoder->mRGBLine;
|
||||
PRUint8* rowBufIndex = aRowBufPtr;
|
||||
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
if (*rowBufIndex >= cmapsize ||
|
||||
((format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) &&
|
||||
(*rowBufIndex == decoder->mGIFStruct->tpixel))) {
|
||||
*rgbRowIndex++ = 0;
|
||||
*rgbRowIndex++ = 0;
|
||||
*rgbRowIndex++ = 0;
|
||||
*rgbRowIndex++ = 0;
|
||||
++rowBufIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
const PRUint32 colorIndex = *rowBufIndex * 3;
|
||||
const PRUint8 r = cmap[colorIndex]; // red
|
||||
const PRUint8 g = cmap[colorIndex + 1]; // green
|
||||
const PRUint8 b = cmap[colorIndex + 2]; // blue
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*rgbRowIndex++ = b;
|
||||
*rgbRowIndex++ = g;
|
||||
*rgbRowIndex++ = r;
|
||||
*rgbRowIndex++ = 0xFF;
|
||||
#else
|
||||
// XRGB
|
||||
*rgbRowIndex++ = 0xFF;
|
||||
*rgbRowIndex++ = r;
|
||||
*rgbRowIndex++ = g;
|
||||
*rgbRowIndex++ = b;
|
||||
#endif
|
||||
++rowBufIndex;
|
||||
}
|
||||
for (int i=0; i<aDuplicateCount; i++)
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine, bpr, (aRowNumber+i)*bpr);
|
||||
|
||||
|
||||
#else
|
||||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
case gfxIFormats::BGR:
|
||||
{
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#if 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(MOZ_CAIRO_GFX) && (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)
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
|
@ -543,12 +580,12 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
memset(decoder->mAlphaLine, 0, abpr);
|
||||
for (PRUint32 x = 0; x < (PRUint32)width; ++x) {
|
||||
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#if 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(MOZ_CAIRO_GFX) && (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)
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
|
@ -564,7 +601,7 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
}
|
||||
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
|
||||
} else {
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
rgbRowIndex+=4;
|
||||
#else
|
||||
rgbRowIndex+=3;
|
||||
|
@ -581,6 +618,7 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
decoder->mCurrentRow = aRowNumber + aDuplicateCount - 1;
|
||||
|
|
|
@ -146,12 +146,40 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
PRInt32 rownum;
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
PRUint8 *row = malloc(bpr);
|
||||
PRUint8 *adata = data + (bpr * height);
|
||||
for (rownum = 0; rownum < height; ++rownum, data += bpr) {
|
||||
PRInt8 *rowdata = data;
|
||||
for (int i = 0; i < bpr; i++) {
|
||||
const PRUint8 r = *rowdata++;
|
||||
const PRUint8 g = *rowdata++;
|
||||
const PRUint8 b = *rowdata++;
|
||||
const PRUint8 a = (format == gfxIFormat::RGB_A1) ? abpr[i>>3] : abpr[i];
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*row++ = b;
|
||||
*row++ = g;
|
||||
*row++ = r;
|
||||
*row++ = a;
|
||||
#else
|
||||
// XRGB
|
||||
*row++ = a;
|
||||
*row++ = r;
|
||||
*row++ = g;
|
||||
*row++ = b;
|
||||
#endif
|
||||
}
|
||||
mFrame->SetImageData(row, bpr, rownum * bpr);
|
||||
}
|
||||
free(row);
|
||||
#else
|
||||
for (rownum = 0; rownum < height; ++rownum, data += bpr)
|
||||
mFrame->SetImageData(data, bpr, rownum * bpr);
|
||||
|
||||
for (rownum = 0; rownum < height; ++rownum, data += abpr)
|
||||
mFrame->SetAlphaData(data, abpr, rownum * abpr);
|
||||
|
||||
#endif
|
||||
nsIntRect r(0, 0, width, height);
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
|
||||
|
|
|
@ -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(MOZ_CAIRO_GFX) && (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;
|
||||
|
@ -363,7 +363,7 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
JPOOL_IMAGE,
|
||||
row_stride, 1);
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(XP_MAC) || defined(XP_MACOSX) || defined(MOZ_WIDGET_PHOTON)
|
||||
#if defined(MOZ_CAIRO_GFX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(XP_MAC) || defined(XP_MACOSX) || defined(MOZ_WIDGET_PHOTON)
|
||||
// allocate buffer to do byte flipping / padding
|
||||
mRGBRow = (PRUint8*) PR_MALLOC(row_stride);
|
||||
#endif
|
||||
|
@ -517,7 +517,32 @@ nsJPEGDecoder::OutputScanlines()
|
|||
break;
|
||||
}
|
||||
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON))
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
PRUint8 *ptrOutputBuf = mRGBRow;
|
||||
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
for (PRUint32 i=0; i < mInfo.output_width; ++i) {
|
||||
const PRUint8 r = *j1++;
|
||||
const PRUint8 g = *j1++;
|
||||
const PRUint8 b = *j1++;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*ptrOutputBuf++ = b;
|
||||
*ptrOutputBuf++ = g;
|
||||
*ptrOutputBuf++ = r;
|
||||
*ptrOutputBuf++ = 0xFF;
|
||||
#else
|
||||
// XRGB
|
||||
*ptrOutputBuf++ = 0xFF;
|
||||
*ptrOutputBuf++ = r;
|
||||
*ptrOutputBuf++ = g;
|
||||
*ptrOutputBuf++ = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
samples = mRGBRow;
|
||||
|
||||
#elif defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
PRUint8 *ptrOutputBuf = mRGBRow;
|
||||
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
|
@ -529,7 +554,7 @@ nsJPEGDecoder::OutputScanlines()
|
|||
}
|
||||
|
||||
samples = mRGBRow;
|
||||
#elif !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
#elif defined(XP_MAC) || defined(XP_MACOSX)
|
||||
PRUint8 *ptrOutputBuf = mRGBRow;
|
||||
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
|
@ -548,7 +573,7 @@ nsJPEGDecoder::OutputScanlines()
|
|||
|
||||
// Note! row_stride here must match the row_stride in
|
||||
// nsJPEGDecoder::WriteFrom
|
||||
#if !defined(MOZ_CAIRO_GFX) && (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;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Stuart Parmenter <stuart@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -435,7 +435,29 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
case gfxIFormats::BGR:
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
{
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
cptr = decoder->colorLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
const PRUint8 r = *line++;
|
||||
const PRUint8 g = *line++;
|
||||
const PRUint8 b = *line++;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*cptr++ = b;
|
||||
*cptr++ = g;
|
||||
*cptr++ = r;
|
||||
*cptr++ = 0xFF;
|
||||
#else
|
||||
// XRGB
|
||||
*cptr++ = 0xFF;
|
||||
*cptr++ = r;
|
||||
*cptr++ = g;
|
||||
*cptr++ = b;
|
||||
#endif
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
#elif defined(XP_MAC) || defined(XP_MACOSX)
|
||||
cptr = decoder->colorLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
*cptr++ = 0;
|
||||
|
@ -447,10 +469,41 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
#else
|
||||
decoder->mFrame->SetImageData((PRUint8*)line, bpr, row_num*bpr);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::BGR_A1:
|
||||
{
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
cptr = decoder->colorLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
if (line[3]) {
|
||||
const PRUint8 r = *line++;
|
||||
const PRUint8 g = *line++;
|
||||
const PRUint8 b = *line++;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
*cptr++ = b;
|
||||
*cptr++ = g;
|
||||
*cptr++ = r;
|
||||
*cptr++ = 0xFF;
|
||||
#else
|
||||
*cptr++ = 0xFF;
|
||||
*cptr++ = r;
|
||||
*cptr++ = g;
|
||||
*cptr++ = b;
|
||||
#endif
|
||||
line++;
|
||||
} else {
|
||||
*cptr++ = 0;
|
||||
*cptr++ = 0;
|
||||
*cptr++ = 0;
|
||||
*cptr++ = 0;
|
||||
line += 4;
|
||||
}
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
|
||||
#else
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
memset(aptr, 0, abpr);
|
||||
|
@ -473,45 +526,56 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
}
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A8:
|
||||
case gfxIFormats::BGR_A8:
|
||||
{
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
const PRUint8 r = *line++;
|
||||
const PRUint8 g = *line++;
|
||||
const PRUint8 b = *line++;
|
||||
const PRUint8 a = *line++;
|
||||
if (a == 0) {
|
||||
*cptr++ = 0;
|
||||
#endif
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*aptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGBA:
|
||||
case gfxIFormats::BGRA:
|
||||
#if !defined(MOZ_CAIRO_GFX) && (defined(XP_MAC) || defined(XP_MACOSX))
|
||||
{
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
*cptr++ = 0;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*aptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
}
|
||||
*cptr++ = 0;
|
||||
*cptr++ = 0;
|
||||
} else {
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRA
|
||||
FAST_DIVIDE_BY_255(*cptr++, b*a);
|
||||
FAST_DIVIDE_BY_255(*cptr++, g*a);
|
||||
FAST_DIVIDE_BY_255(*cptr++, r*a);
|
||||
*cptr++ = a;
|
||||
#else
|
||||
decoder->mFrame->SetImageData(line, bpr, row_num*bpr);
|
||||
// ARGB
|
||||
*cptr++ = a;
|
||||
FAST_DIVIDE_BY_255(*cptr++, r*a);
|
||||
FAST_DIVIDE_BY_255(*cptr++, g*a);
|
||||
FAST_DIVIDE_BY_255(*cptr++, b*a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
|
||||
#else
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*cptr++ = 0;
|
||||
#endif
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*aptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,19 +256,30 @@ nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) {
|
|||
hiByte = !hiByte;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
PRUint32 *ar = ((PRUint32*)mAlphaRow) + mCurCol;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
const PRUint8 val = ((pixel & (1 << i)) >> i) ? 255 : 0;
|
||||
*ar++ = (val << 24) | 0;
|
||||
}
|
||||
#else // MOZ_CAIRO_GFX
|
||||
mAlphaRow[mCurCol/8] = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
PRUint8 val = (pixel & (1 << i)) >> i;
|
||||
mAlphaRow[mCurCol/8] |= val << (7 - i);
|
||||
}
|
||||
|
||||
#endif
|
||||
mCurCol = PR_MIN(mCurCol + 8, mWidth);
|
||||
if (mCurCol == mWidth || mState == RECV_DONE) {
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
mFrame->SetImageData(mAlphaRow, abpr, mCurRow * abpr);
|
||||
#else
|
||||
// Row finished. Set Data.
|
||||
mFrame->SetAlphaData(mAlphaRow, abpr, mCurRow * abpr);
|
||||
// nsnull gets interpreted as all-zeroes, which is what we
|
||||
// want
|
||||
mFrame->SetImageData(nsnull, bpr, mCurRow * bpr);
|
||||
#endif
|
||||
nsIntRect r(0, mCurRow, mWidth, 1);
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче