diff -ur old/decoders/gif/nsGIFDecoder2.cpp new/decoders/gif/nsGIFDecoder2.cpp --- old/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp 2010-10-27 05:01:27.000000000 +0200 +++ new/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp 2010-11-30 22:14:52.000000000 +0100 @@ -202,7 +202,7 @@ nsresult nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows) { - nsIntRect r(0, fromRow, mGIFStruct.width, rows); + nsIntRect r(mGIFStruct.x_offset, mGIFStruct.y_offset + fromRow, mGIFStruct.width, rows); // Update image nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r); @@ -215,7 +215,6 @@ if (!mGIFStruct.images_decoded && mObserver) { PRUint32 imgCurFrame; mImageContainer->GetCurrentFrameIndex(&imgCurFrame); - r.y += mGIFStruct.y_offset; mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r); } return NS_OK; diff -ur old/src/imgContainer.cpp new/src/imgContainer.cpp --- old/modules/libpr0n/src/imgContainer.cpp 2010-10-27 05:01:28.000000000 +0200 +++ new/modules/libpr0n/src/imgContainer.cpp 2010-11-30 21:49:31.000000000 +0100 @@ -420,6 +420,8 @@ frame->GetImageData(imageData, imageLength); + frame->LockImageData(); + mFrames.InsertElementAt(framenum, frame.forget()); mNumFrames++; @@ -445,6 +447,11 @@ nsresult rv = frame->Init(aX, aY, aWidth, aHeight, aFormat, aPaletteDepth); NS_ENSURE_SUCCESS(rv, rv); + if (mFrames.Length() > 0) { + imgFrame *prevframe = mFrames.ElementAt(mFrames.Length() - 1); + prevframe->UnlockImageData(); + } + if (mFrames.Length() == 0) { return InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength, paletteData, paletteLength); diff -ur old/src/imgFrame.cpp new/src/imgFrame.cpp --- old/modules/libpr0n/src/imgFrame.cpp 2010-10-27 05:01:28.000000000 +0200 +++ new/modules/libpr0n/src/imgFrame.cpp 2010-12-01 00:48:13.000000000 +0100 @@ -157,6 +157,7 @@ #ifdef USE_WIN_SURFACE , mIsDDBSurface(PR_FALSE) #endif + , mLocked(PR_FALSE) { static PRBool hasCheckedOptimize = PR_FALSE; if (!hasCheckedOptimize) { @@ -418,8 +419,7 @@ PRBool doTile = !imageRect.Contains(sourceRect); if (doPadding || doPartialDecode) { - gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height) + - gfxPoint(aPadding.left, aPadding.top); + gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height); if (!doTile && !mSinglePixel) { // Not tiling, and we have a surface, so we can account for @@ -713,7 +713,7 @@ // clamp to bounds, in case someone sends a bogus updateRect (I'm looking at // you, gif decoder) - nsIntRect boundsRect(0, 0, mSize.width, mSize.height); + nsIntRect boundsRect(mOffset, mSize); mDecoded.IntersectRect(mDecoded, boundsRect); #ifdef XP_MACOSX @@ -811,7 +811,13 @@ nsresult imgFrame::LockImageData() { if (mPalettedImageData) - return NS_OK; + return NS_ERROR_NOT_AVAILABLE; + + NS_ABORT_IF_FALSE(!mLocked, "Trying to lock already locked image data."); + if (mLocked) { + return NS_ERROR_FAILURE; + } + mLocked = PR_TRUE; if ((mOptSurface || mSinglePixel) && !mImageSurface) { // Recover the pixels @@ -837,13 +843,25 @@ #endif } + if (mImageSurface) + mImageSurface->Flush(); + return NS_OK; } nsresult imgFrame::UnlockImageData() { if (mPalettedImageData) - return NS_OK; + return NS_ERROR_NOT_AVAILABLE; + + NS_ABORT_IF_FALSE(mLocked, "Unlocking an unlocked image!"); + if (!mLocked) { + return NS_ERROR_FAILURE; + } + mLocked = PR_FALSE; + + if (mImageSurface) + mImageSurface->MarkDirty(); #ifdef XP_MACOSX if (mQuartzSurface) @@ -900,7 +918,7 @@ PRBool imgFrame::ImageComplete() const { - return mDecoded == nsIntRect(0, 0, mSize.width, mSize.height); + return mDecoded == nsIntRect(mOffset, mSize); } // A hint from the image decoders that this image has no alpha, even diff -ur old/src/imgFrame.h new/src/imgFrame.h --- old/modules/libpr0n/src/imgFrame.h 2010-10-27 05:01:28.000000000 +0200 +++ new/modules/libpr0n/src/imgFrame.h 2010-11-30 22:04:48.000000000 +0100 @@ -172,6 +172,7 @@ PRPackedBool mNeverUseDeviceSurface; PRPackedBool mFormatChanged; PRPackedBool mCompositingFailed; + PRPackedBool mLocked; #ifdef XP_WIN PRPackedBool mIsDDBSurface;