mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1383404 - Part 4. imgTools::DecodeImage should set the source size hint to optimize the allocation. r=tnikkel
This commit is contained in:
parent
af89f9b9b6
commit
9ea902f3c5
@ -124,8 +124,32 @@ BadImage(const char* aMessage, RefPtr<T>& aImage)
|
||||
return aImage.forget();
|
||||
}
|
||||
|
||||
static void
|
||||
SetSourceSizeHint(RasterImage* aImage, uint32_t aSize)
|
||||
{
|
||||
// Pass anything usable on so that the RasterImage can preallocate
|
||||
// its source buffer.
|
||||
if (aSize == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bound by something reasonable
|
||||
uint32_t sizeHint = std::min<uint32_t>(aSize, 20000000);
|
||||
nsresult rv = aImage->SetSourceSizeHint(sizeHint);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Flush memory, try to get some back, and try again.
|
||||
rv = nsMemory::HeapMinimize(true);
|
||||
nsresult rv2 = aImage->SetSourceSizeHint(sizeHint);
|
||||
// If we've still failed at this point, things are going downhill.
|
||||
if (NS_FAILED(rv) || NS_FAILED(rv2)) {
|
||||
NS_WARNING("About to hit OOM in imagelib!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Image>
|
||||
ImageFactory::CreateAnonymousImage(const nsCString& aMimeType)
|
||||
ImageFactory::CreateAnonymousImage(const nsCString& aMimeType,
|
||||
uint32_t aSizeHint /* = 0 */)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -140,6 +164,7 @@ ImageFactory::CreateAnonymousImage(const nsCString& aMimeType)
|
||||
return BadImage("RasterImage::Init failed", newImage);
|
||||
}
|
||||
|
||||
SetSourceSizeHint(newImage, aSizeHint);
|
||||
return newImage.forget();
|
||||
}
|
||||
|
||||
@ -225,25 +250,7 @@ ImageFactory::CreateRasterImage(nsIRequest* aRequest,
|
||||
|
||||
newImage->SetInnerWindowID(aInnerWindowId);
|
||||
|
||||
uint32_t len = GetContentSize(aRequest);
|
||||
|
||||
// Pass anything usable on so that the RasterImage can preallocate
|
||||
// its source buffer.
|
||||
if (len > 0) {
|
||||
// Bound by something reasonable
|
||||
uint32_t sizeHint = std::min<uint32_t>(len, 20000000);
|
||||
rv = newImage->SetSourceSizeHint(sizeHint);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Flush memory, try to get some back, and try again.
|
||||
rv = nsMemory::HeapMinimize(true);
|
||||
nsresult rv2 = newImage->SetSourceSizeHint(sizeHint);
|
||||
// If we've still failed at this point, things are going downhill.
|
||||
if (NS_FAILED(rv) || NS_FAILED(rv2)) {
|
||||
NS_WARNING("About to hit OOM in imagelib!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetSourceSizeHint(newImage, GetContentSize(aRequest));
|
||||
return newImage.forget();
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,10 @@ public:
|
||||
* the usual image loading mechanism.
|
||||
*
|
||||
* @param aMimeType The mimetype of the image.
|
||||
* @param aSizeHint The length of the source data for the image.
|
||||
*/
|
||||
static already_AddRefed<Image>
|
||||
CreateAnonymousImage(const nsCString& aMimeType);
|
||||
CreateAnonymousImage(const nsCString& aMimeType, uint32_t aSizeHint = 0);
|
||||
|
||||
/**
|
||||
* Creates a new multipart/x-mixed-replace image wrapper, and initializes it
|
||||
|
@ -68,15 +68,6 @@ imgTools::DecodeImage(nsIInputStream* aInStr,
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aInStr);
|
||||
|
||||
// Create a new image container to hold the decoded data.
|
||||
nsAutoCString mimeType(aMimeType);
|
||||
RefPtr<image::Image> image = ImageFactory::CreateAnonymousImage(mimeType);
|
||||
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
|
||||
|
||||
if (image->HasError()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Prepare the input stream.
|
||||
nsCOMPtr<nsIInputStream> inStream = aInStr;
|
||||
if (!NS_InputStreamIsBuffered(aInStr)) {
|
||||
@ -93,6 +84,16 @@ imgTools::DecodeImage(nsIInputStream* aInStr,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(length <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
|
||||
|
||||
// Create a new image container to hold the decoded data.
|
||||
nsAutoCString mimeType(aMimeType);
|
||||
RefPtr<image::Image> image =
|
||||
ImageFactory::CreateAnonymousImage(mimeType, uint32_t(length));
|
||||
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
|
||||
|
||||
if (image->HasError()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Send the source data to the Image.
|
||||
rv = image->OnImageDataAvailable(nullptr, nullptr, inStream, 0,
|
||||
uint32_t(length));
|
||||
|
Loading…
Reference in New Issue
Block a user