/* static */ already_AddRefed<Image> ImageFactory::CreateVectorImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, ImageURL* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { MOZ_ASSERT(aProgressTracker); nsresult rv; nsRefPtr<VectorImage> newImage = new VectorImage(aURI); aProgressTracker->SetImage(newImage); newImage->SetProgressTracker(aProgressTracker); rv = newImage->Init(aMimeType.get(), aImageFlags); if (NS_FAILED(rv)) { return BadImage("VectorImage::Init failed", newImage); } newImage->SetInnerWindowID(aInnerWindowId); rv = newImage->OnStartRequest(aRequest, nullptr); if (NS_FAILED(rv)) { return BadImage("VectorImage::OnStartRequest failed", newImage); } return newImage.forget(); }
/* static */ already_AddRefed<Image> ImageFactory::CreateRasterImage(nsIRequest* aRequest, imgStatusTracker* aStatusTracker, const nsCString& aMimeType, ImageURL* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { nsresult rv; nsRefPtr<RasterImage> newImage = new RasterImage(aStatusTracker, aURI); rv = newImage->Init(aMimeType.get(), aImageFlags); NS_ENSURE_SUCCESS(rv, BadImage(newImage)); newImage->SetInnerWindowID(aInnerWindowId); uint32_t len = GetContentSize(aRequest); // Pass anything usable on so that the RasterImage can preallocate // its source buffer. if (len > 0) { uint32_t sizeHint = std::min<uint32_t>(len, 20000000); // Bound by something reasonable 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!"); } } } nsAutoCString ref; aURI->GetRef(ref); mozilla::net::nsMediaFragmentURIParser parser(ref); if (parser.HasResolution()) { newImage->SetRequestedResolution(parser.GetResolution()); } if (parser.HasSampleSize()) { /* Get our principal */ nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest)); nsCOMPtr<nsIPrincipal> principal; if (chan) { nsContentUtils::GetSecurityManager()->GetChannelPrincipal(chan, getter_AddRefs(principal)); } if ((principal && principal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED) || gEnableMozSampleSize) { newImage->SetRequestedSampleSize(parser.GetSampleSize()); } } return newImage.forget(); }
/* static */ already_AddRefed<Image> ImageFactory::CreateImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, ImageURL* aURI, bool aIsMultiPart, uint32_t aInnerWindowId) { MOZ_ASSERT(gfxPrefs::SingletonExists(), "Pref observers should have been initialized already"); // Compute the image's initialization flags. uint32_t imageFlags = ComputeImageFlags(aURI, aMimeType, aIsMultiPart); // Select the type of image to create based on MIME type. if (aMimeType.EqualsLiteral(IMAGE_SVG_XML)) { nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest)); if (!NS_SVGEnabledForChannel(channel)) { // SVG is disabled. We must return an image object that is marked // "bad", but we want to avoid invoking the VectorImage class (SVG code), // so we return a PNG with the error flag set. nsRefPtr<RasterImage> badImage = new RasterImage(aProgressTracker, aURI); (void)badImage->Init(IMAGE_PNG, Image::INIT_FLAG_NONE); return BadImage(badImage); } return CreateVectorImage(aRequest, aProgressTracker, aMimeType, aURI, imageFlags, aInnerWindowId); } else { return CreateRasterImage(aRequest, aProgressTracker, aMimeType, aURI, imageFlags, aInnerWindowId); } }
/* static */ already_AddRefed<Image> ImageFactory::CreateAnonymousImage(const nsCString& aMimeType) { nsresult rv; nsRefPtr<RasterImage> newImage = new RasterImage(); rv = newImage->Init(aMimeType.get(), Image::INIT_FLAG_NONE); NS_ENSURE_SUCCESS(rv, BadImage(newImage)); return newImage.forget(); }
/* static */ already_AddRefed<Image> ImageFactory::CreateVectorImage(nsIRequest* aRequest, imgStatusTracker* aStatusTracker, const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { nsresult rv; nsRefPtr<VectorImage> newImage = new VectorImage(aStatusTracker, aURI); rv = newImage->Init(aMimeType.get(), aImageFlags); NS_ENSURE_SUCCESS(rv, BadImage(newImage)); newImage->SetInnerWindowID(aInnerWindowId); rv = newImage->OnStartRequest(aRequest, nullptr); NS_ENSURE_SUCCESS(rv, BadImage(newImage)); return newImage.forget(); }
/* static */ already_AddRefed<Image> ImageFactory::CreateAnonymousImage(const nsCString& aMimeType) { nsresult rv; nsRefPtr<RasterImage> newImage = new RasterImage(); nsRefPtr<ProgressTracker> newTracker = new ProgressTracker(); newTracker->SetImage(newImage); newImage->SetProgressTracker(newTracker); rv = newImage->Init(aMimeType.get(), Image::INIT_FLAG_SYNC_LOAD); if (NS_FAILED(rv)) { return BadImage("RasterImage::Init failed", newImage); } return newImage.forget(); }
/* static */ already_AddRefed<Image> ImageFactory::CreateRasterImage(nsIRequest* aRequest, imgStatusTracker* aStatusTracker, const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { nsresult rv; nsRefPtr<RasterImage> newImage = new RasterImage(aStatusTracker, aURI); rv = newImage->Init(aMimeType.get(), aImageFlags); NS_ENSURE_SUCCESS(rv, BadImage(newImage)); newImage->SetInnerWindowID(aInnerWindowId); uint32_t len = GetContentSize(aRequest); // Pass anything usable on so that the RasterImage can preallocate // its source buffer. if (len > 0) { uint32_t sizeHint = std::min<uint32_t>(len, 20000000); // Bound by something reasonable 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!"); } } } mozilla::net::nsMediaFragmentURIParser parser(aURI); if (parser.HasResolution()) { newImage->SetRequestedResolution(parser.GetResolution()); } return newImage.forget(); }