PRUint32 imgFrame::EstimateMemoryUsed(gfxASurface::MemoryLocation aLocation) const { PRUint32 size = 0; if (mSinglePixel && aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP) { size += sizeof(gfxRGBA); } if (mPalettedImageData && aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP) { size += GetImageDataLength() + PaletteDataLength(); } #ifdef USE_WIN_SURFACE if (mWinSurface && aLocation == mWinSurface->GetMemoryLocation()) { size += mWinSurface->KnownMemoryUsed(); } else #endif #ifdef XP_MACOSX if (mQuartzSurface && aLocation == gfxASurface::MEMORY_IN_PROCESS_HEAP) { size += mSize.width * mSize.height * 4; } else #endif if (mImageSurface && aLocation == mImageSurface->GetMemoryLocation()) { size += mImageSurface->KnownMemoryUsed(); } if (mOptSurface && aLocation == mOptSurface->GetMemoryLocation()) { size += mOptSurface->KnownMemoryUsed(); } return size; }
nsresult imgFrame::Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, SurfaceFormat aFormat, uint8_t aPaletteDepth /* = 0 */) { // assert for properties that should be verified by decoders, warn for properties related to bad content if (!AllowedImageSize(aWidth, aHeight)) { NS_WARNING("Should have legal image size"); return NS_ERROR_FAILURE; } mOffset.MoveTo(aX, aY); mSize.SizeTo(aWidth, aHeight); mFormat = aFormat; mPaletteDepth = aPaletteDepth; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_WARNING("Should have legal palette depth"); NS_ERROR("This Depth is not supported"); return NS_ERROR_FAILURE; } // Use the fallible allocator here mPalettedImageData = (uint8_t*)moz_malloc(PaletteDataLength() + GetImageDataLength()); if (!mPalettedImageData) NS_WARNING("moz_malloc for paletted image data should succeed"); NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { // Inform the discard tracker that we are going to allocate some memory. if (!DiscardTracker::TryAllocation(4 * mSize.width * mSize.height)) { NS_WARNING("Exceed the hard limit of decode image size"); return NS_ERROR_OUT_OF_MEMORY; } if (!mImageSurface) { mVBuf = AllocateBufferForImage(mSize, mFormat); if (!mVBuf) { return NS_ERROR_OUT_OF_MEMORY; } if (mVBuf->OnHeap()) { int32_t stride = VolatileSurfaceStride(mSize, mFormat); VolatileBufferPtr<uint8_t> ptr(mVBuf); memset(ptr, 0, stride * mSize.height); } mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat); } if (!mImageSurface) { NS_WARNING("Failed to create VolatileDataSourceSurface"); // Image surface allocation is failed, need to return // the booked buffer size. DiscardTracker::InformDeallocation(4 * mSize.width * mSize.height); return NS_ERROR_OUT_OF_MEMORY; } mInformedDiscardTracker = true; } return NS_OK; }
void imgFrame::GetPaletteData(PRUint32 **aPalette, PRUint32 *length) const { if (!mPalettedImageData) { *aPalette = nsnull; *length = 0; } else { *aPalette = (PRUint32 *) mPalettedImageData; *length = PaletteDataLength(); } }
void imgFrame::GetImageData(PRUint8 **aData, PRUint32 *length) const { if (mImageSurface) *aData = mImageSurface->Data(); else if (mPalettedImageData) *aData = mPalettedImageData + PaletteDataLength(); else *aData = nsnull; *length = GetImageDataLength(); }
nsresult imgFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, gfxASurface::gfxImageFormat aFormat, PRUint8 aPaletteDepth /* = 0 */) { // assert for properties that should be verified by decoders, warn for properties related to bad content if (!AllowedImageSize(aWidth, aHeight)) return NS_ERROR_FAILURE; mOffset.MoveTo(aX, aY); mSize.SizeTo(aWidth, aHeight); mFormat = aFormat; mPaletteDepth = aPaletteDepth; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_ERROR("This Depth is not supported"); return NS_ERROR_FAILURE; } // Use the fallible allocator here mPalettedImageData = (PRUint8*)moz_malloc(PaletteDataLength() + GetImageDataLength()); NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { // For Windows, we must create the device surface first (if we're // going to) so that the image surface can wrap it. Can't be done // the other way around. #ifdef USE_WIN_SURFACE if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) { mWinSurface = new gfxWindowsSurface(gfxIntSize(mSize.width, mSize.height), mFormat); if (mWinSurface && mWinSurface->CairoStatus() == 0) { // no error mImageSurface = mWinSurface->GetAsImageSurface(); } else { mWinSurface = nsnull; } } #endif // For other platforms we create the image surface first and then // possibly wrap it in a device surface. This branch is also used // on Windows if we're not using device surfaces or if we couldn't // create one. if (!mImageSurface) mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height), mFormat); if (!mImageSurface || mImageSurface->CairoStatus()) { mImageSurface = nsnull; // guess return NS_ERROR_OUT_OF_MEMORY; } #ifdef XP_MACOSX if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) { mQuartzSurface = new gfxQuartzImageSurface(mImageSurface); } #endif } return NS_OK; }
nsresult imgFrame::InitForDecoder(const nsIntSize& aImageSize, const nsIntRect& aRect, SurfaceFormat aFormat, uint8_t aPaletteDepth /* = 0 */, bool aNonPremult /* = false */) { // Assert for properties that should be verified by decoders, // warn for properties related to bad content. if (!AllowedImageAndFrameDimensions(aImageSize, aRect)) { NS_WARNING("Should have legal image size"); mAborted = true; return NS_ERROR_FAILURE; } mImageSize = aImageSize; mOffset.MoveTo(aRect.x, aRect.y); mSize.SizeTo(aRect.width, aRect.height); mFormat = aFormat; mPaletteDepth = aPaletteDepth; mNonPremult = aNonPremult; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_WARNING("Should have legal palette depth"); NS_ERROR("This Depth is not supported"); mAborted = true; return NS_ERROR_FAILURE; } // Use the fallible allocator here. Paletted images always use 1 byte per // pixel, so calculating the amount of memory we need is straightforward. mPalettedImageData = static_cast<uint8_t*>(malloc(PaletteDataLength() + (mSize.width * mSize.height))); if (!mPalettedImageData) { NS_WARNING("malloc for paletted image data should succeed"); } NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { MOZ_ASSERT(!mImageSurface, "Called imgFrame::InitForDecoder() twice?"); mVBuf = AllocateBufferForImage(mSize, mFormat); if (!mVBuf) { mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } if (mVBuf->OnHeap()) { int32_t stride = VolatileSurfaceStride(mSize, mFormat); VolatileBufferPtr<uint8_t> ptr(mVBuf); memset(ptr, 0, stride * mSize.height); } mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat); if (!mImageSurface) { NS_WARNING("Failed to create VolatileDataSourceSurface"); mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }
nsresult imgFrame::InitForDecoder(const nsIntSize& aImageSize, const nsIntRect& aRect, SurfaceFormat aFormat, uint8_t aPaletteDepth /* = 0 */, bool aNonPremult /* = false */) { // Assert for properties that should be verified by decoders, // warn for properties related to bad content. if (!AllowedImageAndFrameDimensions(aImageSize, aRect)) { NS_WARNING("Should have legal image size"); mAborted = true; return NS_ERROR_FAILURE; } mImageSize = aImageSize; mFrameRect = aRect; mFormat = aFormat; mPaletteDepth = aPaletteDepth; mNonPremult = aNonPremult; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_WARNING("Should have legal palette depth"); NS_ERROR("This Depth is not supported"); mAborted = true; return NS_ERROR_FAILURE; } // Use the fallible allocator here. Paletted images always use 1 byte per // pixel, so calculating the amount of memory we need is straightforward. size_t dataSize = PaletteDataLength() + mFrameRect.Area(); mPalettedImageData = static_cast<uint8_t*>(calloc(dataSize, sizeof(uint8_t))); if (!mPalettedImageData) { NS_WARNING("Call to calloc for paletted image data should succeed"); } NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { MOZ_ASSERT(!mImageSurface, "Called imgFrame::InitForDecoder() twice?"); mVBuf = AllocateBufferForImage(mFrameRect.Size(), mFormat); if (!mVBuf) { mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } mImageSurface = CreateLockedSurface(mVBuf, mFrameRect.Size(), mFormat); if (!mImageSurface) { NS_WARNING("Failed to create ImageSurface"); mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } if (!ClearSurface(mVBuf, mFrameRect.Size(), mFormat)) { NS_WARNING("Could not clear allocated buffer"); mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }