mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 514033 - Error recovery for imagelib - part 9 - Coalesce end-of-decode notifications into superclass.r=joe,a=blocker
This commit is contained in:
parent
6b88ca3f31
commit
4f052631cc
@ -89,11 +89,7 @@ nsBMPDecoder::FinishInternal()
|
||||
// Send notifications if appropriate
|
||||
if (!IsSizeDecode() && !IsError() && (GetFrameCount() == 1)) {
|
||||
PostFrameStop();
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
PostDecodeDone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,10 +135,11 @@ void
|
||||
nsGIFDecoder2::FinishInternal()
|
||||
{
|
||||
// If the GIF got cut off, handle it anyway
|
||||
if (!IsSizeDecode() && !IsError()) {
|
||||
if (!IsSizeDecode() && !IsError() && mGIFOpen) {
|
||||
if (mCurrentFrame == mGIFStruct.images_decoded)
|
||||
EndImageFrame();
|
||||
EndGIF(/* aSuccess = */ PR_TRUE);
|
||||
PostDecodeDone();
|
||||
mGIFOpen = PR_FALSE;
|
||||
}
|
||||
|
||||
mImage->SetLoopCount(mGIFStruct.loop_count);
|
||||
@ -192,24 +193,6 @@ void nsGIFDecoder2::BeginGIF()
|
||||
return;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void nsGIFDecoder2::EndGIF(PRBool aSuccess)
|
||||
{
|
||||
if (!mGIFOpen)
|
||||
return;
|
||||
|
||||
if (aSuccess)
|
||||
mImage->DecodingComplete();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
mGIFOpen = PR_FALSE;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
|
||||
{
|
||||
@ -1067,18 +1050,17 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
break;
|
||||
|
||||
case gif_done:
|
||||
EndGIF(/* aSuccess = */ PR_TRUE);
|
||||
PostDecodeDone();
|
||||
mGIFOpen = PR_FALSE;
|
||||
goto done;
|
||||
|
||||
case gif_error:
|
||||
PostDataError();
|
||||
EndGIF(/* aSuccess = */ PR_FALSE);
|
||||
return;
|
||||
|
||||
// Handle out of memory errors
|
||||
case gif_oom:
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
EndGIF(/* aSuccess = */ PR_FALSE);
|
||||
return;
|
||||
|
||||
// We shouldn't ever get here.
|
||||
@ -1090,7 +1072,6 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
// if an error state is set but no data remains, code flow reaches here
|
||||
if (mGIFStruct.state == gif_error) {
|
||||
PostDataError();
|
||||
EndGIF(/* aSuccess = */ PR_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ private:
|
||||
* frame size information, etc. */
|
||||
|
||||
void BeginGIF();
|
||||
void EndGIF(PRBool aSuccess);
|
||||
nsresult BeginImageFrame(gfx_depth aDepth);
|
||||
void EndImageFrame();
|
||||
void FlushImageData();
|
||||
|
@ -114,11 +114,7 @@ nsICODecoder::FinishInternal()
|
||||
PostInvalidation(r);
|
||||
|
||||
PostFrameStop();
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, 0);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
PostDecodeDone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,7 @@ nsIconDecoder::nsIconDecoder() :
|
||||
mPixBytesRead(0),
|
||||
mPixBytesTotal(0),
|
||||
mImageData(nsnull),
|
||||
mState(iconStateStart),
|
||||
mNotifiedDone(PR_FALSE)
|
||||
mState(iconStateStart)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
@ -65,15 +64,6 @@ nsIconDecoder::nsIconDecoder() :
|
||||
nsIconDecoder::~nsIconDecoder()
|
||||
{ }
|
||||
|
||||
void
|
||||
nsIconDecoder::FinishInternal()
|
||||
{
|
||||
// If we haven't notified of completion yet for a full/success decode, we
|
||||
// didn't finish. Notify in error mode
|
||||
if (!IsSizeDecode() && !mNotifiedDone)
|
||||
NotifyDone(/* aSuccess = */ PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
{
|
||||
@ -154,7 +144,8 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
|
||||
// If we've got all the pixel bytes, we're finished
|
||||
if (mPixBytesRead == mPixBytesTotal) {
|
||||
NotifyDone(/* aSuccess = */ PR_TRUE);
|
||||
PostFrameStop();
|
||||
PostDecodeDone();
|
||||
mState = iconStateFinished;
|
||||
}
|
||||
break;
|
||||
@ -169,25 +160,5 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIconDecoder::NotifyDone(PRBool aSuccess)
|
||||
{
|
||||
// We should only call this once
|
||||
NS_ABORT_IF_FALSE(!mNotifiedDone, "Calling NotifyDone twice");
|
||||
|
||||
// Notify
|
||||
PostFrameStop();
|
||||
if (aSuccess)
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
// Flag that we've notified
|
||||
mNotifiedDone = PR_TRUE;
|
||||
}
|
||||
|
||||
} // namespace imagelib
|
||||
} // namespace mozilla
|
||||
|
@ -78,7 +78,6 @@ public:
|
||||
virtual ~nsIconDecoder();
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
|
||||
virtual void FinishInternal();
|
||||
|
||||
PRUint8 mWidth;
|
||||
PRUint8 mHeight;
|
||||
@ -86,9 +85,6 @@ public:
|
||||
PRUint32 mPixBytesTotal;
|
||||
PRUint8* mImageData;
|
||||
PRUint32 mState;
|
||||
|
||||
PRBool mNotifiedDone;
|
||||
void NotifyDone(PRBool aSuccess);
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -99,7 +99,6 @@ nsJPEGDecoder::nsJPEGDecoder()
|
||||
{
|
||||
mState = JPEG_HEADER;
|
||||
mReading = PR_TRUE;
|
||||
mNotifiedDone = PR_FALSE;
|
||||
mImageData = nsnull;
|
||||
|
||||
mBytesToSkip = 0;
|
||||
@ -187,16 +186,6 @@ nsJPEGDecoder::FinishInternal()
|
||||
(mState != JPEG_ERROR) &&
|
||||
!IsSizeDecode())
|
||||
this->Write(nsnull, 0);
|
||||
|
||||
/* If we already know we're in an error state, don't
|
||||
bother flagging another one here. */
|
||||
if (mState == JPEG_ERROR)
|
||||
return;
|
||||
|
||||
/* If we're doing a full decode and haven't notified of completion yet,
|
||||
* we must not have got everything we wanted. Send error notifications. */
|
||||
if (!IsSizeDecode() && !mNotifiedDone)
|
||||
NotifyDone(/* aSuccess = */ PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@ -554,23 +543,10 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
}
|
||||
|
||||
void
|
||||
nsJPEGDecoder::NotifyDone(PRBool aSuccess)
|
||||
nsJPEGDecoder::NotifyDone()
|
||||
{
|
||||
// We should only be called once
|
||||
NS_ABORT_IF_FALSE(!mNotifiedDone, "calling NotifyDone twice!");
|
||||
|
||||
// Notify
|
||||
PostFrameStop();
|
||||
if (aSuccess)
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
// Mark that we've been called
|
||||
mNotifiedDone = PR_TRUE;
|
||||
PostDecodeDone();
|
||||
}
|
||||
|
||||
void
|
||||
@ -886,8 +862,8 @@ term_source (j_decompress_ptr jd)
|
||||
NS_ABORT_IF_FALSE(decoder->mState != JPEG_ERROR,
|
||||
"Calling term_source on a JPEG with mState == JPEG_ERROR!");
|
||||
|
||||
// Notify
|
||||
decoder->NotifyDone(/* aSuccess = */ PR_TRUE);
|
||||
// Notify using a helper method to get around protectedness issues.
|
||||
decoder->NotifyDone();
|
||||
}
|
||||
|
||||
} // namespace imagelib
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
|
||||
virtual void FinishInternal();
|
||||
|
||||
void NotifyDone(PRBool aSuccess);
|
||||
void NotifyDone();
|
||||
|
||||
protected:
|
||||
void OutputScanlines(PRBool* suspend);
|
||||
@ -123,7 +123,6 @@ public:
|
||||
qcms_transform *mTransform;
|
||||
|
||||
PRPackedBool mReading;
|
||||
PRPackedBool mNotifiedDone;
|
||||
};
|
||||
|
||||
} // namespace imagelib
|
||||
|
@ -86,8 +86,7 @@ nsPNGDecoder::nsPNGDecoder() :
|
||||
mCMSLine(nsnull), interlacebuf(nsnull),
|
||||
mInProfile(nsnull), mTransform(nsnull),
|
||||
mHeaderBuf(nsnull), mHeaderBytesRead(0),
|
||||
mChannels(0), mFrameIsHidden(PR_FALSE),
|
||||
mNotifiedDone(PR_FALSE)
|
||||
mChannels(0), mFrameIsHidden(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -289,16 +288,6 @@ nsPNGDecoder::InitInternal()
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsPNGDecoder::FinishInternal()
|
||||
{
|
||||
|
||||
// If we're a full/success decode but haven't sent stop notifications yet,
|
||||
// we didn't get all the data we needed. Send error notifications.
|
||||
if (!IsSizeDecode() && !mNotifiedDone)
|
||||
NotifyDone(/* aSuccess = */ PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
{
|
||||
@ -368,26 +357,6 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPNGDecoder::NotifyDone(PRBool aSuccess)
|
||||
{
|
||||
// We should only be called once
|
||||
NS_ABORT_IF_FALSE(!mNotifiedDone, "Calling NotifyDone twice!");
|
||||
|
||||
// Notify
|
||||
EndImageFrame();
|
||||
if (aSuccess)
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
// Mark that we've been called
|
||||
mNotifiedDone = PR_TRUE;
|
||||
}
|
||||
|
||||
// Sets up gamma pre-correction in libpng before our callback gets called.
|
||||
// We need to do this if we don't end up with a CMS profile.
|
||||
static void
|
||||
@ -863,7 +832,8 @@ nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
#endif
|
||||
|
||||
// Send final notifications
|
||||
decoder->NotifyDone(/* aSuccess = */ PR_TRUE);
|
||||
decoder->EndImageFrame();
|
||||
decoder->PostDecodeDone();
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,6 @@ public:
|
||||
|
||||
virtual void InitInternal();
|
||||
virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
|
||||
virtual void FinishInternal();
|
||||
|
||||
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
PRInt32 width, PRInt32 height,
|
||||
@ -72,7 +71,6 @@ public:
|
||||
void SetAnimFrameInfo();
|
||||
|
||||
void EndImageFrame();
|
||||
void NotifyDone(PRBool aSuccess);
|
||||
|
||||
public:
|
||||
png_structp mPNG;
|
||||
@ -93,7 +91,6 @@ public:
|
||||
PRUint8 mChannels;
|
||||
PRPackedBool mFrameHasNoAlpha;
|
||||
PRPackedBool mFrameIsHidden;
|
||||
PRPackedBool mNotifiedDone;
|
||||
|
||||
/*
|
||||
* libpng callbacks
|
||||
|
@ -47,6 +47,7 @@ Decoder::Decoder()
|
||||
, mInitialized(false)
|
||||
, mSizeDecode(false)
|
||||
, mInFrame(false)
|
||||
, mDecodeDone(false)
|
||||
, mDataError(false)
|
||||
{
|
||||
}
|
||||
@ -97,7 +98,23 @@ Decoder::Finish()
|
||||
{
|
||||
// Implementation-specific finalization
|
||||
FinishInternal();
|
||||
return IsError() ? NS_ERROR_FAILURE : NS_OK;
|
||||
|
||||
// If the implementation left us mid-frame, finish that up.
|
||||
if (mInFrame)
|
||||
PostFrameStop();
|
||||
|
||||
if (IsError())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// If the implementation didn't post success, we assume failure
|
||||
if (!IsSizeDecode() && !mDecodeDone) {
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_ERROR_FAILURE, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
@ -200,6 +217,22 @@ Decoder::PostInvalidation(nsIntRect& aRect)
|
||||
mInvalidRect.UnionRect(mInvalidRect, aRect);
|
||||
}
|
||||
|
||||
void
|
||||
Decoder::PostDecodeDone()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!IsSizeDecode(), "Can't be done with decoding with size decode!");
|
||||
NS_ABORT_IF_FALSE(!mInFrame, "Can't be done decoding if we're mid-frame!");
|
||||
NS_ABORT_IF_FALSE(!mDecodeDone, "Decode already done!");
|
||||
mDecodeDone = true;
|
||||
|
||||
// Notify
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Decoder::PostDataError()
|
||||
{
|
||||
|
@ -153,6 +153,13 @@ protected:
|
||||
// actually pass these invalidations on right away.
|
||||
void PostInvalidation(nsIntRect& aRect);
|
||||
|
||||
// Called by the decoders when they have successfully decoded the image. This
|
||||
// may occur as the result of the decoder getting to the appropriate point in
|
||||
// the stream, or by us calling FinishInternal().
|
||||
//
|
||||
// May not be called mid-frame.
|
||||
void PostDecodeDone();
|
||||
|
||||
// Data errors are the fault of the source data, decoder errors are our fault
|
||||
void PostDataError();
|
||||
void PostDecoderError(nsresult aFailCode);
|
||||
@ -174,6 +181,7 @@ protected:
|
||||
bool mInitialized;
|
||||
bool mSizeDecode;
|
||||
bool mInFrame;
|
||||
bool mDecodeDone;
|
||||
bool mDataError;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user