Skip to content

Commit

Permalink
Bug 274244: Display more broken GIFs. r=stuart sr=tor
Browse files Browse the repository at this point in the history
  • Loading branch information
paper%animecity.nu committed Mar 8, 2005
1 parent 5831f8d commit 0dd638f
Show file tree
Hide file tree
Showing 23 changed files with 127 additions and 15 deletions.
7 changes: 6 additions & 1 deletion gfx/idl/gfxIImageFrame.idl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ native nsRectRef(nsIntRect &);
* @author Stuart Parmenter <[email protected]>
* @version 0.1
*/
[scriptable, uuid(20caf74f-2c35-450f-9f87-c3ecc213553c)]
[scriptable, uuid(f6d00ee7-defc-4101-b2dc-e72cf4c37c3c)]
interface gfxIImageFrame : nsISupports
{
/**
Expand Down Expand Up @@ -116,6 +116,11 @@ interface gfxIImageFrame : nsISupports
*/
readonly attribute gfx_format format;

/**
* returns whether the image requires the background to be painted
*/
readonly attribute boolean needsBackground;

/* data accessors */
readonly attribute unsigned long imageBytesPerRow;

Expand Down
7 changes: 7 additions & 0 deletions gfx/public/nsIImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ class nsIImage : public nsISupports
* @param aUpdateRect The rectangle to update
*/
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect) = 0;

/**
* Get whether this image's region is completely filled with data.
* @return PR_TRUE if image is complete, PR_FALSE if image is not yet
* complete or broken
*/
virtual PRBool GetIsImageComplete() = 0;

/**
* Converted this pixelmap to an optimized pixelmap for the device
Expand Down
10 changes: 10 additions & 0 deletions gfx/src/beos/nsImageBeOS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ void nsImageBeOS::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRec
mDecodedX2 = aUpdateRect->XMost();
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageBeOS::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}

// Draw the bitmap, this method has a source and destination coordinates
NS_IMETHODIMP nsImageBeOS::Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
Expand Down
1 change: 1 addition & 0 deletions gfx/src/beos/nsImageBeOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class nsImageBeOS : public nsIImage

virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);

Expand Down
7 changes: 7 additions & 0 deletions gfx/src/cairo/nsCairoImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ nsCairoImage::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *a
{
}

PRBool
nsCairoImage::GetIsImageComplete()
{
/* TODO: nsCairoImage needs to store coords of decoded data */
return PR_TRUE;
}

nsresult
nsCairoImage::Optimize(nsIDeviceContext* aContext)
{
Expand Down
1 change: 1 addition & 0 deletions gfx/src/cairo/nsCairoImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class nsCairoImage : public nsIImage
virtual PRBool GetHasAlphaMask();
virtual PRUint8 * GetAlphaBits();
virtual PRInt32 GetAlphaLineStride();
virtual PRBool GetIsImageComplete();
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual nsColorMap * GetColorMap();
Expand Down
10 changes: 10 additions & 0 deletions gfx/src/gtk/nsImageGTK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,16 @@ void nsImageGTK::ImageUpdated(nsIDeviceContext *aContext,
mDecodedX2 = aUpdateRect->XMost();
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageGTK::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}

void nsImageGTK::UpdateCachedImage()
{
#ifdef TRACE_IMAGE_ALLOCATION
Expand Down
1 change: 1 addition & 0 deletions gfx/src/gtk/nsImageGTK.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class nsImageGTK :
void UpdateCachedImage();
virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);
Expand Down
9 changes: 9 additions & 0 deletions gfx/src/mac/nsImageMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ nsImageMac::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
mDecodedX2 = aUpdateRect->XMost();
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageMac::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}

void DataProviderReleaseFunc(void *info, const void *data, size_t size)
{
Expand Down
1 change: 1 addition & 0 deletions gfx/src/mac/nsImageMac.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class nsImageMac : public nsIImage, public nsIImageMac
// mAlphaBits). 'aFlags' is ignored.
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();

// Optimizes memory usage for object.
virtual nsresult Optimize(nsIDeviceContext* aContext);
Expand Down
11 changes: 11 additions & 0 deletions gfx/src/os2/nsImageOS2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ void nsImageOS2::ImageUpdated( nsIDeviceContext *aContext,
}
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageOS2::GetIsImageComplete() {
return mInfo &&
mDecodedRect.x == 0 &&
mDecodedRect.y == 0 &&
mDecodedRect.width == mInfo->cx &&
mDecodedRect.height == mInfo->cy;
}

void nsImageOS2::BuildBlenderLookup (void)
{
for (int y = 0 ; y < 256 ; y++)
Expand Down
1 change: 1 addition & 0 deletions gfx/src/os2/nsImageOS2.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class nsImageOS2 : public nsIImage{
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
virtual nsColorMap* GetColorMap() {return mColorMap;}
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
Expand Down
10 changes: 10 additions & 0 deletions gfx/src/photon/nsImagePh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ nsresult nsImagePh :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMas
return NS_OK;
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImagePh::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}

/** ----------------------------------------------------------------
* Draw the bitmap, this method has a source and destination coordinates
* @update dc - 11/20/98
Expand Down
1 change: 1 addition & 0 deletions gfx/src/photon/nsImagePh.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class nsImagePh : public nsIImage {
mDirtyFlags = aFlags;
mPhImage.size.h = mDecodedY2;
}
virtual PRBool GetIsImageComplete();

virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
// virtual PRBool IsOptimized() { return mIsOptimized; }
Expand Down
10 changes: 10 additions & 0 deletions gfx/src/qt/nsImageQt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,16 @@ void nsImageQt::ImageUpdated(nsIDeviceContext *aContext,
mDecodedRect.UnionRect(mDecodedRect, *aUpdateRect);
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageQt::GetIsImageComplete() {
return mDecodedRect.x == 0 &&
mDecodedRect.y == 0 &&
mDecodedRect.width == mWidth &&
mDecodedRect.height == mHeight;
}

// Draw the bitmap, this method has a source and destination coordinates
NS_IMETHODIMP nsImageQt::Draw(nsIRenderingContext &aContext,
nsIDrawingSurface *aSurface,
Expand Down
1 change: 1 addition & 0 deletions gfx/src/qt/nsImageQt.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class nsImageQt : public nsIImage

virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags,nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();

virtual nsresult Optimize(nsIDeviceContext *aContext);

Expand Down
13 changes: 13 additions & 0 deletions gfx/src/shared/gfxImageFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,19 @@ NS_IMETHODIMP gfxImageFrame::GetFormat(gfx_format *aFormat)
return NS_OK;
}

/* readonly attribute boolean needsBackground; */
NS_IMETHODIMP gfxImageFrame::GetNeedsBackground(PRBool *aNeedsBackground)
{
if (!mInitalized)
return NS_ERROR_NOT_INITIALIZED;

*aNeedsBackground = (mFormat != gfxIFormats::RGB &&
mFormat != gfxIFormats::BGR) ||
!mImage->GetIsImageComplete();
return NS_OK;
}


/* readonly attribute unsigned long imageBytesPerRow; */
NS_IMETHODIMP gfxImageFrame::GetImageBytesPerRow(PRUint32 *aBytesPerRow)
{
Expand Down
14 changes: 12 additions & 2 deletions gfx/src/windows/nsImageWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,17 @@ nsImageWin :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *a
mDecodedX2 = aUpdateRect->XMost();
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageWin::GetIsImageComplete() {
return mInitialized &&
mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mBHead->biWidth &&
mDecodedY2 == mBHead->biHeight;
}

//------------------------------------------------------------

struct MONOBITMAPINFO {
Expand Down Expand Up @@ -1088,8 +1099,7 @@ nsImageWin::ProgressiveDoubleBlit(nsIDeviceContext *aContext,
return PR_FALSE;
}
}
mTmpHBitmap = ::CreateCompatibleBitmap(theHDC, mBHead->biWidth,
mBHead->biHeight);
mTmpHBitmap = ::CreateCompatibleBitmap(theHDC, mDecodedX2, mDecodedY2);
if (!mTmpHBitmap) {
::DeleteDC(imgDC);
if (maskDC) {
Expand Down
1 change: 1 addition & 0 deletions gfx/src/windows/nsImageWin.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class nsImageWin : public nsIImage{
nscoord aDWidth, nscoord aDHeight);
virtual nsColorMap* GetColorMap() {return mColorMap;}
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
Expand Down
10 changes: 10 additions & 0 deletions gfx/src/xlib/nsImageXlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,16 @@ void nsImageXlib::ImageUpdated(nsIDeviceContext *aContext,
mDecodedX2 = aUpdateRect->XMost();
}

/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageXlib::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}

void nsImageXlib::UpdateCachedImage()
{
nsRegionRectIterator ri(mUpdateRegion);
Expand Down
1 change: 1 addition & 0 deletions gfx/src/xlib/nsImageXlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class nsImageXlib : public nsIImage {
void UpdateCachedImage();
virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);
Expand Down
7 changes: 1 addition & 6 deletions layout/base/nsCSSRendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2936,12 +2936,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
if (gfxImgFrame) {
gfx_format frameFormat;
gfxImgFrame->GetFormat(&frameFormat);
NS_ASSERTION(frameFormat >= 0 && frameFormat <= 7,
"Unknown gfxIFormats value");
needBackgroundColor = frameFormat != gfxIFormats::RGB &&
frameFormat != gfxIFormats::BGR;
gfxImgFrame->GetNeedsBackground(&needBackgroundColor);

/* check for tiling of a image where frame smaller than container */
nsSize iSize;
Expand Down
8 changes: 2 additions & 6 deletions modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
PRUint32 numFrames = 0;
if (mImageContainer)
mImageContainer->GetNumFrames(&numFrames);
if (numFrames <= 1)
if (numFrames <= 0)
return NS_ERROR_FAILURE;
}

Expand Down Expand Up @@ -359,11 +359,7 @@ int nsGIFDecoder2::EndImageFrame(
}
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);

// if the gif is corrupt don't mark the frame as complete, as nsCSSRendering
// will happily try using it to draw a background
if (decoder->mObserver &&
decoder->mImageFrame &&
decoder->mGIFStruct->state != gif_error) {
if (decoder->mObserver && decoder->mImageFrame) {
decoder->FlushImageData();

if (aFrameNumber == 1) {
Expand Down

0 comments on commit 0dd638f

Please sign in to comment.