зеркало из https://github.com/mozilla/gecko-dev.git
Bug 513681 - part 13 - switch from "HEADERONLY" flag to IsSizeDecode()/SetSizeDecode().r=joe,a=blocker
This commit is contained in:
Родитель
157e0862fb
Коммит
24cf517be4
|
@ -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();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче