Bug 399925 - "GIF decoder needs to allow its data to be discarded" [p=alfredkayser@gmail.com (Alfred Kayser) r=stuart sr=tor a=blocking1.9+]

This commit is contained in:
reed@reedloden.com 2008-03-09 22:09:24 -07:00
Родитель 9ee8cb0d7c
Коммит 68ac33c026
2 изменённых файлов: 25 добавлений и 7 удалений

Просмотреть файл

@ -142,8 +142,18 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
{ {
mObserver = do_QueryInterface(aLoad); mObserver = do_QueryInterface(aLoad);
/* The image container may already exist if it is reloading itself from us.
*/
aLoad->GetImage(getter_AddRefs(mImageContainer));
if (!mImageContainer) {
mImageContainer = do_CreateInstance("@mozilla.org/image/container;1"); mImageContainer = do_CreateInstance("@mozilla.org/image/container;1");
if (!mImageContainer)
return NS_ERROR_OUT_OF_MEMORY;
aLoad->SetImage(mImageContainer); aLoad->SetImage(mImageContainer);
nsresult rv = mImageContainer->SetDiscardable("image/gif");
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
}
// Start with the version (GIF89a|GIF87a) // Start with the version (GIF89a|GIF87a)
mGIFStruct.state = gif_type; mGIFStruct.state = gif_type;
@ -174,7 +184,7 @@ NS_IMETHODIMP nsGIFDecoder2::Close()
/* void flush (); */ /* void flush (); */
NS_IMETHODIMP nsGIFDecoder2::Flush() NS_IMETHODIMP nsGIFDecoder2::Flush()
{ {
return NS_ERROR_NOT_IMPLEMENTED; return NS_OK;
} }
//****************************************************************************** //******************************************************************************
@ -187,7 +197,7 @@ static NS_METHOD ReadDataOut(nsIInputStream* in,
PRUint32 *writeCount) PRUint32 *writeCount)
{ {
nsGIFDecoder2 *decoder = static_cast<nsGIFDecoder2*>(closure); nsGIFDecoder2 *decoder = static_cast<nsGIFDecoder2*>(closure);
nsresult rv = decoder->ProcessData((unsigned char*)fromRawSegment, count, writeCount); nsresult rv = decoder->ProcessData(fromRawSegment, count, writeCount);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
*writeCount = 0; *writeCount = 0;
return rv; return rv;
@ -236,11 +246,11 @@ nsGIFDecoder2::FlushImageData()
} }
//****************************************************************************** //******************************************************************************
nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint32 *_retval) nsresult nsGIFDecoder2::ProcessData(const char *data, PRUint32 count, PRUint32 *_retval)
{ {
// Push the data to the GIF decoder // Push the data to the GIF decoder
nsresult rv = GifWrite(data, count); nsresult rv = GifWrite((const PRUint8*)data, count);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Flushing is only needed for first frame // Flushing is only needed for first frame
@ -250,6 +260,13 @@ nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint3
mLastFlushedPass = mCurrentPass; mLastFlushedPass = mCurrentPass;
} }
// We should just disable the 'restore' when AddRestoreData fails, so that we still load the image...
rv = mImageContainer->AddRestoreData(data, count);
if (NS_FAILED(rv)) {
mGIFStruct.state = gif_oom;
return rv;
}
*_retval = count; *_retval = count;
return NS_OK; return NS_OK;
@ -310,6 +327,7 @@ void nsGIFDecoder2::EndGIF()
mImageContainer->SetLoopCount(mGIFStruct.loop_count); mImageContainer->SetLoopCount(mGIFStruct.loop_count);
mImageContainer->DecodingComplete(); mImageContainer->DecodingComplete();
(void)mImageContainer->RestoreDataDone(); // Discard error code
mGIFOpen = PR_FALSE; mGIFOpen = PR_FALSE;
} }

Просмотреть файл

@ -68,7 +68,7 @@ public:
nsGIFDecoder2(); nsGIFDecoder2();
~nsGIFDecoder2(); ~nsGIFDecoder2();
nsresult ProcessData(unsigned char *data, PRUint32 count, PRUint32 *_retval); nsresult ProcessData(const char *data, PRUint32 count, PRUint32 *_retval);
private: private:
/* These functions will be called when the decoder has a decoded row, /* These functions will be called when the decoder has a decoded row,