diff --git a/content/canvas/src/ImageEncoder.cpp b/content/canvas/src/ImageEncoder.cpp deleted file mode 100644 index 1f03353f9104..000000000000 --- a/content/canvas/src/ImageEncoder.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -#include "gfxImageSurface.h" -#include "ImageEncoder.h" -#include "mozilla/dom/CanvasRenderingContext2D.h" - -namespace mozilla { -namespace dom { - -class EncodingCompleteEvent : public nsRunnable -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - - EncodingCompleteEvent(nsIScriptContext* aScriptContext, - nsIThread* aEncoderThread, - FileCallback& aCallback) - : mImgSize(0) - , mType() - , mImgData(nullptr) - , mScriptContext(aScriptContext) - , mEncoderThread(aEncoderThread) - , mCallback(&aCallback) - {} - virtual ~EncodingCompleteEvent() {} - - NS_IMETHOD Run() - { - MOZ_ASSERT(NS_IsMainThread()); - - nsRefPtr blob = - new nsDOMMemoryFile(mImgData, mImgSize, mType); - - if (mScriptContext) { - JSContext* jsContext = mScriptContext->GetNativeContext(); - if (jsContext) { - JS_updateMallocCounter(jsContext, mImgSize); - } - } - - mozilla::ErrorResult rv; - mCallback->Call(blob, rv); - NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode()); - - mEncoderThread->Shutdown(); - return rv.ErrorCode(); - } - - void SetMembers(void* aImgData, uint64_t aImgSize, const nsAutoString& aType) - { - mImgData = aImgData; - mImgSize = aImgSize; - mType = aType; - } - -private: - uint64_t mImgSize; - nsAutoString mType; - void* mImgData; - nsCOMPtr mScriptContext; - nsCOMPtr mEncoderThread; - nsRefPtr mCallback; -}; - -NS_IMPL_ISUPPORTS1(EncodingCompleteEvent, nsIRunnable); - -class EncodingRunnable : public nsRunnable -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - - EncodingRunnable(const nsAString& aType, - const nsAString& aOptions, - uint8_t* aImageBuffer, - imgIEncoder* aEncoder, - EncodingCompleteEvent* aEncodingCompleteEvent, - int32_t aFormat, - const nsIntSize aSize, - bool aUsingCustomOptions) - : mType(aType) - , mOptions(aOptions) - , mImageBuffer(aImageBuffer) - , mEncoder(aEncoder) - , mEncodingCompleteEvent(aEncodingCompleteEvent) - , mFormat(aFormat) - , mSize(aSize) - , mUsingCustomOptions(aUsingCustomOptions) - {} - virtual ~EncodingRunnable() {} - - NS_IMETHOD Run() - { - nsCOMPtr stream; - nsresult rv = ImageEncoder::ExtractDataInternal(mType, - mOptions, - mImageBuffer, - mFormat, - mSize, - nullptr, - getter_AddRefs(stream), - mEncoder); - - // If there are unrecognized custom parse options, we should fall back to - // the default values for the encoder without any options at all. - if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) { - rv = ImageEncoder::ExtractDataInternal(mType, - EmptyString(), - mImageBuffer, - mFormat, - mSize, - nullptr, - getter_AddRefs(stream), - mEncoder); - } - NS_ENSURE_SUCCESS(rv, rv); - - uint64_t imgSize; - rv = stream->Available(&imgSize); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(imgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); - - void* imgData = nullptr; - rv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize); - NS_ENSURE_SUCCESS(rv, rv); - - mEncodingCompleteEvent->SetMembers(imgData, imgSize, mType); - rv = NS_DispatchToMainThread(mEncodingCompleteEvent, NS_DISPATCH_NORMAL); - NS_ENSURE_SUCCESS(rv, rv); - - return rv; - } - -private: - nsAutoString mType; - nsAutoString mOptions; - nsAutoArrayPtr mImageBuffer; - nsCOMPtr mEncoder; - nsRefPtr mEncodingCompleteEvent; - int32_t mFormat; - const nsIntSize mSize; - bool mUsingCustomOptions; -}; - -NS_IMPL_ISUPPORTS1(EncodingRunnable, nsIRunnable) - -/* static */ -nsresult -ImageEncoder::ExtractData(nsAString& aType, - const nsAString& aOptions, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIInputStream** aStream) -{ - nsCOMPtr encoder = ImageEncoder::GetImageEncoder(aType); - if (!encoder) { - return NS_IMAGELIB_ERROR_NO_ENCODER; - } - - return ExtractDataInternal(aType, aOptions, nullptr, 0, aSize, aContext, - aStream, encoder); -} - -/* static */ -nsresult -ImageEncoder::ExtractDataAsync(nsAString& aType, - const nsAString& aOptions, - bool aUsingCustomOptions, - uint8_t* aImageBuffer, - int32_t aFormat, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIScriptContext* aScriptContext, - FileCallback& aCallback) -{ - nsCOMPtr encoder = ImageEncoder::GetImageEncoder(aType); - if (!encoder) { - return NS_IMAGELIB_ERROR_NO_ENCODER; - } - - nsCOMPtr encoderThread; - nsresult rv = NS_NewThread(getter_AddRefs(encoderThread), nullptr); - NS_ENSURE_SUCCESS(rv, rv); - - nsRefPtr completeEvent = - new EncodingCompleteEvent(aScriptContext, encoderThread, aCallback); - - nsCOMPtr event = new EncodingRunnable(aType, - aOptions, - aImageBuffer, - encoder, - completeEvent, - aFormat, - aSize, - aUsingCustomOptions); - return encoderThread->Dispatch(event, NS_DISPATCH_NORMAL); -} - -/*static*/ nsresult -ImageEncoder::GetInputStream(int32_t aWidth, - int32_t aHeight, - uint8_t* aImageBuffer, - int32_t aFormat, - imgIEncoder* aEncoder, - const PRUnichar* aEncoderOptions, - nsIInputStream** aStream) -{ - nsresult rv = - aEncoder->InitFromData(aImageBuffer, - aWidth * aHeight * 4, aWidth, aHeight, aWidth * 4, - aFormat, - nsDependentString(aEncoderOptions)); - NS_ENSURE_SUCCESS(rv, rv); - - return CallQueryInterface(aEncoder, aStream); -} - -/* static */ -nsresult -ImageEncoder::ExtractDataInternal(const nsAString& aType, - const nsAString& aOptions, - uint8_t* aImageBuffer, - int32_t aFormat, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIInputStream** aStream, - imgIEncoder* aEncoder) -{ - nsCOMPtr imgStream; - - // get image bytes - nsresult rv; - if (aImageBuffer) { - rv = ImageEncoder::GetInputStream( - aSize.width, - aSize.height, - aImageBuffer, - aFormat, - aEncoder, - nsPromiseFlatString(aOptions).get(), - getter_AddRefs(imgStream)); - } else if (aContext) { - NS_ConvertUTF16toUTF8 encoderType(aType); - rv = aContext->GetInputStream(encoderType.get(), - nsPromiseFlatString(aOptions).get(), - getter_AddRefs(imgStream)); - } else { - // no context, so we have to encode an empty image - // note that if we didn't have a current context, the spec says we're - // supposed to just return transparent black pixels of the canvas - // dimensions. - nsRefPtr emptyCanvas = - new gfxImageSurface(gfxIntSize(aSize.width, aSize.height), - gfxImageFormatARGB32); - if (emptyCanvas->CairoStatus()) { - return NS_ERROR_INVALID_ARG; - } - rv = aEncoder->InitFromData(emptyCanvas->Data(), - aSize.width * aSize.height * 4, - aSize.width, - aSize.height, - aSize.width * 4, - imgIEncoder::INPUT_FORMAT_HOSTARGB, - aOptions); - if (NS_SUCCEEDED(rv)) { - imgStream = do_QueryInterface(aEncoder); - } - } - NS_ENSURE_SUCCESS(rv, rv); - - imgStream.forget(aStream); - return rv; -} - -/* static */ -already_AddRefed -ImageEncoder::GetImageEncoder(nsAString& aType) -{ - // Get an image encoder for the media type. - nsCString encoderCID("@mozilla.org/image/encoder;2?type="); - NS_ConvertUTF16toUTF8 encoderType(aType); - encoderCID += encoderType; - nsCOMPtr encoder = do_CreateInstance(encoderCID.get()); - - if (!encoder && aType != NS_LITERAL_STRING("image/png")) { - // Unable to create an encoder instance of the specified type. Falling back - // to PNG. - aType.AssignLiteral("image/png"); - nsCString PNGEncoderCID("@mozilla.org/image/encoder;2?type=image/png"); - encoder = do_CreateInstance(PNGEncoderCID.get()); - } - - return encoder.forget(); -} - -} // namespace dom -} // namespace mozilla diff --git a/content/canvas/src/ImageEncoder.h b/content/canvas/src/ImageEncoder.h deleted file mode 100644 index 391def94a941..000000000000 --- a/content/canvas/src/ImageEncoder.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -#ifndef ImageEncoder_h -#define ImageEncoder_h - -#include "imgIEncoder.h" -#include "nsDOMFile.h" -#include "nsError.h" -#include "mozilla/dom/HTMLCanvasElementBinding.h" -#include "nsLayoutUtils.h" -#include "nsNetUtil.h" -#include "nsSize.h" - -class nsICanvasRenderingContextInternal; - -namespace mozilla { -namespace dom { - -class EncodingRunnable; - -class ImageEncoder -{ -public: - // Extracts data synchronously and gives you a stream containing the image - // represented by aContext. aType may change to "image/png" if we had to fall - // back to a PNG encoder. A return value of NS_OK implies successful data - // extraction. If there are any unrecognized custom parse options in - // aOptions, NS_ERROR_INVALID_ARG will be returned. When encountering this - // error it is usual to call this function again without any options at all. - static nsresult ExtractData(nsAString& aType, - const nsAString& aOptions, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIInputStream** aStream); - - // Extracts data asynchronously. aType may change to "image/png" if we had to - // fall back to a PNG encoder. aOptions are the options to be passed to the - // encoder and aUsingCustomOptions specifies whether custom parse options were - // used (i.e. by using -moz-parse-options). If there are any unrecognized - // custom parse options, we fall back to the default values for the encoder - // without any options at all. A return value of NS_OK only implies - // successful dispatching of the extraction step to the encoding thread. - static nsresult ExtractDataAsync(nsAString& aType, - const nsAString& aOptions, - bool aUsingCustomOptions, - uint8_t* aImageBuffer, - int32_t aFormat, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIScriptContext* aScriptContext, - FileCallback& aCallback); - - // Gives you a stream containing the image represented by aImageBuffer. - // The format is given in aFormat, for example - // imgIEncoder::INPUT_FORMAT_HOSTARGB. - static nsresult GetInputStream(int32_t aWidth, - int32_t aHeight, - uint8_t* aImageBuffer, - int32_t aFormat, - imgIEncoder* aEncoder, - const PRUnichar* aEncoderOptions, - nsIInputStream** aStream); - -private: - // When called asynchronously, aContext is null. - static nsresult - ExtractDataInternal(const nsAString& aType, - const nsAString& aOptions, - uint8_t* aImageBuffer, - int32_t aFormat, - const nsIntSize aSize, - nsICanvasRenderingContextInternal* aContext, - nsIInputStream** aStream, - imgIEncoder* aEncoder); - - // Creates and returns an encoder instance of the type specified in aType. - // aType may change to "image/png" if no instance of the original type could - // be created and we had to fall back to a PNG encoder. A return value of - // NULL should be interpreted as NS_IMAGELIB_ERROR_NO_ENCODER and aType is - // undefined in this case. - static already_AddRefed GetImageEncoder(nsAString& aType); - - friend class EncodingRunnable; -}; - -} // namespace dom -} // namespace mozilla - -#endif // ImageEncoder_h \ No newline at end of file diff --git a/content/canvas/src/moz.build b/content/canvas/src/moz.build index bacae09c0046..694667da1d6c 100644 --- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -22,7 +22,6 @@ CPP_SOURCES += [ 'DocumentRendererChild.cpp', 'DocumentRendererParent.cpp', 'ImageData.cpp', - 'ImageEncoder.cpp', ] if CONFIG['MOZ_WEBGL']: