Bug 716140 - Set metadata directly on frames. r=seth

--HG--
extra : rebase_source : d3899816bb6b5f816955a53c2cd7ad1bf8ad788a
This commit is contained in:
Joe Drew 2013-02-27 14:23:08 -05:00
Родитель bcfc2cf2fa
Коммит d38580343a
5 изменённых файлов: 52 добавлений и 121 удалений

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

@ -316,7 +316,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
mContainedDecoder->SetObserver(mObserver);
mContainedDecoder->SetSizeDecode(IsSizeDecode());
mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength,
mColormap, mColormapSize);
mColormap, mColormapSize,
mCurrentFrame);
if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) {
return;
}
@ -386,7 +387,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
mContainedDecoder->SetObserver(mObserver);
mContainedDecoder->SetSizeDecode(IsSizeDecode());
mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength,
mColormap, mColormapSize);
mColormap, mColormapSize,
mCurrentFrame);
// The ICO format when containing a BMP does not include the 14 byte
// bitmap file header. To use the code of the BMP decoder we need to

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

@ -15,6 +15,7 @@ namespace image {
Decoder::Decoder(RasterImage &aImage)
: mImage(aImage)
, mCurrentFrame(nullptr)
, mImageData(nullptr)
, mColormap(nullptr)
, mDecodeFlags(0)
@ -60,7 +61,8 @@ Decoder::Init()
// parent decoder
void
Decoder::InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
uint32_t* colormap, uint32_t colormapSize)
uint32_t* colormap, uint32_t colormapSize,
imgFrame* currentFrame)
{
// No re-initializing
NS_ABORT_IF_FALSE(!mInitialized, "Can't re-initialize a decoder!");
@ -70,6 +72,7 @@ Decoder::InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
mImageDataLength = imageDataLength;
mColormap = colormap;
mColormapSize = colormapSize;
mCurrentFrame = currentFrame;
// Implementation-specific initialization
InitInternal();
@ -200,12 +203,12 @@ Decoder::AllocateFrame()
mNewFrameData.mHeight, mNewFrameData.mFormat,
mNewFrameData.mPaletteDepth,
&mImageData, &mImageDataLength,
&mColormap, &mColormapSize);
&mColormap, &mColormapSize, &mCurrentFrame);
} else {
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
mNewFrameData.mOffsetY, mNewFrameData.mWidth,
mNewFrameData.mHeight, mNewFrameData.mFormat,
&mImageData, &mImageDataLength);
&mImageData, &mImageDataLength, &mCurrentFrame);
}
if (NS_SUCCEEDED(rv)) {
@ -313,21 +316,24 @@ Decoder::PostFrameStop(RasterImage::FrameAlpha aFrameAlpha /* = RasterImage::kFr
{
// We should be mid-frame
NS_ABORT_IF_FALSE(mInFrame, "Stopping frame when we didn't start one!");
NS_ABORT_IF_FALSE(mCurrentFrame, "Stopping frame when we don't have one!");
// Update our state
mInFrame = false;
if (aFrameAlpha == RasterImage::kFrameOpaque) {
mImage.SetFrameHasNoAlpha(mFrameCount - 1);
mCurrentFrame->SetHasNoAlpha();
}
mImage.SetFrameDisposalMethod(mFrameCount - 1, aDisposalMethod);
mImage.SetFrameTimeout(mFrameCount - 1, aTimeout);
mImage.SetFrameBlendMethod(mFrameCount - 1, aBlendMethod);
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
mCurrentFrame->SetTimeout(aTimeout);
mCurrentFrame->SetBlendMethod(aBlendMethod);
// Flush any invalidations before we finish the frame
FlushInvalidations();
mCurrentFrame = nullptr;
// Fire notifications
if (mObserver) {
mObserver->OnStopFrame();
@ -343,9 +349,11 @@ Decoder::PostInvalidation(nsIntRect& aRect)
{
// We should be mid-frame
NS_ABORT_IF_FALSE(mInFrame, "Can't invalidate when not mid-frame!");
NS_ABORT_IF_FALSE(mCurrentFrame, "Can't invalidate when not mid-frame!");
// Account for the new region
mInvalidRect.UnionRect(mInvalidRect, aRect);
mCurrentFrame->ImageUpdated(aRect);
}
void

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

@ -35,7 +35,8 @@ public:
* Notifications Sent: TODO
*/
void InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
uint32_t* colormap, uint32_t colormapSize);
uint32_t* colormap, uint32_t colormapSize,
imgFrame* currentFrame);
/**
* Writes data to the decoder.
@ -206,6 +207,7 @@ protected:
*
*/
RasterImage &mImage;
imgFrame* mCurrentFrame;
RefPtr<imgDecoderObserver> mObserver;
ImageMetadata mImageMetadata;

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

@ -1253,7 +1253,8 @@ RasterImage::DeleteImgFrame(uint32_t framenum)
nsresult
RasterImage::InternalAddFrameHelper(uint32_t framenum, imgFrame *aFrame,
uint8_t **imageData, uint32_t *imageLength,
uint32_t **paletteData, uint32_t *paletteLength)
uint32_t **paletteData, uint32_t *paletteLength,
imgFrame** aRetFrame)
{
NS_ABORT_IF_FALSE(framenum <= mFrames.Length(), "Invalid frame index!");
if (framenum > mFrames.Length())
@ -1270,11 +1271,13 @@ RasterImage::InternalAddFrameHelper(uint32_t framenum, imgFrame *aFrame,
frame->GetImageData(imageData, imageLength);
*aRetFrame = frame;
mFrames.InsertElementAt(framenum, frame.forget());
return NS_OK;
}
nsresult
RasterImage::InternalAddFrame(uint32_t framenum,
int32_t aX, int32_t aY,
@ -1284,7 +1287,8 @@ RasterImage::InternalAddFrame(uint32_t framenum,
uint8_t **imageData,
uint32_t *imageLength,
uint32_t **paletteData,
uint32_t *paletteLength)
uint32_t *paletteLength,
imgFrame** aRetFrame)
{
// We assume that we're in the middle of decoding because we unlock the
// previous frame when we create a new frame, and only when decoding do we
@ -1309,7 +1313,7 @@ RasterImage::InternalAddFrame(uint32_t framenum,
if (mFrames.Length() == 0) {
return InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength,
paletteData, paletteLength);
paletteData, paletteLength, aRetFrame);
}
if (mFrames.Length() == 1) {
@ -1333,7 +1337,7 @@ RasterImage::InternalAddFrame(uint32_t framenum,
frameRect);
rv = InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength,
paletteData, paletteLength);
paletteData, paletteLength, aRetFrame);
// We may be able to start animating, if we now have enough frames
EvaluateAnimation();
@ -1400,13 +1404,15 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
gfxASurface::gfxImageFormat aFormat,
uint8_t aPaletteDepth,
uint8_t **imageData, uint32_t *imageLength,
uint32_t **paletteData, uint32_t *paletteLength)
uint32_t **paletteData, uint32_t *paletteLength,
imgFrame** aRetFrame)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ENSURE_ARG_POINTER(imageData);
NS_ENSURE_ARG_POINTER(imageLength);
NS_ENSURE_ARG_POINTER(aRetFrame);
NS_ABORT_IF_FALSE(aFrameNum <= mFrames.Length(), "Invalid frame index!");
if (aPaletteDepth > 0) {
@ -1421,13 +1427,13 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
if (aFrameNum == mFrames.Length())
return InternalAddFrame(aFrameNum, aX, aY, aWidth, aHeight, aFormat,
aPaletteDepth, imageData, imageLength,
paletteData, paletteLength);
paletteData, paletteLength, aRetFrame);
imgFrame *frame = GetImgFrame(aFrameNum);
if (!frame)
return InternalAddFrame(aFrameNum, aX, aY, aWidth, aHeight, aFormat,
aPaletteDepth, imageData, imageLength,
paletteData, paletteLength);
paletteData, paletteLength, aRetFrame);
// See if we can re-use the frame that already exists.
nsIntRect rect = frame->GetRect();
@ -1439,6 +1445,8 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
frame->GetPaletteData(paletteData, paletteLength);
}
*aRetFrame = frame;
// We can re-use the frame if it has image data.
if (*imageData && paletteData && *paletteData) {
return NS_OK;
@ -1460,19 +1468,22 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
nsresult rv = newFrame->Init(aX, aY, aWidth, aHeight, aFormat, aPaletteDepth);
NS_ENSURE_SUCCESS(rv, rv);
return InternalAddFrameHelper(aFrameNum, newFrame.forget(), imageData,
imageLength, paletteData, paletteLength);
imageLength, paletteData, paletteLength,
aRetFrame);
}
nsresult
RasterImage::EnsureFrame(uint32_t aFramenum, int32_t aX, int32_t aY,
int32_t aWidth, int32_t aHeight,
gfxASurface::gfxImageFormat aFormat,
uint8_t** imageData, uint32_t* imageLength)
uint8_t** imageData, uint32_t* imageLength,
imgFrame** aFrame)
{
return EnsureFrame(aFramenum, aX, aY, aWidth, aHeight, aFormat,
/* aPaletteDepth = */ 0, imageData, imageLength,
/* aPaletteData = */ nullptr,
/* aPaletteLength = */ nullptr);
/* aPaletteLength = */ nullptr,
aFrame);
}
void
@ -1491,84 +1502,6 @@ RasterImage::FrameUpdated(uint32_t aFrameNum, nsIntRect &aUpdatedRect)
}
}
nsresult
RasterImage::SetFrameDisposalMethod(uint32_t aFrameNum,
int32_t aDisposalMethod)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
if (aFrameNum >= mFrames.Length())
return NS_ERROR_INVALID_ARG;
imgFrame *frame = GetImgFrameNoDecode(aFrameNum);
NS_ABORT_IF_FALSE(frame,
"Calling SetFrameDisposalMethod on frame that doesn't exist!");
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
frame->SetFrameDisposalMethod(aDisposalMethod);
return NS_OK;
}
nsresult
RasterImage::SetFrameTimeout(uint32_t aFrameNum, int32_t aTimeout)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
if (aFrameNum >= mFrames.Length())
return NS_ERROR_INVALID_ARG;
imgFrame *frame = GetImgFrameNoDecode(aFrameNum);
NS_ABORT_IF_FALSE(frame, "Calling SetFrameTimeout on frame that doesn't exist!");
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
frame->SetTimeout(aTimeout);
return NS_OK;
}
nsresult
RasterImage::SetFrameBlendMethod(uint32_t aFrameNum, int32_t aBlendMethod)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
if (aFrameNum >= mFrames.Length())
return NS_ERROR_INVALID_ARG;
imgFrame *frame = GetImgFrameNoDecode(aFrameNum);
NS_ABORT_IF_FALSE(frame, "Calling SetFrameBlendMethod on frame that doesn't exist!");
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
frame->SetBlendMethod(aBlendMethod);
return NS_OK;
}
nsresult
RasterImage::SetFrameHasNoAlpha(uint32_t aFrameNum)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ABORT_IF_FALSE(aFrameNum < mFrames.Length(), "Invalid frame index!");
if (aFrameNum >= mFrames.Length())
return NS_ERROR_INVALID_ARG;
imgFrame *frame = GetImgFrameNoDecode(aFrameNum);
NS_ABORT_IF_FALSE(frame, "Calling SetFrameHasNoAlpha on frame that doesn't exist!");
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
frame->SetHasNoAlpha();
return NS_OK;
}
nsresult
RasterImage::SetFrameAsNonPremult(uint32_t aFrameNum, bool aIsNonPremult)
{
@ -3464,19 +3397,6 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
}
}
// If it has any frames, tell the image what happened to the most recent
// one. This will be better when frames are published to decoders instead of
// decoders requesting them.
if (image->GetNumFrames()) {
nsIntRect rect;
if (request) {
rect = request->mStatusTracker->GetInvalidRect();
} else {
rect = image->CurrentStatusTracker().GetInvalidRect();
}
image->FrameUpdated(image->GetNumFrames() - 1, rect);
}
// Then, tell the observers what happened in the decoder.
// If we have no request, we have not yet created a decoder, but we still
// need to send out notifications.

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

@ -184,11 +184,6 @@ public:
void ForceDiscard() { Discard(/* force = */ true); }
/* Callbacks for decoders */
nsresult SetFrameDisposalMethod(uint32_t aFrameNum,
int32_t aDisposalMethod);
nsresult SetFrameTimeout(uint32_t aFrameNum, int32_t aTimeout);
nsresult SetFrameBlendMethod(uint32_t aFrameNum, int32_t aBlendMethod);
nsresult SetFrameHasNoAlpha(uint32_t aFrameNum);
nsresult SetFrameAsNonPremult(uint32_t aFrameNum, bool aIsNonPremult);
/**
@ -212,7 +207,8 @@ public:
uint8_t** imageData,
uint32_t* imageLength,
uint32_t** paletteData,
uint32_t* paletteLength);
uint32_t* paletteLength,
imgFrame** aFrame);
/**
* A shorthand for EnsureFrame, above, with aPaletteDepth = 0 and paletteData
@ -222,7 +218,8 @@ public:
int32_t aWidth, int32_t aHeight,
gfxASurface::gfxImageFormat aFormat,
uint8_t** imageData,
uint32_t* imageLength);
uint32_t* imageLength,
imgFrame** aFrame);
void FrameUpdated(uint32_t aFrameNum, nsIntRect& aUpdatedRect);
@ -664,11 +661,13 @@ private:
nsresult InternalAddFrameHelper(uint32_t framenum, imgFrame *frame,
uint8_t **imageData, uint32_t *imageLength,
uint32_t **paletteData, uint32_t *paletteLength);
uint32_t **paletteData, uint32_t *paletteLength,
imgFrame** aRetFrame);
nsresult InternalAddFrame(uint32_t framenum, int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
gfxASurface::gfxImageFormat aFormat, uint8_t aPaletteDepth,
uint8_t **imageData, uint32_t *imageLength,
uint32_t **paletteData, uint32_t *paletteLength);
uint32_t **paletteData, uint32_t *paletteLength,
imgFrame** aRetFrame);
nsresult DoImageDataComplete();