2010-08-22 19:30:45 -07:00
|
|
|
|
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-08-22 19:30:45 -07:00
|
|
|
|
|
|
|
#include "Decoder.h"
|
2010-09-12 08:22:31 -07:00
|
|
|
#include "nsIConsoleService.h"
|
2010-12-20 08:21:59 -08:00
|
|
|
#include "nsIScriptError.h"
|
2013-03-18 07:25:50 -07:00
|
|
|
#include "GeckoProfiler.h"
|
2013-09-07 06:01:08 -07:00
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "nsComponentManagerUtils.h"
|
2010-08-22 19:30:45 -07:00
|
|
|
|
|
|
|
namespace mozilla {
|
2012-01-06 08:02:27 -08:00
|
|
|
namespace image {
|
2010-08-22 19:30:45 -07:00
|
|
|
|
2013-01-18 13:47:18 -08:00
|
|
|
Decoder::Decoder(RasterImage &aImage)
|
2011-09-29 06:17:13 -07:00
|
|
|
: mImage(aImage)
|
2013-02-27 11:23:08 -08:00
|
|
|
, mCurrentFrame(nullptr)
|
2014-11-14 20:10:47 -08:00
|
|
|
, mProgress(NoProgress)
|
2013-01-28 09:26:36 -08:00
|
|
|
, mImageData(nullptr)
|
|
|
|
, mColormap(nullptr)
|
2011-09-29 06:17:13 -07:00
|
|
|
, mDecodeFlags(0)
|
2014-10-15 13:52:20 -07:00
|
|
|
, mBytesDecoded(0)
|
2012-01-02 12:23:41 -08:00
|
|
|
, mDecodeDone(false)
|
|
|
|
, mDataError(false)
|
2011-01-12 17:45:13 -08:00
|
|
|
, mFrameCount(0)
|
2010-09-12 08:22:27 -07:00
|
|
|
, mFailCode(NS_OK)
|
2013-01-28 09:27:35 -08:00
|
|
|
, mNeedsNewFrame(false)
|
2010-08-22 19:30:46 -07:00
|
|
|
, mInitialized(false)
|
2010-08-22 19:30:46 -07:00
|
|
|
, mSizeDecode(false)
|
2010-08-22 19:30:46 -07:00
|
|
|
, mInFrame(false)
|
2011-11-09 13:39:16 -08:00
|
|
|
, mIsAnimated(false)
|
2014-11-14 20:06:19 -08:00
|
|
|
{ }
|
2010-08-22 19:30:45 -07:00
|
|
|
|
|
|
|
Decoder::~Decoder()
|
|
|
|
{
|
|
|
|
mInitialized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common implementation of the decoder interface.
|
|
|
|
*/
|
|
|
|
|
2010-09-12 08:22:31 -07:00
|
|
|
void
|
2011-09-27 09:24:03 -07:00
|
|
|
Decoder::Init()
|
2010-08-22 19:30:45 -07:00
|
|
|
{
|
2010-08-22 19:30:46 -07:00
|
|
|
// No re-initializing
|
2011-09-27 09:24:03 -07:00
|
|
|
NS_ABORT_IF_FALSE(!mInitialized, "Can't re-initialize a decoder!");
|
2010-08-22 19:30:45 -07:00
|
|
|
|
2013-01-25 18:39:11 -08:00
|
|
|
// Fire OnStartDecode at init time to support bug 512435.
|
2014-11-14 20:06:19 -08:00
|
|
|
if (!IsSizeDecode()) {
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED;
|
2014-11-14 20:06:19 -08:00
|
|
|
}
|
2013-01-25 18:39:11 -08:00
|
|
|
|
2010-08-22 19:30:45 -07:00
|
|
|
// Implementation-specific initialization
|
2010-09-12 08:22:28 -07:00
|
|
|
InitInternal();
|
2013-02-01 17:06:30 -08:00
|
|
|
|
2010-08-22 19:30:45 -07:00
|
|
|
mInitialized = true;
|
|
|
|
}
|
|
|
|
|
2013-01-18 13:47:18 -08:00
|
|
|
// Initializes a decoder whose image and observer is already being used by a
|
2011-08-25 13:09:01 -07:00
|
|
|
// parent decoder
|
2011-09-27 09:24:03 -07:00
|
|
|
void
|
2013-02-01 17:06:30 -08:00
|
|
|
Decoder::InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
|
2013-02-27 11:23:08 -08:00
|
|
|
uint32_t* colormap, uint32_t colormapSize,
|
|
|
|
imgFrame* currentFrame)
|
2011-08-25 13:09:01 -07:00
|
|
|
{
|
|
|
|
// No re-initializing
|
2011-09-27 09:24:03 -07:00
|
|
|
NS_ABORT_IF_FALSE(!mInitialized, "Can't re-initialize a decoder!");
|
2013-02-01 17:06:30 -08:00
|
|
|
|
|
|
|
mImageData = imageData;
|
|
|
|
mImageDataLength = imageDataLength;
|
|
|
|
mColormap = colormap;
|
|
|
|
mColormapSize = colormapSize;
|
2013-02-27 11:23:08 -08:00
|
|
|
mCurrentFrame = currentFrame;
|
2013-02-27 11:23:08 -08:00
|
|
|
// We have all the frame data, so we've started the frame.
|
|
|
|
if (!IsSizeDecode()) {
|
|
|
|
PostFrameStart();
|
|
|
|
}
|
2011-08-25 13:09:01 -07:00
|
|
|
|
|
|
|
// Implementation-specific initialization
|
|
|
|
InitInternal();
|
|
|
|
mInitialized = true;
|
|
|
|
}
|
|
|
|
|
2010-09-12 08:22:31 -07:00
|
|
|
void
|
2013-12-17 14:04:24 -08:00
|
|
|
Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy)
|
2010-08-22 19:30:45 -07:00
|
|
|
{
|
2014-05-23 14:12:29 -07:00
|
|
|
PROFILER_LABEL("ImageDecoder", "Write",
|
|
|
|
js::ProfileEntry::Category::GRAPHICS);
|
|
|
|
|
2013-12-17 14:04:24 -08:00
|
|
|
MOZ_ASSERT(NS_IsMainThread() || aStrategy == DECODE_ASYNC);
|
2013-02-13 13:49:57 -08:00
|
|
|
|
2010-09-12 08:22:30 -07:00
|
|
|
// We're strict about decoder errors
|
2014-10-15 13:52:20 -07:00
|
|
|
MOZ_ASSERT(!HasDecoderError(),
|
|
|
|
"Not allowed to make more decoder calls after error!");
|
|
|
|
|
|
|
|
// Keep track of the total number of bytes written.
|
|
|
|
mBytesDecoded += aCount;
|
2010-09-12 08:22:30 -07:00
|
|
|
|
2014-10-15 16:00:12 -07:00
|
|
|
// If a data error occured, just ignore future data
|
2010-09-12 08:22:31 -07:00
|
|
|
if (HasDataError())
|
2010-09-12 08:22:31 -07:00
|
|
|
return;
|
2010-09-12 08:22:30 -07:00
|
|
|
|
2013-03-23 08:05:55 -07:00
|
|
|
if (IsSizeDecode() && HasSize()) {
|
|
|
|
// More data came in since we found the size. We have nothing to do here.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-08-22 19:30:45 -07:00
|
|
|
// Pass the data along to the implementation
|
2013-12-17 14:04:24 -08:00
|
|
|
WriteInternal(aBuffer, aCount, aStrategy);
|
2013-01-28 09:27:35 -08:00
|
|
|
|
2013-02-27 11:23:08 -08:00
|
|
|
// If we're a synchronous decoder and we need a new frame to proceed, let's
|
|
|
|
// create one and call it again.
|
2013-12-17 14:04:24 -08:00
|
|
|
while (aStrategy == DECODE_SYNC && NeedsNewFrame() && !HasDataError()) {
|
2013-02-01 17:06:30 -08:00
|
|
|
nsresult rv = AllocateFrame();
|
2013-01-28 09:27:35 -08:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Tell the decoder to use the data it saved when it asked for a new frame.
|
2013-12-17 14:04:24 -08:00
|
|
|
WriteInternal(nullptr, 0, aStrategy);
|
2013-01-28 09:27:35 -08:00
|
|
|
}
|
|
|
|
}
|
2010-08-22 19:30:45 -07:00
|
|
|
}
|
|
|
|
|
2010-09-12 08:22:31 -07:00
|
|
|
void
|
2012-11-16 11:43:24 -08:00
|
|
|
Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent)
|
2010-08-22 19:30:45 -07:00
|
|
|
{
|
2013-12-17 14:04:24 -08:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2010-08-22 19:30:45 -07:00
|
|
|
// Implementation-specific finalization
|
2010-09-12 08:22:31 -07:00
|
|
|
if (!HasError())
|
2010-09-12 08:22:30 -07:00
|
|
|
FinishInternal();
|
2010-09-12 08:22:30 -07:00
|
|
|
|
|
|
|
// If the implementation left us mid-frame, finish that up.
|
2013-02-27 11:23:08 -08:00
|
|
|
if (mInFrame && !HasError())
|
2010-09-12 08:22:30 -07:00
|
|
|
PostFrameStop();
|
|
|
|
|
2010-09-12 08:22:30 -07:00
|
|
|
// If PostDecodeDone() has not been called, we need to sent teardown
|
|
|
|
// notifications.
|
2010-09-12 08:22:30 -07:00
|
|
|
if (!IsSizeDecode() && !mDecodeDone) {
|
2010-09-12 08:22:30 -07:00
|
|
|
|
2010-09-12 08:22:31 -07:00
|
|
|
// Log data errors to the error console
|
2010-12-20 08:21:59 -08:00
|
|
|
nsCOMPtr<nsIConsoleService> consoleService =
|
|
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
2011-12-21 13:51:29 -08:00
|
|
|
nsCOMPtr<nsIScriptError> errorObject =
|
2010-12-20 08:21:59 -08:00
|
|
|
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
|
|
|
|
|
2012-11-16 13:58:11 -08:00
|
|
|
if (consoleService && errorObject && !HasDecoderError()) {
|
2010-09-12 08:22:31 -07:00
|
|
|
nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated: ") +
|
2013-01-30 12:11:20 -08:00
|
|
|
NS_ConvertUTF8toUTF16(mImage.GetURIString()));
|
2010-12-20 08:21:59 -08:00
|
|
|
|
2011-12-21 13:51:29 -08:00
|
|
|
if (NS_SUCCEEDED(errorObject->InitWithWindowID(
|
2012-09-09 16:29:12 -07:00
|
|
|
msg,
|
|
|
|
NS_ConvertUTF8toUTF16(mImage.GetURIString()),
|
|
|
|
EmptyString(), 0, 0, nsIScriptError::errorFlag,
|
2011-12-21 13:51:29 -08:00
|
|
|
"Image", mImage.InnerWindowID()
|
|
|
|
))) {
|
|
|
|
consoleService->LogMessage(errorObject);
|
|
|
|
}
|
2010-09-12 08:22:31 -07:00
|
|
|
}
|
|
|
|
|
2014-02-26 19:48:51 -08:00
|
|
|
bool usable = !HasDecoderError();
|
2013-02-13 13:41:45 -08:00
|
|
|
if (aShutdownIntent != RasterImage::eShutdownIntent_NotNeeded && !HasDecoderError()) {
|
2013-02-07 14:23:44 -08:00
|
|
|
// If we only have a data error, we're usable if we have at least one complete frame.
|
|
|
|
if (GetCompleteFrameCount() == 0) {
|
2012-11-16 11:43:24 -08:00
|
|
|
usable = false;
|
|
|
|
}
|
|
|
|
}
|
2012-11-16 13:58:11 -08:00
|
|
|
|
2012-11-16 11:43:24 -08:00
|
|
|
// If we're usable, do exactly what we should have when the decoder
|
|
|
|
// completed.
|
|
|
|
if (usable) {
|
2013-04-25 13:35:23 -07:00
|
|
|
if (mInFrame) {
|
|
|
|
PostFrameStop();
|
|
|
|
}
|
2012-11-16 11:43:24 -08:00
|
|
|
PostDecodeDone();
|
|
|
|
} else {
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_DECODE_STOPPED | FLAG_ONLOAD_UNBLOCKED |
|
|
|
|
FLAG_HAS_ERROR;
|
2010-09-12 08:22:30 -07:00
|
|
|
}
|
|
|
|
}
|
2013-01-18 13:47:18 -08:00
|
|
|
|
|
|
|
// Set image metadata before calling DecodingComplete, because DecodingComplete calls Optimize().
|
|
|
|
mImageMetadata.SetOnImage(&mImage);
|
|
|
|
|
|
|
|
if (mDecodeDone) {
|
|
|
|
mImage.DecodingComplete();
|
|
|
|
}
|
2010-08-22 19:30:45 -07:00
|
|
|
}
|
|
|
|
|
2011-08-25 13:09:01 -07:00
|
|
|
void
|
|
|
|
Decoder::FinishSharedDecoder()
|
|
|
|
{
|
2013-12-17 14:04:24 -08:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2011-08-25 13:09:01 -07:00
|
|
|
if (!HasError()) {
|
|
|
|
FinishInternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 17:06:30 -08:00
|
|
|
nsresult
|
|
|
|
Decoder::AllocateFrame()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mNeedsNewFrame);
|
2013-02-27 11:23:08 -08:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2013-02-01 17:06:30 -08:00
|
|
|
|
|
|
|
nsresult rv;
|
2014-08-22 13:49:54 -07:00
|
|
|
nsRefPtr<imgFrame> frame;
|
2013-02-01 17:06:30 -08:00
|
|
|
if (mNewFrameData.mPaletteDepth) {
|
|
|
|
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
|
|
|
|
mNewFrameData.mOffsetY, mNewFrameData.mWidth,
|
|
|
|
mNewFrameData.mHeight, mNewFrameData.mFormat,
|
|
|
|
mNewFrameData.mPaletteDepth,
|
|
|
|
&mImageData, &mImageDataLength,
|
2014-08-22 13:49:54 -07:00
|
|
|
&mColormap, &mColormapSize,
|
|
|
|
getter_AddRefs(frame));
|
2013-02-01 17:06:30 -08:00
|
|
|
} else {
|
|
|
|
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
|
|
|
|
mNewFrameData.mOffsetY, mNewFrameData.mWidth,
|
|
|
|
mNewFrameData.mHeight, mNewFrameData.mFormat,
|
2014-08-22 13:49:54 -07:00
|
|
|
&mImageData, &mImageDataLength,
|
|
|
|
getter_AddRefs(frame));
|
2013-02-01 17:06:30 -08:00
|
|
|
}
|
|
|
|
|
2013-06-07 13:42:57 -07:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mCurrentFrame = frame;
|
|
|
|
} else {
|
|
|
|
mCurrentFrame = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify if appropriate
|
2013-02-27 11:23:08 -08:00
|
|
|
if (NS_SUCCEEDED(rv) && mNewFrameData.mFrameNum == mFrameCount) {
|
2013-02-01 17:06:30 -08:00
|
|
|
PostFrameStart();
|
2013-02-27 11:23:08 -08:00
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
PostDataError();
|
2013-02-01 17:06:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Mark ourselves as not needing another frame before talking to anyone else
|
|
|
|
// so they can tell us if they need yet another.
|
|
|
|
mNeedsNewFrame = false;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-02-27 11:23:08 -08:00
|
|
|
void
|
|
|
|
Decoder::SetSizeOnImage()
|
|
|
|
{
|
2013-08-25 00:19:42 -07:00
|
|
|
MOZ_ASSERT(mImageMetadata.HasSize(), "Should have size");
|
|
|
|
MOZ_ASSERT(mImageMetadata.HasOrientation(), "Should have orientation");
|
|
|
|
|
|
|
|
mImage.SetSize(mImageMetadata.GetWidth(),
|
|
|
|
mImageMetadata.GetHeight(),
|
|
|
|
mImageMetadata.GetOrientation());
|
2013-02-27 11:23:08 -08:00
|
|
|
}
|
|
|
|
|
2010-08-22 19:30:45 -07:00
|
|
|
/*
|
|
|
|
* Hook stubs. Override these as necessary in decoder implementations.
|
|
|
|
*/
|
|
|
|
|
2010-09-12 08:22:30 -07:00
|
|
|
void Decoder::InitInternal() { }
|
2013-12-17 14:04:24 -08:00
|
|
|
void Decoder::WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) { }
|
2010-09-12 08:22:30 -07:00
|
|
|
void Decoder::FinishInternal() { }
|
2010-08-22 19:30:45 -07:00
|
|
|
|
2010-08-22 19:30:46 -07:00
|
|
|
/*
|
|
|
|
* Progress Notifications
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2013-08-25 00:19:42 -07:00
|
|
|
Decoder::PostSize(int32_t aWidth,
|
|
|
|
int32_t aHeight,
|
|
|
|
Orientation aOrientation /* = Orientation()*/)
|
2010-08-22 19:30:46 -07:00
|
|
|
{
|
|
|
|
// Validate
|
|
|
|
NS_ABORT_IF_FALSE(aWidth >= 0, "Width can't be negative!");
|
|
|
|
NS_ABORT_IF_FALSE(aHeight >= 0, "Height can't be negative!");
|
|
|
|
|
|
|
|
// Tell the image
|
2013-08-25 00:19:42 -07:00
|
|
|
mImageMetadata.SetSize(aWidth, aHeight, aOrientation);
|
2010-08-22 19:30:46 -07:00
|
|
|
|
2014-11-14 20:06:19 -08:00
|
|
|
// Record this notification.
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_HAS_SIZE;
|
2010-08-22 19:30:46 -07:00
|
|
|
}
|
|
|
|
|
2010-08-22 19:30:46 -07:00
|
|
|
void
|
|
|
|
Decoder::PostFrameStart()
|
|
|
|
{
|
|
|
|
// We shouldn't already be mid-frame
|
|
|
|
NS_ABORT_IF_FALSE(!mInFrame, "Starting new frame but not done with old one!");
|
|
|
|
|
|
|
|
// Update our state to reflect the new frame
|
|
|
|
mFrameCount++;
|
|
|
|
mInFrame = true;
|
|
|
|
|
2014-11-14 20:06:19 -08:00
|
|
|
// If we just became animated, record that fact.
|
|
|
|
if (mFrameCount > 1) {
|
|
|
|
mIsAnimated = true;
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_IS_ANIMATED;
|
2014-11-14 20:06:19 -08:00
|
|
|
}
|
|
|
|
|
2010-08-22 19:30:46 -07:00
|
|
|
// Decoder implementations should only call this method if they successfully
|
|
|
|
// appended the frame to the image. So mFrameCount should always match that
|
|
|
|
// reported by the Image.
|
2011-09-29 06:17:13 -07:00
|
|
|
NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(),
|
2010-08-22 19:30:46 -07:00
|
|
|
"Decoder frame count doesn't match image's!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-17 13:49:04 -07:00
|
|
|
Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::kFrameHasAlpha */,
|
|
|
|
FrameBlender::FrameDisposalMethod aDisposalMethod /* = FrameBlender::kDisposeKeep */,
|
2012-12-19 12:11:42 -08:00
|
|
|
int32_t aTimeout /* = 0 */,
|
2013-06-17 13:49:04 -07:00
|
|
|
FrameBlender::FrameBlendMethod aBlendMethod /* = FrameBlender::kBlendOver */)
|
2010-08-22 19:30:46 -07:00
|
|
|
{
|
|
|
|
// We should be mid-frame
|
|
|
|
NS_ABORT_IF_FALSE(mInFrame, "Stopping frame when we didn't start one!");
|
2013-02-27 11:23:08 -08:00
|
|
|
NS_ABORT_IF_FALSE(mCurrentFrame, "Stopping frame when we don't have one!");
|
2010-08-22 19:30:46 -07:00
|
|
|
|
|
|
|
// Update our state
|
|
|
|
mInFrame = false;
|
|
|
|
|
2013-06-17 13:49:04 -07:00
|
|
|
if (aFrameAlpha == FrameBlender::kFrameOpaque) {
|
2013-02-27 11:23:08 -08:00
|
|
|
mCurrentFrame->SetHasNoAlpha();
|
2012-12-19 12:11:42 -08:00
|
|
|
}
|
|
|
|
|
2013-02-27 11:23:08 -08:00
|
|
|
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
|
2013-12-06 01:45:24 -08:00
|
|
|
mCurrentFrame->SetRawTimeout(aTimeout);
|
2013-02-27 11:23:08 -08:00
|
|
|
mCurrentFrame->SetBlendMethod(aBlendMethod);
|
2013-08-15 14:06:01 -07:00
|
|
|
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
|
2012-12-19 12:11:42 -08:00
|
|
|
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_FRAME_STOPPED | FLAG_ONLOAD_UNBLOCKED;
|
2010-08-22 19:30:46 -07:00
|
|
|
}
|
|
|
|
|
2010-08-24 13:40:45 -07:00
|
|
|
void
|
|
|
|
Decoder::PostInvalidation(nsIntRect& aRect)
|
|
|
|
{
|
|
|
|
// We should be mid-frame
|
|
|
|
NS_ABORT_IF_FALSE(mInFrame, "Can't invalidate when not mid-frame!");
|
2013-02-27 11:23:08 -08:00
|
|
|
NS_ABORT_IF_FALSE(mCurrentFrame, "Can't invalidate when not mid-frame!");
|
2010-08-24 13:40:45 -07:00
|
|
|
|
|
|
|
// Account for the new region
|
|
|
|
mInvalidRect.UnionRect(mInvalidRect, aRect);
|
2013-02-27 11:23:08 -08:00
|
|
|
mCurrentFrame->ImageUpdated(aRect);
|
2010-08-24 13:40:45 -07:00
|
|
|
}
|
|
|
|
|
2010-09-12 08:22:30 -07:00
|
|
|
void
|
2012-12-19 12:11:42 -08:00
|
|
|
Decoder::PostDecodeDone(int32_t aLoopCount /* = 0 */)
|
2010-09-12 08:22:30 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2012-12-20 08:49:25 -08:00
|
|
|
mImageMetadata.SetLoopCount(aLoopCount);
|
|
|
|
mImageMetadata.SetIsNonPremultiplied(GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA);
|
2012-03-23 15:10:50 -07:00
|
|
|
|
2014-11-14 20:10:47 -08:00
|
|
|
mProgress |= FLAG_DECODE_STOPPED;
|
2010-09-12 08:22:30 -07:00
|
|
|
}
|
|
|
|
|
2010-09-12 08:22:27 -07:00
|
|
|
void
|
|
|
|
Decoder::PostDataError()
|
|
|
|
{
|
|
|
|
mDataError = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Decoder::PostDecoderError(nsresult aFailureCode)
|
|
|
|
{
|
|
|
|
NS_ABORT_IF_FALSE(NS_FAILED(aFailureCode), "Not a failure code!");
|
|
|
|
|
|
|
|
mFailCode = aFailureCode;
|
|
|
|
|
|
|
|
// XXXbholley - we should report the image URI here, but imgContainer
|
|
|
|
// needs to know its URI first
|
|
|
|
NS_WARNING("Image decoding error - This is probably a bug!");
|
|
|
|
}
|
|
|
|
|
2013-01-28 09:27:35 -08:00
|
|
|
void
|
|
|
|
Decoder::NeedNewFrame(uint32_t framenum, uint32_t x_offset, uint32_t y_offset,
|
|
|
|
uint32_t width, uint32_t height,
|
2014-04-19 18:28:38 -07:00
|
|
|
gfx::SurfaceFormat format,
|
2013-01-28 09:27:35 -08:00
|
|
|
uint8_t palette_depth /* = 0 */)
|
|
|
|
{
|
|
|
|
// Decoders should never call NeedNewFrame without yielding back to Write().
|
|
|
|
MOZ_ASSERT(!mNeedsNewFrame);
|
|
|
|
|
|
|
|
// We don't want images going back in time or skipping frames.
|
2013-02-27 11:23:08 -08:00
|
|
|
MOZ_ASSERT(framenum == mFrameCount || framenum == (mFrameCount - 1));
|
2013-01-28 09:27:35 -08:00
|
|
|
|
|
|
|
mNewFrameData = NewFrameData(framenum, x_offset, y_offset, width, height, format, palette_depth);
|
|
|
|
mNeedsNewFrame = true;
|
|
|
|
}
|
|
|
|
|
2012-01-06 08:02:27 -08:00
|
|
|
} // namespace image
|
2010-08-22 19:30:45 -07:00
|
|
|
} // namespace mozilla
|