Bug 513681 - part 13 - switch from "HEADERONLY" flag to IsSizeDecode()/SetSizeDecode().r=joe,a=blocker

This commit is contained in:
Bobby Holley 2010-08-22 22:30:46 -04:00
Родитель 157e0862fb
Коммит 24cf517be4
12 изменённых файлов: 74 добавлений и 86 удалений

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

@ -87,7 +87,7 @@ nsBMPDecoder::InitInternal()
PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", mImage.get())); PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", mImage.get()));
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
return NS_OK; return NS_OK;
@ -99,7 +99,7 @@ nsBMPDecoder::ShutdownInternal(PRUint32 aFlags)
PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Close()\n")); PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Close()\n"));
// Send notifications if appropriate // Send notifications if appropriate
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && if (!IsSizeDecode() &&
!mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) {
if (mObserver) if (mObserver)
mObserver->OnStopFrame(nsnull, 0); mObserver->OnStopFrame(nsnull, 0);
@ -220,9 +220,9 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
// We have the size. If we're doing a header-only decode, we got what // We have the size. If we're doing a size decode, we got what
// we came for. // we came for.
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) if (IsSizeDecode())
return NS_OK; return NS_OK;
// We're doing a real decode. // We're doing a real decode.

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

@ -132,7 +132,7 @@ nsresult
nsGIFDecoder2::InitInternal() nsGIFDecoder2::InitInternal()
{ {
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
// Start with the version (GIF89a|GIF87a) // Start with the version (GIF89a|GIF87a)
@ -146,7 +146,7 @@ nsresult
nsGIFDecoder2::ShutdownInternal(PRUint32 aFlags) nsGIFDecoder2::ShutdownInternal(PRUint32 aFlags)
{ {
// Send notifications if appropriate // Send notifications if appropriate
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && if (!IsSizeDecode() &&
!mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) {
if (mCurrentFrame == mGIFStruct.images_decoded) if (mCurrentFrame == mGIFStruct.images_decoded)
EndImageFrame(); EndImageFrame();
@ -260,8 +260,8 @@ void nsGIFDecoder2::BeginGIF()
if (mObserver) if (mObserver)
mObserver->OnStartContainer(nsnull, mImage); mObserver->OnStartContainer(nsnull, mImage);
// If we're doing a header-only decode, we have what we came for // If we're doing a size decode, we have what we came for
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) if (IsSizeDecode())
return; return;
} }
@ -1020,8 +1020,8 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
// Create the image container with the right size. // Create the image container with the right size.
BeginGIF(); BeginGIF();
// If we were doing header-only, we're done // If we were doing a size decode, we're done
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) if (IsSizeDecode())
return NS_OK; return NS_OK;
} }

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

@ -90,7 +90,7 @@ nsresult
nsICODecoder::InitInternal() nsICODecoder::InitInternal()
{ {
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
return NS_OK; return NS_OK;
@ -102,7 +102,7 @@ nsICODecoder::ShutdownInternal(PRUint32 aFlags)
nsresult rv = NS_OK; nsresult rv = NS_OK;
// Send notifications if appropriate // Send notifications if appropriate
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && if (!IsSizeDecode() &&
!mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) {
// Tell the image that it's data has been updated // Tell the image that it's data has been updated
nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight); nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight);
@ -240,7 +240,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
rv = mObserver->OnStartContainer(nsnull, mImage); rv = mObserver->OnStartContainer(nsnull, mImage);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) if (IsSizeDecode())
return NS_OK; return NS_OK;
if (mBIH.bpp <= 8) { if (mBIH.bpp <= 8) {

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

@ -70,7 +70,7 @@ nsresult
nsIconDecoder::InitInternal() nsIconDecoder::InitInternal()
{ {
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
return NS_OK; return NS_OK;
@ -82,7 +82,7 @@ nsIconDecoder::ShutdownInternal(PRUint32 aFlags)
// If we haven't notified of completion yet for a full/success decode, we // If we haven't notified of completion yet for a full/success decode, we
// didn't finish. Notify in error mode // didn't finish. Notify in error mode
if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) &&
!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !IsSizeDecode() &&
!mNotifiedDone) !mNotifiedDone)
NotifyDone(/* aSuccess = */ PR_FALSE); NotifyDone(/* aSuccess = */ PR_FALSE);
@ -126,8 +126,8 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
if (mObserver) if (mObserver)
mObserver->OnStartContainer(nsnull, mImage); mObserver->OnStartContainer(nsnull, mImage);
// If We're doing a header-only decode, we're done // If We're doing a size decode, we're done
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { if (IsSizeDecode()) {
mState = iconStateFinished; mState = iconStateFinished;
break; break;
} }

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

@ -139,7 +139,7 @@ nsresult
nsJPEGDecoder::InitInternal() nsJPEGDecoder::InitInternal()
{ {
/* Fire OnStartDecode at init time to support bug 512435 */ /* Fire OnStartDecode at init time to support bug 512435 */
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
/* We set up the normal JPEG error routines, then override error_exit. */ /* We set up the normal JPEG error routines, then override error_exit. */
@ -189,7 +189,7 @@ nsJPEGDecoder::ShutdownInternal(PRUint32 aFlags)
*/ */
if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) && if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
(mState != JPEG_ERROR) && (mState != JPEG_ERROR) &&
!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !IsSizeDecode() &&
!(aFlags & CLOSE_FLAG_DONTNOTIFY)) !(aFlags & CLOSE_FLAG_DONTNOTIFY))
this->Write(nsnull, 0); this->Write(nsnull, 0);
@ -206,7 +206,7 @@ nsJPEGDecoder::ShutdownInternal(PRUint32 aFlags)
/* If we're doing a full decode and haven't notified of completion yet, /* 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. */ * we must not have got everything we wanted. Send error notifications. */
if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) &&
!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !IsSizeDecode() &&
!mNotifiedDone) !mNotifiedDone)
NotifyDone(/* aSuccess = */ PR_FALSE); NotifyDone(/* aSuccess = */ PR_FALSE);
@ -261,8 +261,8 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
if (mObserver) if (mObserver)
mObserver->OnStartContainer(nsnull, mImage); mObserver->OnStartContainer(nsnull, mImage);
/* If we're doing a header-only decode, we're done. */ /* If we're doing a size decode, we're done. */
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) if (IsSizeDecode())
return NS_OK; return NS_OK;
/* We're doing a full decode. */ /* We're doing a full decode. */

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

@ -71,7 +71,7 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog =
/* limit image dimensions (bug #251381) */ /* limit image dimensions (bug #251381) */
#define MOZ_PNG_MAX_DIMENSION 1000000L #define MOZ_PNG_MAX_DIMENSION 1000000L
// For header-only decodes // For size decodes
#define WIDTH_OFFSET 16 #define WIDTH_OFFSET 16
#define HEIGHT_OFFSET (WIDTH_OFFSET + 4) #define HEIGHT_OFFSET (WIDTH_OFFSET + 4)
#define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4) #define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4)
@ -242,11 +242,11 @@ nsPNGDecoder::InitInternal()
#endif #endif
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) if (!IsSizeDecode() && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
// For header-only decodes, we only need a small buffer // For size decodes, we only need a small buffer
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { if (IsSizeDecode()) {
mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS); mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS);
if (!mHeaderBuf) if (!mHeaderBuf)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -303,7 +303,7 @@ nsPNGDecoder::ShutdownInternal(PRUint32 aFlags)
// If we're a full/success decode but haven't sent stop notifications yet, // 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. // we didn't get all the data we needed. Send error notifications.
if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) &&
!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !IsSizeDecode() &&
!mNotifiedDone) !mNotifiedDone)
NotifyDone(/* aSuccess = */ PR_FALSE); NotifyDone(/* aSuccess = */ PR_FALSE);
@ -323,7 +323,7 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
goto error; goto error;
// If we only want width/height, we don't need to go through libpng // If we only want width/height, we don't need to go through libpng
if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { if (IsSizeDecode()) {
// Are we done? // Are we done?
if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS) if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS)

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

@ -86,7 +86,7 @@ public:
gfxASurface::gfxImageFormat format; gfxASurface::gfxImageFormat format;
// For header-only decodes // For size decodes
PRUint8 *mHeaderBuf; PRUint8 *mHeaderBuf;
PRUint32 mHeaderBytesRead; PRUint32 mHeaderBytesRead;

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

@ -54,20 +54,6 @@ interface imgIDecoderObserver;
[scriptable, uuid(6fc61088-5443-4539-9e24-629a266a800a)] [scriptable, uuid(6fc61088-5443-4539-9e24-629a266a800a)]
interface imgIDecoder : nsISupports interface imgIDecoder : nsISupports
{ {
/**
* Bits that can be passed to the decoder to affect decoding.
* @name decodeflags
*
* Meanings:
*
* DECODER_FLAG_NONE: No flags
*
* DECODER_FLAG_HEADERONLY: Read basic data from the image in order to
* set up the image container, but don't read any actual image data.
*/
const long DECODER_FLAG_NONE = 0x0;
const long DECODER_FLAG_HEADERONLY = 0x1;
/** /**
* Initialize an image decoder. * Initialize an image decoder.
* @param aContainer The image container to decode to. * @param aContainer The image container to decode to.

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

@ -70,6 +70,7 @@ NS_IMETHODIMP Decoder::Flush()
Decoder::Decoder() Decoder::Decoder()
: mInitialized(false) : mInitialized(false)
, mSizeDecode(false)
{ {
} }
@ -83,8 +84,7 @@ Decoder::~Decoder()
*/ */
nsresult nsresult
Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver, Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver)
PRUint32 aFlags)
{ {
// We should always have an image // We should always have an image
NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!"); NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!");
@ -92,7 +92,6 @@ Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver,
// Save our paremeters // Save our paremeters
mImage = aImage; mImage = aImage;
mObserver = aObserver; mObserver = aObserver;
mFlags = aFlags;
// Implementation-specific initialization // Implementation-specific initialization
nsresult rv = InitInternal(); nsresult rv = InitInternal();

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

@ -68,12 +68,10 @@ public:
* *
* @param aContainer The image container to decode to. * @param aContainer The image container to decode to.
* @param aObserver The observer for decode notification events. * @param aObserver The observer for decode notification events.
* @param aFlags Flags for the decoder
* *
* Notifications Sent: TODO * Notifications Sent: TODO
*/ */
nsresult Init(RasterImage* aImage, imgIDecoderObserver* aObserver, nsresult Init(RasterImage* aImage, imgIDecoderObserver* aObserver);
PRUint32 aFlags);
/** /**
* Writes data to the decoder. * Writes data to the decoder.
@ -109,6 +107,20 @@ public:
// XXX - This is uncommented in a later patch when we stop inheriting imgIDecoder // XXX - This is uncommented in a later patch when we stop inheriting imgIDecoder
// NS_INLINE_DECL_REFCOUNTING(Decoder) // NS_INLINE_DECL_REFCOUNTING(Decoder)
/*
* State.
*/
// If we're doing a "size decode", we more or less pass through the image
// data, stopping only to scoop out the image dimensions. A size decode
// must be enabled by SetSizeDecode() _before_calling Init().
bool IsSizeDecode() { return mSizeDecode; };
void SetSizeDecode(bool aSizeDecode)
{
NS_ABORT_IF_FALSE(!mInitialized, "Can't set size decode after Init()!");
mSizeDecode = aSizeDecode;
}
protected: protected:
/* /*
@ -127,9 +139,9 @@ protected:
*/ */
nsRefPtr<RasterImage> mImage; nsRefPtr<RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver; nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
bool mInitialized; bool mInitialized;
bool mSizeDecode;
}; };
} // namespace imagelib } // namespace imagelib

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

@ -159,7 +159,6 @@ RasterImage::RasterImage() :
mDecoder(nsnull), mDecoder(nsnull),
mWorker(nsnull), mWorker(nsnull),
mBytesDecoded(0), mBytesDecoded(0),
mDecoderFlags(imgIDecoder::DECODER_FLAG_NONE),
mHasSize(PR_FALSE), mHasSize(PR_FALSE),
mDecodeOnDraw(PR_FALSE), mDecodeOnDraw(PR_FALSE),
mMultipart(PR_FALSE), mMultipart(PR_FALSE),
@ -261,16 +260,12 @@ RasterImage::Init(imgIDecoderObserver *aObserver,
return NS_OK; return NS_OK;
} }
// Determine our decoder flags. If we're doing decode-on-draw,
// we want to do a quick first pass to get the size but nothing
// else. We instantiate another decoder later to do the full
// decoding.
PRUint32 dFlags = imgIDecoder::DECODER_FLAG_NONE;
if (mDecodeOnDraw)
dFlags |= imgIDecoder::DECODER_FLAG_HEADERONLY;
// Instantiate the decoder // Instantiate the decoder
nsresult rv = InitDecoder(dFlags); //
// If we're doing decode-on-draw, we want to do a quick first pass to get
// the size but nothing else. We instantiate another decoder later to do
// the full decoding.
nsresult rv = InitDecoder(/* aDoSizeDecode = */ mDecodeOnDraw);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
// Mark us as initialized // Mark us as initialized
@ -1396,7 +1391,7 @@ RasterImage::NewSourceData()
// We're decode-on-load here. Open up a new decoder just like what happens when // We're decode-on-load here. Open up a new decoder just like what happens when
// we call Init() for decode-on-load images. // we call Init() for decode-on-load images.
rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); rv = InitDecoder(/* aDoSizeDecode = */ false);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
return NS_OK; return NS_OK;
@ -2103,7 +2098,7 @@ RasterImage::StoringSourceData() {
// Sets up a decoder for this image. It is an error to call this function // Sets up a decoder for this image. It is an error to call this function
// when decoding is already in process (ie - when mDecoder is non-null). // when decoding is already in process (ie - when mDecoder is non-null).
nsresult nsresult
RasterImage::InitDecoder(PRUint32 dFlags) RasterImage::InitDecoder(bool aDoSizeDecode)
{ {
// Ensure that the decoder is not already initialized // Ensure that the decoder is not already initialized
NS_ABORT_IF_FALSE(!mDecoder, "Calling InitDecoder() while already decoding!"); NS_ABORT_IF_FALSE(!mDecoder, "Calling InitDecoder() while already decoding!");
@ -2142,12 +2137,10 @@ RasterImage::InitDecoder(PRUint32 dFlags)
NS_ABORT_IF_FALSE(0, "Shouldn't get here!"); NS_ABORT_IF_FALSE(0, "Shouldn't get here!");
} }
// Store the flags for this decoder
mDecoderFlags = dFlags;
// Initialize the decoder // Initialize the decoder
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver)); nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
nsresult result = mDecoder->Init(this, observer, dFlags); mDecoder->SetSizeDecode(aDoSizeDecode);
nsresult result = mDecoder->Init(this, observer);
CONTAINER_ENSURE_SUCCESS(result); CONTAINER_ENSURE_SUCCESS(result);
// Create a decode worker // Create a decode worker
@ -2175,6 +2168,9 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
// Ensure that the decoder is initialized // Ensure that the decoder is initialized
NS_ABORT_IF_FALSE(mDecoder, "Calling ShutdownDecoder() with no active decoder!"); NS_ABORT_IF_FALSE(mDecoder, "Calling ShutdownDecoder() with no active decoder!");
// Figure out what kind of decode we were doing before we get rid of our decoder
bool wasSizeDecode = mDecoder->IsSizeDecode();
// Close the decoder with the appropriate flags // Close the decoder with the appropriate flags
mInDecoder = PR_TRUE; mInDecoder = PR_TRUE;
PRUint32 closeFlags = (aIntent == eShutdownIntent_Error) PRUint32 closeFlags = (aIntent == eShutdownIntent_Error)
@ -2197,18 +2193,15 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
// We just shut down the decoder. If we didn't get what we want, but expected // We just shut down the decoder. If we didn't get what we want, but expected
// to, flag an error // to, flag an error
PRBool failed = PR_FALSE; PRBool failed = PR_FALSE;
if ((mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mHasSize) if (wasSizeDecode && !mHasSize)
failed = PR_TRUE; failed = PR_TRUE;
if (!(mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mDecoded) if (!wasSizeDecode && !mDecoded)
failed = PR_TRUE; failed = PR_TRUE;
if ((aIntent == eShutdownIntent_Done) && failed) { if ((aIntent == eShutdownIntent_Done) && failed) {
DoError(); DoError();
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Clear the flags
mDecoderFlags = imgIDecoder::DECODER_FLAG_NONE;
// Reset number of decoded bytes // Reset number of decoded bytes
mBytesDecoded = 0; mBytesDecoded = 0;
@ -2295,11 +2288,11 @@ RasterImage::RequestDecode()
return NS_OK; return NS_OK;
// If we've already got a full decoder running, we have nothing to do // If we've already got a full decoder running, we have nothing to do
if (mDecoder && !(mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) if (mDecoder && !mDecoder->IsSizeDecode())
return NS_OK; return NS_OK;
// If our callstack goes through a header-only decoder, we have a problem. // If our callstack goes through a size decoder, we have a problem.
// We need to shutdown the header-only decoder and replace it with a full // We need to shutdown the size decode and replace it with a full
// decoder, but can't do that from within the decoder itself. Thus, we post // decoder, but can't do that from within the decoder itself. Thus, we post
// an asynchronous event to the event loop to do it later. Since // an asynchronous event to the event loop to do it later. Since
// RequestDecode() is an asynchronous function this works fine (though it's // RequestDecode() is an asynchronous function this works fine (though it's
@ -2312,8 +2305,8 @@ RasterImage::RequestDecode()
} }
// If we have a header-only decoder open, interrupt it and shut it down // If we have a size decode open, interrupt it and shut it down
if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) { if (mDecoder && mDecoder->IsSizeDecode()) {
rv = ShutdownDecoder(eShutdownIntent_Interrupted); rv = ShutdownDecoder(eShutdownIntent_Interrupted);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2321,7 +2314,7 @@ RasterImage::RequestDecode()
// If we don't have a decoder, create one // If we don't have a decoder, create one
if (!mDecoder) { if (!mDecoder) {
NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array");
rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); rv = InitDecoder(/* aDoSizeDecode = */ false);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2359,8 +2352,8 @@ RasterImage::SyncDecode()
// disallow this type of call in the API, and check for it in API methods. // disallow this type of call in the API, and check for it in API methods.
NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!"); NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!");
// If we have a header-only decoder open, shut it down // If we have a size decode open, shut it down
if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) { if (mDecoder && mDecoder->IsSizeDecode()) {
rv = ShutdownDecoder(eShutdownIntent_Interrupted); rv = ShutdownDecoder(eShutdownIntent_Interrupted);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2368,7 +2361,7 @@ RasterImage::SyncDecode()
// If we don't have a decoder, create one // If we don't have a decoder, create one
if (!mDecoder) { if (!mDecoder) {
NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array");
rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); rv = InitDecoder(/* aDoSizeDecode = */ false);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2518,7 +2511,7 @@ RasterImage::IsDecodeFinished()
"just shut down on SourceDataComplete!"); "just shut down on SourceDataComplete!");
// The decode is complete if we got what we wanted... // The decode is complete if we got what we wanted...
if (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { if (mDecoder->IsSizeDecode()) {
if (mHasSize) if (mHasSize)
decodeFinished = PR_TRUE; decodeFinished = PR_TRUE;
} }
@ -2606,11 +2599,10 @@ imgDecodeWorker::Run()
if (!image->mDecoder) if (!image->mDecoder)
return NS_OK; return NS_OK;
// Header-only decodes are cheap and we more or less want them to be // Size decodes are cheap and we more or less want them to be
// synchronous. Write all the data in that case, otherwise write a // synchronous. Write all the data in that case, otherwise write a
// chunk // chunk
PRUint32 maxBytes = PRUint32 maxBytes = image->mDecoder->IsSizeDecode()
(image->mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME; ? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME;
// Loop control // Loop control

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

@ -462,7 +462,6 @@ private: // data
nsRefPtr<Decoder> mDecoder; nsRefPtr<Decoder> mDecoder;
nsRefPtr<imgDecodeWorker> mWorker; nsRefPtr<imgDecodeWorker> mWorker;
PRUint32 mBytesDecoded; PRUint32 mBytesDecoded;
PRUint32 mDecoderFlags;
// Boolean flags (clustered together to conserve space): // Boolean flags (clustered together to conserve space):
PRPackedBool mHasSize:1; // Has SetSize() been called? PRPackedBool mHasSize:1; // Has SetSize() been called?
@ -484,7 +483,7 @@ private: // data
// Decoding // Decoding
nsresult WantDecodedFrames(); nsresult WantDecodedFrames();
nsresult SyncDecode(); nsresult SyncDecode();
nsresult InitDecoder(PRUint32 dFlags); nsresult InitDecoder(bool aDoSizeDecode);
nsresult WriteToDecoder(const char *aBuffer, PRUint32 aCount); nsresult WriteToDecoder(const char *aBuffer, PRUint32 aCount);
nsresult DecodeSomeData(PRUint32 aMaxBytes); nsresult DecodeSomeData(PRUint32 aMaxBytes);
PRBool IsDecodeFinished(); PRBool IsDecodeFinished();