Bug 584841 patch 9: Move RasterImage-specific methods from imgIContainer interface to RasterImage class. r=bholley sr=vlad a=blocking

This commit is contained in:
Daniel Holbert 2010-08-13 21:09:49 -07:00
Родитель 62b307a4a8
Коммит 67428f776b
22 изменённых файлов: 304 добавлений и 256 удалений

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

@ -52,4 +52,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = nsBMPDecoder.cpp nsICODecoder.cpp nsIconDecoder.cpp
# ns[BMP,ICO,Icon]Decoder.cpp all include RasterImage.h
LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
include $(topsrcdir)/config/rules.mk

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

@ -47,12 +47,15 @@
#include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "RasterImage.h"
#include "imgIContainerObserver.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "prlog.h"
using namespace mozilla::imagelib;
#ifdef PR_LOGGING
PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder");
#endif
@ -86,8 +89,12 @@ NS_IMETHODIMP nsBMPDecoder::Init(imgIContainer *aImage,
imgIDecoderObserver *aObserver,
PRUint32 aFlags)
{
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", aImage));
mImage = aImage;
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;

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

@ -40,9 +40,8 @@
#ifndef _nsBMPDecoder_h
#define _nsBMPDecoder_h
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "gfxColor.h"
@ -140,6 +139,12 @@ enum ERLEState {
eRLEStateAbsoluteModePadded ///< As above, but another byte of data has to be read as padding
};
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
/**
* Decoder for BMP-Files, as used by Windows and OS/2
*/
@ -160,7 +165,7 @@ private:
nsCOMPtr<imgIDecoderObserver> mObserver;
nsCOMPtr<imgIContainer> mImage;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
PRUint32 mFlags;
PRUint32 mPos;

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

@ -47,6 +47,7 @@
#include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "RasterImage.h"
#include "imgIContainerObserver.h"
#include "nsIInterfaceRequestor.h"
@ -55,7 +56,7 @@
#include "nsIProperties.h"
#include "nsISupportsPrimitives.h"
#include "nsAutoPtr.h"
using namespace mozilla::imagelib;
NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
@ -93,8 +94,11 @@ NS_IMETHODIMP nsICODecoder::Init(imgIContainer *aImage,
imgIDecoderObserver *aObserver,
PRUint32 aFlags)
{
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
// Grab parameters
mImage = aImage;
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
@ -280,18 +284,15 @@ nsICODecoder::Write(const char* aBuffer, PRUint32 aCount)
}
if (mIsCursor) {
nsCOMPtr<nsIProperties> props(do_QueryInterface(mImage));
if (props) {
nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance("@mozilla.org/supports-PRUint32;1");
if (intwrapx && intwrapy) {
intwrapx->SetData(mDirEntry.mXHotspot);
intwrapy->SetData(mDirEntry.mYHotspot);
if (intwrapx && intwrapy) {
intwrapx->SetData(mDirEntry.mXHotspot);
intwrapy->SetData(mDirEntry.mYHotspot);
props->Set("hotspotX", intwrapx);
props->Set("hotspotY", intwrapy);
}
mImage->Set("hotspotX", intwrapx);
mImage->Set("hotspotY", intwrapy);
}
}

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

@ -41,7 +41,7 @@
#ifndef _nsICODecoder_h
#define _nsICODecoder_h
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
@ -51,6 +51,12 @@
#define NS_ICODECODER_CID \
{ 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } }
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
struct IconDirEntry
{
PRUint8 mWidth;
@ -88,7 +94,7 @@ private:
PRUint32 CalcAlphaRowSize();
private:
nsCOMPtr<imgIContainer> mImage;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;

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

@ -40,7 +40,7 @@
#include "nsIconDecoder.h"
#include "nsIInputStream.h"
#include "imgIContainer.h"
#include "RasterImage.h"
#include "imgIContainerObserver.h"
#include "nspr.h"
#include "nsIComponentManager.h"
@ -50,6 +50,8 @@
#include "nsIInterfaceRequestorUtils.h"
#include "ImageErrors.h"
using namespace mozilla::imagelib;
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder)
NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder)
@ -85,7 +87,10 @@ NS_IMETHODIMP nsIconDecoder::Init(imgIContainer *aImage,
{
// Grab parameters
mImage = aImage;
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;

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

@ -56,6 +56,11 @@
{ 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \
}
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
//////////////////////////////////////////////////////////////////////////////////////////////
// The icon decoder is a decoder specifically tailored for loading icons
@ -85,7 +90,7 @@ public:
nsIconDecoder();
virtual ~nsIconDecoder();
nsCOMPtr<imgIContainer> mImage;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
PRUint8 mWidth;

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

@ -51,7 +51,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = nsGIFDecoder2.cpp
# nsGIFDecoder2.cpp includes imgContainer.h
# nsGIFDecoder2.cpp includes RasterImage.h
LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src
include $(topsrcdir)/config/rules.mk

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

@ -81,6 +81,7 @@ mailing address.
#include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "imgIContainerObserver.h"
#include "RasterImage.h"
#include "gfxColor.h"
#include "gfxPlatform.h"
@ -144,8 +145,11 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgIContainer *aImage,
imgIDecoderObserver *aObserver,
PRUint32 aFlags)
{
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
// Store parameters
mImageContainer = aImage;
mImageContainer = static_cast<mozilla::imagelib::RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;

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

@ -56,6 +56,12 @@
{0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \
}
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
//////////////////////////////////////////////////////////////////////
// nsGIFDecoder2 Definition
@ -85,7 +91,9 @@ private:
inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
nsCOMPtr<imgIContainer> mImageContainer;
// XXXdholbert This member variable should probably be renamed to "mImage"
// for consistency with nsPNGDecoder
nsRefPtr<mozilla::imagelib::RasterImage> mImageContainer;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
PRInt32 mCurrentRow;

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

@ -53,5 +53,8 @@ CPPSRCS = nsJPEGDecoder.cpp
CSRCS = iccjpeg.c
# nsJPEGDecoder.cpp includes RasterImage.h
LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
include $(topsrcdir)/config/rules.mk

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

@ -56,6 +56,8 @@
#include "gfxPlatform.h"
using namespace mozilla::imagelib;
extern "C" {
#include "iccjpeg.h"
@ -145,9 +147,11 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgIContainer *aImage,
imgIDecoderObserver *aObserver,
PRUint32 aFlags)
{
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
/* Grab the parameters. */
mImage = aImage;
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;

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

@ -41,11 +41,16 @@
#ifndef nsJPEGDecoder_h__
#define nsJPEGDecoder_h__
#include "RasterImage.h"
/* On Windows systems, RasterImage.h brings in 'windows.h', which defines INT32.
* But the jpeg decoder has its own definition of INT32. To avoid build issues,
* we need to undefine the version from 'windows.h'. */
#undef INT32
#include "imgIDecoder.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h"
#include "nsIInputStream.h"
#include "nsIPipe.h"
@ -81,6 +86,12 @@ typedef enum {
JPEG_ERROR
} jstate;
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
class nsJPEGDecoder : public imgIDecoder
{
public:
@ -96,7 +107,7 @@ protected:
nsresult OutputScanlines(PRBool* suspend);
public:
nsCOMPtr<imgIContainer> mImage;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;

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

@ -50,7 +50,6 @@ LIBXUL_LIBRARY = 1
EXTRA_DSO_LIBS = gkgfx
CPPSRCS = nsPNGDecoder.cpp
ifneq (,$(filter png,$(MOZ_IMG_ENCODERS)))
@ -61,5 +60,7 @@ ifneq (,$(filter png,$(MOZ_IMG_DECODERS)))
DEFINES += -DMOZ_PNG_READ
endif
include $(topsrcdir)/config/rules.mk
# nsPNGDecoder.cpp includes RasterImage.h
LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/
include $(topsrcdir)/config/rules.mk

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

@ -49,6 +49,7 @@
#include "nsIComponentManager.h"
#include "nsIInputStream.h"
#include "RasterImage.h"
#include "imgIContainerObserver.h"
#include "nsIInterfaceRequestorUtils.h"
@ -60,6 +61,8 @@
#include "gfxPlatform.h"
using namespace mozilla::imagelib;
static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass);
@ -191,18 +194,18 @@ void nsPNGDecoder::SetAnimFrameInfo()
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
mImage->SetFrameDisposalMethod(numFrames - 1,
imgIContainer::kDisposeRestorePrevious);
RasterImage::kDisposeRestorePrevious);
else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
mImage->SetFrameDisposalMethod(numFrames - 1,
imgIContainer::kDisposeClear);
RasterImage::kDisposeClear);
else
mImage->SetFrameDisposalMethod(numFrames - 1,
imgIContainer::kDisposeKeep);
RasterImage::kDisposeKeep);
if (blend_op == PNG_BLEND_OP_SOURCE)
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendSource);
/*else // 'over' is the default
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendOver); */
}
#endif
@ -264,8 +267,10 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgIContainer *aImage,
116, 73, 77, 69, '\0', /* tIME */
122, 84, 88, 116, '\0'}; /* zTXt */
#endif
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
mImage = aImage;
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;

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

@ -61,6 +61,12 @@
{0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \
}
namespace mozilla {
namespace imagelib {
class RasterImage;
} // namespace imagelib
} // namespace mozilla
class nsPNGDecoder : public imgIDecoder
{
public:
@ -79,7 +85,7 @@ public:
void NotifyDone(PRBool aSuccess);
public:
nsCOMPtr<imgIContainer> mImage;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;

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

@ -264,29 +264,6 @@ interface imgIContainer : nsISupports
in string aMimeType,
in PRUint32 aFlags);
/**
* "Disposal" method indicates how the image should be handled before the
* subsequent image is displayed.
* Don't change these without looking at the implementations using them,
* struct gif_struct::disposal_method and gif_write() in particular.
*/
const long kDisposeClearAll = -1; // Clear the whole image, revealing
// what was there before the gif displayed
const long kDisposeNotSpecified = 0; // Leave frame, let new frame draw on top
const long kDisposeKeep = 1; // Leave frame, let new frame draw on top
const long kDisposeClear = 2; // Clear the frame's area, revealing bg
const long kDisposeRestorePrevious = 3; // Restore the previous (composited) frame
/*
* "Blend" method indicates how the current image is combined with the
* previous image.
*/
const long kBlendSource = 0; // All color components of the frame, including alpha,
// overwrite the current contents of the frame's
// output buffer region
const long kBlendOver = 1; // The frame should be composited onto the output buffer
// based on its alpha, using a simple OVER operation
/**
* Animation mode Constants
* 0 = normal
@ -323,76 +300,8 @@ interface imgIContainer : nsISupports
*/
readonly attribute unsigned long dataSize;
void setFrameDisposalMethod(in unsigned long framenumber, in PRInt32 aDisposalMethod);
void setFrameBlendMethod(in unsigned long framenumber, in PRInt32 aBlendMethod);
void setFrameTimeout(in unsigned long framenumber, in PRInt32 aTimeout);
void setFrameHasNoAlpha(in unsigned long framenumber);
/**
* Sets the size of the container. This should only be called by the decoder. This function may be called multiple
* times, but will throw an error if subsequent calls do not match the first.
*/
[noscript] void setSize(in long aWidth, in long aHeight);
/**
* Create or re-use a frame at index aFrameNum. It is an error to call this with aFrameNum not in the range [0, numFrames].
*/
[noscript] void ensureCleanFrame(in unsigned long aFramenum, in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
/**
* Adds to the end of the list of frames.
*/
[noscript] void appendFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
[noscript] void appendPalettedFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, in PRUint8 aPaletteDepth,
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength,
[array, size_is(paletteLength)] out PRUint32 paletteData, out unsigned long paletteLength);
[noscript] void frameUpdated(in unsigned long framenum, in nsIntRect aNewRect);
/* notification when the current frame is done decoding */
void endFrameDecode(in unsigned long framenumber);
/* notification that the entire image has been decoded */
void decodingComplete();
/* Methods to control animation */
void startAnimation();
void stopAnimation();
void resetAnimation();
/**
* number of times to loop the image.
* @note -1 means forever.
*/
attribute long loopCount;
/* Add compressed source data to the imgContainer.
*
* The decoder will use this data, either immediately or at draw time, do
* decode the image.
*/
[noscript] void addSourceData([array, size_is(aCount), const] in char data,
in unsigned long aCount);
/* Called after the all the source data has been added with addSourceData. */
[noscript] void sourceDataComplete();
/* Called for multipart images when there's a new source image to add. */
[noscript] void newSourceData();
/**
* A hint of the number of bytes of source data that the image contains. If
* called early on, this can help reduce copying and reallocations by
* appropriately preallocating the source data buffer.
*
* We take this approach rather than having the source data management code do
* something more complicated (like chunklisting) because HTTP is by far the
* dominant source of images, and the Content-Length header is quite reliable.
* Thus, pre-allocation simplifies code and reduces the total number of
* allocations.
*/
void setSourceSizeHint(in unsigned long sizeHint);
};

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

@ -795,8 +795,8 @@ RasterImage::InternalAddFrame(PRUint32 framenum,
// First Frame's refresh area is all of itself.
// RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR)
PRInt32 frameDisposalMethod = mFrames[0]->GetFrameDisposalMethod();
if (frameDisposalMethod == imgIContainer::kDisposeClear ||
frameDisposalMethod == imgIContainer::kDisposeRestorePrevious)
if (frameDisposalMethod == kDisposeClear ||
frameDisposalMethod == kDisposeRestorePrevious)
mAnim->firstFrameRefreshArea = mFrames[0]->GetRect();
}
@ -819,8 +819,7 @@ RasterImage::InternalAddFrame(PRUint32 framenum,
return rv;
}
/* [noscript] void appendFrame (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, [array, size_is (imageLength)] out PRUint8 imageData, out unsigned long imageLength); */
NS_IMETHODIMP
nsresult
RasterImage::AppendFrame(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
@ -839,8 +838,7 @@ RasterImage::AppendFrame(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
/* aPaletteLength = */ nsnull);
}
/* [noscript] void appendPalettedFrame (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, in PRUint8 aPaletteDepth, [array, size_is (imageLength)] out PRUint8 imageData, out unsigned long imageLength, [array, size_is (paletteLength)] out PRUint32 paletteData, out unsigned long paletteLength); */
NS_IMETHODIMP
nsresult
RasterImage::AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
@ -863,8 +861,7 @@ RasterImage::AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
paletteData, paletteLength);
}
/* [noscript] void setSize(in long aWidth, in long aHeight); */
NS_IMETHODIMP
nsresult
RasterImage::SetSize(PRInt32 aWidth, PRInt32 aHeight)
{
if (mError)
@ -896,13 +893,7 @@ RasterImage::SetSize(PRInt32 aWidth, PRInt32 aHeight)
return NS_OK;
}
/* [noscript] void ensureCleanFrame(in unsigned long aFramenum, in PRInt32 aX,
in PRInt32 aY, in PRInt32 aWidth,
in PRInt32 aHeight, in gfxImageFormat aFormat,
[array, size_is(imageLength)]
out PRUint8 imageData,
out unsigned long imageLength); */
NS_IMETHODIMP
nsresult
RasterImage::EnsureCleanFrame(PRUint32 aFrameNum, PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
@ -949,9 +940,7 @@ RasterImage::EnsureCleanFrame(PRUint32 aFrameNum, PRInt32 aX, PRInt32 aY,
}
//******************************************************************************
/* void frameUpdated (in unsigned long framenumber, in nsIntRect rect); */
NS_IMETHODIMP
nsresult
RasterImage::FrameUpdated(PRUint32 aFrameNum, nsIntRect &aUpdatedRect)
{
NS_ASSERTION(aFrameNum < mFrames.Length(), "Invalid frame index!");
@ -967,10 +956,9 @@ RasterImage::FrameUpdated(PRUint32 aFrameNum, nsIntRect &aUpdatedRect)
return NS_OK;
}
//******************************************************************************
/* void setFrameDisposalMethod (in unsigned long framenumber, in PRInt32 aDisposalMethod); */
NS_IMETHODIMP
RasterImage::SetFrameDisposalMethod(PRUint32 aFrameNum, PRInt32 aDisposalMethod)
nsresult
RasterImage::SetFrameDisposalMethod(PRUint32 aFrameNum,
PRInt32 aDisposalMethod)
{
if (mError)
return NS_ERROR_FAILURE;
@ -989,9 +977,7 @@ RasterImage::SetFrameDisposalMethod(PRUint32 aFrameNum, PRInt32 aDisposalMethod)
return NS_OK;
}
//******************************************************************************
/* void setFrameTimeout (in unsigned long framenumber, in PRInt32 aTimeout); */
NS_IMETHODIMP
nsresult
RasterImage::SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout)
{
if (mError)
@ -1010,9 +996,7 @@ RasterImage::SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout)
return NS_OK;
}
//******************************************************************************
/* void setFrameBlendMethod (in unsigned long framenumber, in PRInt32 aBlendMethod); */
NS_IMETHODIMP
nsresult
RasterImage::SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod)
{
if (mError)
@ -1031,10 +1015,7 @@ RasterImage::SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod)
return NS_OK;
}
//******************************************************************************
/* void setFrameHasNoAlpha (in unsigned long framenumber); */
NS_IMETHODIMP
nsresult
RasterImage::SetFrameHasNoAlpha(PRUint32 aFrameNum)
{
if (mError)
@ -1053,9 +1034,7 @@ RasterImage::SetFrameHasNoAlpha(PRUint32 aFrameNum)
return NS_OK;
}
//******************************************************************************
/* void endFrameDecode (in unsigned long framenumber); */
NS_IMETHODIMP
nsresult
RasterImage::EndFrameDecode(PRUint32 aFrameNum)
{
if (mError)
@ -1069,9 +1048,7 @@ RasterImage::EndFrameDecode(PRUint32 aFrameNum)
return NS_OK;
}
//******************************************************************************
/* void decodingComplete (); */
NS_IMETHODIMP
nsresult
RasterImage::DecodingComplete()
{
if (mError)
@ -1130,9 +1107,9 @@ RasterImage::SetAnimationMode(PRUint16 aAnimationMode)
if (mError)
return NS_ERROR_FAILURE;
NS_ASSERTION(aAnimationMode == imgIContainer::kNormalAnimMode ||
aAnimationMode == imgIContainer::kDontAnimMode ||
aAnimationMode == imgIContainer::kLoopOnceAnimMode,
NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
aAnimationMode == kDontAnimMode ||
aAnimationMode == kLoopOnceAnimMode,
"Wrong Animation Mode is being set!");
switch (mAnimationMode = aAnimationMode) {
@ -1247,41 +1224,20 @@ RasterImage::ResetAnimation()
return NS_OK;
}
//******************************************************************************
/* attribute long loopCount; */
NS_IMETHODIMP
RasterImage::GetLoopCount(PRInt32 *aLoopCount)
{
if (mError)
return NS_ERROR_FAILURE;
NS_ENSURE_ARG_POINTER(aLoopCount);
*aLoopCount = mLoopCount;
return NS_OK;
}
//******************************************************************************
/* attribute long loopCount; */
NS_IMETHODIMP
void
RasterImage::SetLoopCount(PRInt32 aLoopCount)
{
if (mError)
return NS_ERROR_FAILURE;
return;
// -1 infinite
// 0 no looping, one iteration
// 1 one loop, two iterations
// ...
mLoopCount = aLoopCount;
return NS_OK;
}
//******************************************************************************
/* void addSourceData(in nsIInputStream aInputStream, in unsigned long aCount); */
NS_IMETHODIMP
nsresult
RasterImage::AddSourceData(const char *aBuffer, PRUint32 aCount)
{
if (mError)
@ -1361,9 +1317,7 @@ get_header_str (char *buf, char *data, PRSize data_len)
buf[i * 2] = 0;
}
//******************************************************************************
/* void sourceDataComplete(); */
NS_IMETHODIMP
nsresult
RasterImage::SourceDataComplete()
{
if (mError)
@ -1423,9 +1377,7 @@ RasterImage::SourceDataComplete()
return NS_OK;
}
//******************************************************************************
/* void newSourceData(); */
NS_IMETHODIMP
nsresult
RasterImage::NewSourceData()
{
nsresult rv;
@ -1469,9 +1421,7 @@ RasterImage::NewSourceData()
return NS_OK;
}
//******************************************************************************
/* void setSourceSizeHint(in unsigned long sizeHint); */
NS_IMETHODIMP
nsresult
RasterImage::SetSourceSizeHint(PRUint32 sizeHint)
{
if (sizeHint && StoringSourceData())
@ -1612,9 +1562,9 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
NS_ENSURE_ARG_POINTER(aFrameToUse);
PRInt32 prevFrameDisposalMethod = aPrevFrame->GetFrameDisposalMethod();
if (prevFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious &&
if (prevFrameDisposalMethod == kDisposeRestorePrevious &&
!mAnim->compositingPrevFrame)
prevFrameDisposalMethod = imgIContainer::kDisposeClear;
prevFrameDisposalMethod = kDisposeClear;
nsIntRect prevFrameRect = aPrevFrame->GetRect();
PRBool isFullPrevFrame = (prevFrameRect.x == 0 && prevFrameRect.y == 0 &&
@ -1624,8 +1574,8 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
// Optimization: DisposeClearAll if the previous frame is the same size as
// container and it's clearing itself
if (isFullPrevFrame &&
(prevFrameDisposalMethod == imgIContainer::kDisposeClear))
prevFrameDisposalMethod = imgIContainer::kDisposeClearAll;
(prevFrameDisposalMethod == kDisposeClear))
prevFrameDisposalMethod = kDisposeClearAll;
PRInt32 nextFrameDisposalMethod = aNextFrame->GetFrameDisposalMethod();
nsIntRect nextFrameRect = aNextFrame->GetRect();
@ -1636,7 +1586,7 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
if (!aNextFrame->GetIsPaletted()) {
// Optimization: Skip compositing if the previous frame wants to clear the
// whole image
if (prevFrameDisposalMethod == imgIContainer::kDisposeClearAll) {
if (prevFrameDisposalMethod == kDisposeClearAll) {
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
*aFrameToUse = aNextFrame;
return NS_OK;
@ -1645,7 +1595,7 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
// Optimization: Skip compositing if this frame is the same size as the
// container and it's fully drawing over prev frame (no alpha)
if (isFullNextFrame &&
(nextFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious) &&
(nextFrameDisposalMethod != kDisposeRestorePrevious) &&
!aNextFrame->GetHasAlpha()) {
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
*aFrameToUse = aNextFrame;
@ -1656,17 +1606,17 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
// Calculate area that needs updating
switch (prevFrameDisposalMethod) {
default:
case imgIContainer::kDisposeNotSpecified:
case imgIContainer::kDisposeKeep:
case kDisposeNotSpecified:
case kDisposeKeep:
*aDirtyRect = nextFrameRect;
break;
case imgIContainer::kDisposeClearAll:
case kDisposeClearAll:
// Whole image container is cleared
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
break;
case imgIContainer::kDisposeClear:
case kDisposeClear:
// Calc area that needs to be redrawn (the combination of previous and
// this frame)
// XXX - This could be done with multiple framechanged calls
@ -1677,7 +1627,7 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
aDirtyRect->UnionRect(nextFrameRect, prevFrameRect);
break;
case imgIContainer::kDisposeRestorePrevious:
case kDisposeRestorePrevious:
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
break;
}
@ -1739,7 +1689,7 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
if (doDisposal) {
// Dispose of previous: clear, restore, or keep (copy)
switch (prevFrameDisposalMethod) {
case imgIContainer::kDisposeClear:
case kDisposeClear:
if (needToBlankComposite) {
// If we just created the composite, it could have anything in it's
// buffer. Clear whole frame
@ -1750,18 +1700,18 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
}
break;
case imgIContainer::kDisposeClearAll:
case kDisposeClearAll:
ClearFrame(mAnim->compositingFrame);
break;
case imgIContainer::kDisposeRestorePrevious:
case kDisposeRestorePrevious:
// It would be better to copy only the area changed back to
// compositingFrame.
if (mAnim->compositingPrevFrame) {
CopyFrameImage(mAnim->compositingPrevFrame, mAnim->compositingFrame);
// destroy only if we don't need it for this frame's disposal
if (nextFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)
if (nextFrameDisposalMethod != kDisposeRestorePrevious)
mAnim->compositingPrevFrame = nsnull;
} else {
ClearFrame(mAnim->compositingFrame);
@ -1799,8 +1749,8 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
// Check if the frame we are composing wants the previous image restored afer
// it is done. Don't store it (again) if last frame wanted its image restored
// too
if ((nextFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious) &&
(prevFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)) {
if ((nextFrameDisposalMethod == kDisposeRestorePrevious) &&
(prevFrameDisposalMethod != kDisposeRestorePrevious)) {
// We are storing the whole image.
// It would be better if we just stored the area that nextFrame is going to
// overwrite.
@ -1844,7 +1794,7 @@ RasterImage::DoComposite(imgFrame** aFrameToUse,
// Then set the previous frame's disposal to CLEAR_ALL so we just draw the
// frame next time around
if (CopyFrameImage(mAnim->compositingFrame, aNextFrame)) {
aPrevFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClearAll);
aPrevFrame->SetFrameDisposalMethod(kDisposeClearAll);
mAnim->lastCompositedFrameIndex = -1;
*aFrameToUse = aNextFrame;
return NS_OK;
@ -2035,7 +1985,7 @@ RasterImage::DrawFrameTo(imgFrame *aSrc,
// first clear the surface if the blend flag says so
PRInt32 blendMethod = aSrc->GetBlendMethod();
if (blendMethod == imgIContainer::kBlendSource) {
if (blendMethod == kBlendSource) {
gfxContext::GraphicsOperator defaultOperator = dst.CurrentOperator();
dst.SetOperator(gfxContext::OPERATOR_CLEAR);
dst.Fill();

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

@ -172,6 +172,108 @@ public:
/* Triggers discarding. */
void Discard();
/* Callbacks for decoders */
nsresult SetFrameDisposalMethod(PRUint32 aFrameNum,
PRInt32 aDisposalMethod);
nsresult SetFrameTimeout(PRUint32 aFrameNum, PRInt32 aTimeout);
nsresult SetFrameBlendMethod(PRUint32 aFrameNum, PRInt32 aBlendMethod);
nsresult SetFrameHasNoAlpha(PRUint32 aFrameNum);
/**
* Sets the size of the container. This should only be called by the
* decoder. This function may be called multiple times, but will throw an
* error if subsequent calls do not match the first.
*/
nsresult SetSize(PRInt32 aWidth, PRInt32 aHeight);
nsresult EnsureCleanFrame(PRUint32 aFramenum, PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
PRUint8** imageData,
PRUint32* imageLength);
/**
* Adds to the end of the list of frames.
*/
nsresult AppendFrame(PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
PRUint8** imageData,
PRUint32* imageLength);
nsresult AppendPalettedFrame(PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight,
gfxASurface::gfxImageFormat aFormat,
PRUint8 aPaletteDepth,
PRUint8** imageData,
PRUint32* imageLength,
PRUint32** paletteData,
PRUint32* paletteLength);
nsresult FrameUpdated(PRUint32 aFrameNum, nsIntRect& aUpdatedRect);
/* notification when the current frame is done decoding */
nsresult EndFrameDecode(PRUint32 aFrameNum);
/* notification that the entire image has been decoded */
nsresult DecodingComplete();
/**
* Number of times to loop the image.
* @note -1 means forever.
*/
void SetLoopCount(PRInt32 aLoopCount);
/* Add compressed source data to the imgContainer.
*
* The decoder will use this data, either immediately or at draw time, to
* decode the image.
*
* XXX This method's only caller (WriteToContainer) ignores the return
* value. Should this just return void?
*/
nsresult AddSourceData(const char *aBuffer, PRUint32 aCount);
/* Called after the all the source data has been added with addSourceData. */
virtual nsresult SourceDataComplete();
/* Called for multipart images when there's a new source image to add. */
virtual nsresult NewSourceData();
/**
* A hint of the number of bytes of source data that the image contains. If
* called early on, this can help reduce copying and reallocations by
* appropriately preallocating the source data buffer.
*
* We take this approach rather than having the source data management code do
* something more complicated (like chunklisting) because HTTP is by far the
* dominant source of images, and the Content-Length header is quite reliable.
* Thus, pre-allocation simplifies code and reduces the total number of
* allocations.
*/
virtual nsresult SetSourceSizeHint(PRUint32 sizeHint);
// "Blend" method indicates how the current image is combined with the
// previous image.
enum {
// All color components of the frame, including alpha, overwrite the current
// contents of the frame's output buffer region
kBlendSource = 0,
// The frame should be composited onto the output buffer based on its alpha,
// using a simple OVER operation
kBlendOver
};
enum {
kDisposeClearAll = -1, // Clear the whole image, revealing
// what was there before the gif displayed
kDisposeNotSpecified, // Leave frame, let new frame draw on top
kDisposeKeep, // Leave frame, let new frame draw on top
kDisposeClear, // Clear the frame's area, revealing bg
kDisposeRestorePrevious // Restore the previous (composited) frame
};
private:
struct Anim
{

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

@ -87,6 +87,7 @@
#define DISCARD_PREF "image.mem.discardable"
#define DECODEONDRAW_PREF "image.mem.decodeondraw"
#define SVG_MIMETYPE "image/svg+xml"
using namespace mozilla::imagelib;
@ -202,6 +203,9 @@ nsresult imgRequest::Init(nsIURI *aURI,
NS_ABORT_IF_FALSE(aChannel, "No channel");
mProperties = do_CreateInstance("@mozilla.org/properties;1");
// XXXdholbert For SVG support, this mImage-construction will need to happen
// later -- *after* we know image mimetype.
nsCOMPtr<imgIContainer> comImg = do_CreateInstance("@mozilla.org/image/rasterimage;1");
mImage = static_cast<Image*>(comImg.get());
@ -725,10 +729,10 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
"Already have an image for non-multipart request");
// If we're multipart, and our image is initialized, fix things up for another round
if (mIsMultiPartChannel && mImage->IsInitialized()) {
if (mIsMultiPartChannel && mImage->IsInitialized() &&
mImage->GetType() == imgIContainer::TYPE_RASTER) {
// Inform the container that we have new source data
mImage->NewSourceData();
static_cast<RasterImage*>(mImage.get())->NewSourceData();
}
/*
@ -863,10 +867,11 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
// Tell the image that it has all of the source data. Note that this can
// trigger a failure, since the image might be waiting for more non-optional
// data and this is the point where we break the news that it's not coming.
if (mImage->IsInitialized()) {
if (mImage->IsInitialized() &&
mImage->GetType() == imgIContainer::TYPE_RASTER) {
// Notify the image
nsresult rv = mImage->SourceDataComplete();
nsresult rv = static_cast<RasterImage*>(mImage.get())->SourceDataComplete();
// If we got an error in the SourceDataComplete() call, we don't want to
// proceed as if nothing bad happened. However, we also want to give
@ -914,7 +919,10 @@ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctx
nsresult rv;
if (!mGotData) {
PRUint16 imageType;
if (mGotData) {
imageType = mImage->GetType();
} else {
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |First time through... finding mimetype|");
mGotData = PR_TRUE;
@ -952,6 +960,10 @@ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctx
LOG_MSG(gImgLog, "imgRequest::OnDataAvailable", "Got content type from the channel");
}
/* now we have mimetype, so we can infer the image type that we want */
imageType = mContentType.EqualsLiteral(SVG_MIMETYPE) ?
imgIContainer::TYPE_VECTOR : imgIContainer::TYPE_RASTER;
/* set our mimetype as a property */
nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
if (contentType) {
@ -1026,20 +1038,23 @@ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctx
return NS_BINDING_ABORTED;
}
/* Use content-length as a size hint for http channels. */
if (httpChannel) {
nsCAutoString contentLength;
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
contentLength);
if (NS_SUCCEEDED(rv)) {
PRInt32 len = contentLength.ToInteger(&rv);
if (imageType == imgIContainer::TYPE_RASTER) {
/* Use content-length as a size hint for http channels. */
if (httpChannel) {
nsCAutoString contentLength;
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
contentLength);
if (NS_SUCCEEDED(rv)) {
PRInt32 len = contentLength.ToInteger(&rv);
// Pass anything usable on so that the Image can preallocate its
// source buffer
if (len > 0) {
PRUint32 sizeHint = (PRUint32) len;
sizeHint = PR_MIN(sizeHint, 20000000); /* Bound by something reasonable */
mImage->SetSourceSizeHint(sizeHint);
// Pass anything usable on so that the RasterImage can preallocate
// its source buffer
if (len > 0) {
PRUint32 sizeHint = (PRUint32) len;
sizeHint = PR_MIN(sizeHint, 20000000); /* Bound by something reasonable */
RasterImage* rasterImage = static_cast<RasterImage*>(mImage.get());
rasterImage->SetSourceSizeHint(sizeHint);
}
}
}
}

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

@ -78,20 +78,24 @@ NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
imgIContainer **aContainer)
{
nsresult rv;
RasterImage* image; // convenience alias for *aContainer
NS_ENSURE_ARG_POINTER(aInStr);
// If the caller didn't provide a container, create one
if (!*aContainer) {
*aContainer = new RasterImage();
if (!*aContainer)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aContainer);
// If the caller didn't provide an imgIContainer, create one.
if (*aContainer) {
NS_ABORT_IF_FALSE((*aContainer)->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
image = static_cast<RasterImage*>(*aContainer);
} else {
*aContainer = image = new RasterImage();
NS_ADDREF(image);
}
// Initialize the container. If we're using the one from the caller, we
// require that it not be initialized
nsCString mimeType(aMimeType);
rv = (*aContainer)->Init(nsnull, mimeType.get(), imgIContainer::INIT_FLAG_NONE);
rv = image->Init(nsnull, mimeType.get(), Image::INIT_FLAG_NONE);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> inStream = aInStr;
@ -111,13 +115,13 @@ NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
// consumes everything it gets.
PRUint32 bytesRead;
rv = inStream->ReadSegments(RasterImage::WriteToContainer,
static_cast<void*>(*aContainer),
static_cast<void*>(image),
length, &bytesRead);
NS_ENSURE_SUCCESS(rv, rv);
// Let the container know we've sent all the data
rv = (*aContainer)->SourceDataComplete();
rv = image->SourceDataComplete();
NS_ENSURE_SUCCESS(rv, rv);
// All done

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

@ -758,12 +758,6 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
HICON *aIcon) {
nsresult rv;
PRUint32 nFrames;
rv = aContainer->GetNumFrames(&nFrames);
NS_ENSURE_SUCCESS(rv, rv);
if (!nFrames)
return NS_ERROR_INVALID_ARG;
// Get the image data
nsRefPtr<gfxImageSurface> frame;