--- a/dom/canvas/ImageBitmapUtils.cpp
+++ b/dom/canvas/ImageBitmapUtils.cpp
@@ -11,209 +11,308 @@
#include "mozilla/gfx/2D.h"
using namespace libyuv;
using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
-/* static */ ImageBitmapFormatUtils*
+class ImageBitmapFormatUtils;
+class ImageBitmapFormatUtils_RGBA32;
+class ImageBitmapFormatUtils_BGRA32;
+class ImageBitmapFormatUtils_YUV420P;
+
+/*
+ * The UtilsUniquePtr is a UniquePtr to ImageBitmapFormatUtils with a customized
+ * deleter which does nothing. This is used as the return type of
+ * ImageBitmapFormatUtils::GetUtils to prevent users deleting the returned
+ * pointer.
+ */
+struct DoNotDelete { void operator()(void* p) {} };
+using UtilsUniquePtr = UniquePtr<ImageBitmapFormatUtils, DoNotDelete>;
+
+/*
+ * ImageBitmapFormatUtils is an abstract class which provides interfaces to
+ * extract information of each ImageBitmapFormat and interfaces to convert
+ * image data between different ImageBitmapFormats. For each kind of
+ * ImageBitmapFromat, we derive a subclass from the ImageBitmapFormatUtils to
+ * implement functionalities that are subject to the specific ImageBitmapFormat.
+ *
+ * ImageBitmapFormatUtils is an abstract class and its sub-classes are designed
+ * as singletons. The singleton instance of sub-classes could be initialized and
+ * accessed via the ImageBitmapFormatUtils::GetUtils() static method. The
+ * singleton instance is a static local variable which does not need to be
+ * released manually and, with the C++11 static initialization, the
+ * initialization is thread-safe.
+ *
+ * ImageBitmapFormatUtils and its sub-classes are designed to unify operations
+ * of ImageBitmap-extensions over different kinds of ImageBitmapFormats; they
+ * provide following functionalities:
+ *
+ * (1) Create default/customized ImagePixelLayout object of each kind of
+ * ImageBitmapFormat.
+ * (2) Store the channel counts of each ImageBitmapFormat.
+ * (3) Calculate the needed buffer size of each kind of ImageBitmapFormat with
+ * given width, height and stride.
+ * (4) Perform color conversion between supported ImageBitmapFormats. We use
+ * _double dispatching_ to identify the source format and destination format
+ * at run time. The _double dispatching_ here is mainly implemented by
+ * overriding the _convertTo_ method over the ImageBitmapFormatUtils class
+ * hierarchy and overloading the _convertFrom_ methods over all sub-classes
+ * of ImageBitmapFormatUtils.
+ */
+
+class ImageBitmapFormatUtils
+{
+public:
+ // Get the singleton utility instance of the given ImageBitmapFormat.
+ static UtilsUniquePtr GetUtils(ImageBitmapFormat aFormat);
+
+ // Get the needed buffer size to store image data in the current
+ // ImageBitmapFormat with the given width and height.
+ // The current ImageBitmapFormat is the format used to implement the concrete
+ // subclass of which the current instance is initialized.
+ virtual uint32_t NeededBufferSize(uint32_t width, uint32_t height) = 0;
+
+ // Creates a default ImagePixelLayout object of the current ImageBitmapFormat
+ // with the given width, height and stride.
+ virtual UniquePtr<ImagePixelLayout>
+ CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride) = 0;
+
+ // Creates a customized ImagePixelLayout object of the current
+ // ImageBitmapFormatfrom using the information extracted from the aImage
+ // parameter.
+ virtual UniquePtr<ImagePixelLayout>
+ CreateCustomizedLayout(layers::Image* aImage) = 0;
+
+ // Convert the source image data (stored in the aSrcBuffer and described by
+ // the aSrcLayout) from the current ImageBitmapFormat to the given
+ // ImageBitmapFormat, aDstFormat.
+ // The converted image data is stored in the aDstBuffer and described by the
+ // returned ImagePixelLayout object.
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
+
+ // Convert the source RGBA32 source image data (stored in the aSrcBuffer and
+ // described by the aSrcLayout) to the current ImageBitmapFormat.
+ // The converted image data is stored in the aDstBuffer and described by the
+ // returned ImagePixelLayout object.
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
+
+ // Convert the source BGRA32 source image data (stored in the aSrcBuffer and
+ // described by the aSrcLayout) to the current ImageBitmapFormat.
+ // The converted image data is stored in the aDstBuffer and described by the
+ // returned ImagePixelLayout object.
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
+
+ // Convert the source YUV420P source image data (stored in the aSrcBuffer and
+ // described by the aSrcLayout) to the current ImageBitmapFormat.
+ // The converted image data is stored in the aDstBuffer and described by the
+ // returned ImagePixelLayout object.
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
+
+ // Check whether or not the current ImageBitmapFormat can be converted from
+ // the given ImageBitmapFormat.
+ virtual bool
+ CanConvertFrom(ImageBitmapFormat aSrcFormat) = 0;
+
+ // Get the number of channels.
+ uint8_t GetChannelCount() const
+ {
+ return mChannels;
+ }
+
+protected:
+ explicit ImageBitmapFormatUtils(uint32_t aChannels)
+ : mChannels(aChannels)
+ {
+ }
+
+ virtual ~ImageBitmapFormatUtils()
+ {
+ }
+
+ const uint8_t mChannels;
+};
+
+class ImageBitmapFormatUtils_RGBA32 : public ImageBitmapFormatUtils
+{
+private:
+ explicit ImageBitmapFormatUtils_RGBA32()
+ : ImageBitmapFormatUtils(4)
+ {
+ }
+
+ ~ImageBitmapFormatUtils_RGBA32() = default;
+ ImageBitmapFormatUtils_RGBA32(ImageBitmapFormatUtils_RGBA32 const &) = delete;
+ ImageBitmapFormatUtils_RGBA32(ImageBitmapFormatUtils_RGBA32&&) = delete;
+ ImageBitmapFormatUtils_RGBA32& operator=(ImageBitmapFormatUtils_RGBA32 const &) = delete;
+ ImageBitmapFormatUtils_RGBA32& operator=(ImageBitmapFormatUtils_RGBA32&&) = delete;
+
+public:
+ static ImageBitmapFormatUtils_RGBA32& GetInstance();
+
+ virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
+ {
+ return aWidth * aHeight * (uint32_t)mChannels;
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateCustomizedLayout(layers::Image* aImage) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
+ {
+ return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual bool
+ CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
+};
+
+class ImageBitmapFormatUtils_BGRA32 : public ImageBitmapFormatUtils
+{
+private:
+ explicit ImageBitmapFormatUtils_BGRA32()
+ : ImageBitmapFormatUtils(4)
+ {
+ }
+
+ ~ImageBitmapFormatUtils_BGRA32() = default;
+ ImageBitmapFormatUtils_BGRA32(ImageBitmapFormatUtils_BGRA32 const &) = delete;
+ ImageBitmapFormatUtils_BGRA32(ImageBitmapFormatUtils_BGRA32&&) = delete;
+ ImageBitmapFormatUtils_BGRA32& operator=(ImageBitmapFormatUtils_BGRA32 const &) = delete;
+ ImageBitmapFormatUtils_BGRA32& operator=(ImageBitmapFormatUtils_BGRA32&&) = delete;
+
+public:
+ static ImageBitmapFormatUtils_BGRA32& GetInstance();
+
+ virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
+ {
+ return aWidth * aHeight * (uint32_t)mChannels;
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateCustomizedLayout(layers::Image* aImage) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
+ {
+ return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual bool
+ CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
+};
+
+class ImageBitmapFormatUtils_YUV420P : public ImageBitmapFormatUtils
+{
+private:
+ explicit ImageBitmapFormatUtils_YUV420P()
+ : ImageBitmapFormatUtils(3)
+ {
+ }
+
+ ~ImageBitmapFormatUtils_YUV420P() = default;
+ ImageBitmapFormatUtils_YUV420P(ImageBitmapFormatUtils_YUV420P const &) = delete;
+ ImageBitmapFormatUtils_YUV420P(ImageBitmapFormatUtils_YUV420P&&) = delete;
+ ImageBitmapFormatUtils_YUV420P& operator=(ImageBitmapFormatUtils_YUV420P const &) = delete;
+ ImageBitmapFormatUtils_YUV420P& operator=(ImageBitmapFormatUtils_YUV420P&&) = delete;
+
+public:
+ static ImageBitmapFormatUtils_YUV420P& GetInstance();
+
+ virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
+ {
+ return aWidth * aHeight + 2 * (aWidth / 2) * (aHeight / 2);
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ CreateCustomizedLayout(layers::Image* aImage) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
+ {
+ return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
+ }
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual UniquePtr<ImagePixelLayout>
+ ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
+
+ virtual bool
+ CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
+};
+
+/*
+ * ImageBitmapFormatUtils.
+ */
+/* static */ UtilsUniquePtr
ImageBitmapFormatUtils::GetUtils(ImageBitmapFormat aFormat)
{
switch(aFormat)
{
case ImageBitmapFormat::RGBA32:
- return &ImageBitmapFormatUtils_RGBA32::GetInstance();
+ return UtilsUniquePtr(&ImageBitmapFormatUtils_RGBA32::GetInstance());
case ImageBitmapFormat::BGRA32:
- return &ImageBitmapFormatUtils_BGRA32::GetInstance();
+ return UtilsUniquePtr(&ImageBitmapFormatUtils_BGRA32::GetInstance());
case ImageBitmapFormat::RGB24:
case ImageBitmapFormat::BGR24:
case ImageBitmapFormat::GRAY8:
case ImageBitmapFormat::YUV444P:
case ImageBitmapFormat::YUV422P:
return nullptr;
case ImageBitmapFormat::YUV420P:
- return &ImageBitmapFormatUtils_YUV420P::GetInstance();
+ return UtilsUniquePtr(&ImageBitmapFormatUtils_YUV420P::GetInstance());
case ImageBitmapFormat::YUV420SP_NV12:
case ImageBitmapFormat::YUV420SP_NV21:
case ImageBitmapFormat::HSV:
case ImageBitmapFormat::Lab:
case ImageBitmapFormat::DEPTH:
default:
return nullptr;
}
}
-/* static */ UniquePtr<ImagePixelLayout>
-ImageBitmapFormatUtils::CreateDefaultLayout(ImageBitmapFormat aFormat,
- uint32_t aWidth,
- uint32_t aHeight,
- uint32_t aStride)
-{
- // information from format
- uint8_t channelCount = GetChannelCountOfImageFormat(aFormat);
-
- UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(channelCount));
-
- // set mChannels
- switch (aFormat) {
- case ImageBitmapFormat::RGBA32:
- case ImageBitmapFormat::BGRA32:
- case ImageBitmapFormat::RGB24:
- case ImageBitmapFormat::BGR24:
- {
- for (uint8_t i = 0; i < channelCount; ++i) {
- ChannelPixelLayout* channel = layout->AppendElement();
- channel->mOffset = i;
- channel->mWidth = aWidth;
- channel->mHeight = aHeight;
- channel->mDataType = ChannelPixelLayoutDataType::Uint8;
- channel->mStride = aStride;
- channel->mSkip = channelCount - 1;
- }
- break;
- }
- case ImageBitmapFormat::GRAY8:
- {
- return nullptr;
- }
- case ImageBitmapFormat::YUV444P:
- case ImageBitmapFormat::YUV422P:
- case ImageBitmapFormat::YUV420P:
- {
- ChannelPixelLayout* ychannel = layout->AppendElement();
- ChannelPixelLayout* uchannel = layout->AppendElement();
- ChannelPixelLayout* vchannel = layout->AppendElement();
- ychannel->mOffset = 0;
- ychannel->mWidth = aWidth;
- ychannel->mHeight = aHeight;
- ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- ychannel->mStride = aStride;
- ychannel->mSkip = 0; // aYSkip;
-
- uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
- uchannel->mWidth = aWidth / 2;
- uchannel->mHeight = aHeight / 2;
- uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- uchannel->mStride = aStride / 2;
- uchannel->mSkip = 0; // aUSkip;
-
- vchannel->mOffset = uchannel->mOffset + uchannel->mStride * uchannel->mHeight;
- vchannel->mWidth = aWidth / 2;
- vchannel->mHeight = aHeight / 2;
- vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- vchannel->mStride = aStride / 2;
- vchannel->mSkip = 0; // aVSkip;
- break;
- }
- case ImageBitmapFormat::YUV420SP_NV12:
- case ImageBitmapFormat::YUV420SP_NV21:
- case ImageBitmapFormat::HSV:
- case ImageBitmapFormat::Lab:
- case ImageBitmapFormat::DEPTH:
- default:
- return nullptr;
- }
-
- return layout;
-}
-
-/* static */ UniquePtr<ImagePixelLayout>
-ImageBitmapFormatUtils::CreateCustomizedLayout(ImageBitmapFormat aFormat,
- layers::Image* aImage)
-{
- MOZ_ASSERT(aImage, "Create layout from a null image.");
-
- // information from format
- uint8_t channelCount = GetChannelCountOfImageFormat(aFormat);
-
- UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(channelCount));
-
- // set mChannels
- switch (aFormat) {
- case ImageBitmapFormat::RGBA32:
- case ImageBitmapFormat::BGRA32:
- case ImageBitmapFormat::RGB24:
- case ImageBitmapFormat::BGR24:
- {
- layers::CairoImage* src = static_cast<layers::CairoImage*> (aImage);
- RefPtr<SourceSurface> surface = src->GetAsSourceSurface();
- RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
- gfx::DataSourceSurface::ScopedMap map(dataSurface, gfx::DataSourceSurface::READ);
- if (!map.IsMapped()) {
- return nullptr;
- }
-
- const IntSize surfaceSize = surface->GetSize();
- const uint32_t surfaceStride = map.GetStride();
-
- for (uint8_t i = 0; i < channelCount; ++i) {
- ChannelPixelLayout* channel = layout->AppendElement();
- channel->mOffset = i;
- channel->mWidth = surfaceSize.width;
- channel->mHeight = surfaceSize.height;
- channel->mDataType = ChannelPixelLayoutDataType::Uint8;
- channel->mStride = surfaceStride;
- channel->mSkip = channelCount - 1;
- }
- break;
- }
- case ImageBitmapFormat::GRAY8:
- {
- return nullptr;
- }
- case ImageBitmapFormat::YUV444P:
- case ImageBitmapFormat::YUV422P:
- case ImageBitmapFormat::YUV420P:
- case ImageBitmapFormat::YUV420SP_NV12:
- case ImageBitmapFormat::YUV420SP_NV21:
- {
- layers::PlanarYCbCrImage* ycbcrImage = static_cast<layers::PlanarYCbCrImage*> (aImage);
- layers::PlanarYCbCrData const *ycbcrLayout = ycbcrImage->GetData();
- if (!ycbcrLayout) {
- // something wrong
- return nullptr;
- }
-
- ChannelPixelLayout* ychannel = layout->AppendElement();
- ChannelPixelLayout* uchannel = layout->AppendElement();
- ChannelPixelLayout* vchannel = layout->AppendElement();
-
- ychannel->mOffset = 0;
- uchannel->mOffset = ychannel->mOffset + ycbcrLayout->mYStride * ycbcrLayout->mYSize.height;
- vchannel->mOffset = uchannel->mOffset + ycbcrLayout->mCbCrStride * ycbcrLayout->mCbCrSize.height;
- ychannel->mWidth = ycbcrLayout->mYSize.width;
- ychannel->mHeight = ycbcrLayout->mYSize.height;
- ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- ychannel->mStride = ycbcrLayout->mYStride;
- ychannel->mSkip = ycbcrLayout->mYSkip;
- uchannel->mWidth = ycbcrLayout->mCbCrSize.width;
- uchannel->mHeight = ycbcrLayout->mCbCrSize.height;
- uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- uchannel->mStride = ycbcrLayout->mCbCrStride;
- uchannel->mSkip = ycbcrLayout->mCbSkip;
- vchannel->mWidth = ycbcrLayout->mCbCrSize.width;
- vchannel->mHeight = ycbcrLayout->mCbCrSize.height;
- vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
- vchannel->mStride = ycbcrLayout->mCbCrStride;
- vchannel->mSkip = ycbcrLayout->mCrSkip;
-
- break;
- }
- case ImageBitmapFormat::HSV:
- case ImageBitmapFormat::Lab:
- case ImageBitmapFormat::DEPTH:
- default:
- return nullptr;
- }
-
- return layout;
-}
-
/*
* ImageBitmapFormatUtils_RGBA32.
*/
/* static */ImageBitmapFormatUtils_RGBA32&
ImageBitmapFormatUtils_RGBA32::GetInstance()
{
static ImageBitmapFormatUtils_RGBA32 instance;
return instance;
@@ -233,18 +332,17 @@ ImageBitmapFormatUtils_RGBA32::ConvertFr
const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
MOZ_ASSERT(channels.Length() == aSrcFormat->GetChannelCount(),
"The channel count is wrong.");
const uint32_t length = channels[0].mHeight * channels[0].mStride;
memcpy(aDstBuffer, aSrcBuffer, length);
- return CreateDefaultLayout(ImageBitmapFormat::RGBA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mStride);
}
UniquePtr<ImagePixelLayout>
ImageBitmapFormatUtils_RGBA32::ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat,
const uint8_t* aSrcBuffer,
const ImagePixelLayout* aSrcLayout,
@@ -262,18 +360,17 @@ ImageBitmapFormatUtils_RGBA32::ConvertFr
int rv = ABGRToARGB(aSrcBuffer, channels[0].mStride,
aDstBuffer, channels[0].mStride,
channels[0].mWidth, channels[0].mHeight);
if (NS_WARN_IF(rv != 0)) {
return nullptr;
}
- return CreateDefaultLayout(ImageBitmapFormat::RGBA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mStride);
}
UniquePtr<ImagePixelLayout>
ImageBitmapFormatUtils_RGBA32::ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat,
const uint8_t* aSrcBuffer,
const ImagePixelLayout* aSrcLayout,
@@ -293,34 +390,86 @@ ImageBitmapFormatUtils_RGBA32::ConvertFr
aSrcBuffer + channels[2].mOffset, channels[2].mStride,
aDstBuffer, channels[0].mWidth * 4,
channels[0].mWidth, channels[0].mHeight);
if (NS_WARN_IF(rv != 0)) {
return nullptr;
}
- return CreateDefaultLayout(ImageBitmapFormat::RGBA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mWidth * 4);
}
bool
ImageBitmapFormatUtils_RGBA32::CanConvertFrom(ImageBitmapFormat aSrcFormat)
{
if (aSrcFormat == ImageBitmapFormat::RGBA32 ||
aSrcFormat == ImageBitmapFormat::BGRA32 ||
aSrcFormat == ImageBitmapFormat::YUV420P) {
return true;
}
return false;
}
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_RGBA32::CreateDefaultLayout(uint32_t aWidth,
+ uint32_t aHeight,
+ uint32_t aStride)
+{
+ UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
+
+ // set mChannels
+ for (uint8_t i = 0; i < mChannels; ++i) {
+ ChannelPixelLayout* channel = layout->AppendElement();
+ channel->mOffset = i;
+ channel->mWidth = aWidth;
+ channel->mHeight = aHeight;
+ channel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ channel->mStride = aStride;
+ channel->mSkip = mChannels - 1;
+ }
+
+ return layout;
+}
+
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_RGBA32::CreateCustomizedLayout(layers::Image* aImage)
+{
+ MOZ_ASSERT(aImage, "Create layout from a null image.");
+
+ UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
+
+ // set mChannels
+ layers::CairoImage* src = static_cast<layers::CairoImage*> (aImage);
+ RefPtr<SourceSurface> surface = src->GetAsSourceSurface();
+ RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
+ gfx::DataSourceSurface::ScopedMap map(dataSurface, gfx::DataSourceSurface::READ);
+ if (!map.IsMapped()) {
+ return nullptr;
+ }
+
+ const IntSize surfaceSize = surface->GetSize();
+ const uint32_t surfaceStride = map.GetStride();
+
+ for (uint8_t i = 0; i < mChannels; ++i) {
+ ChannelPixelLayout* channel = layout->AppendElement();
+ channel->mOffset = i;
+ channel->mWidth = surfaceSize.width;
+ channel->mHeight = surfaceSize.height;
+ channel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ channel->mStride = surfaceStride;
+ channel->mSkip = mChannels - 1;
+ }
+
+ return layout;
+}
+
/*
* ImageBitmapFormatUtils_BGRA32.
*/
/* static */ImageBitmapFormatUtils_BGRA32&
ImageBitmapFormatUtils_BGRA32::GetInstance()
{
static ImageBitmapFormatUtils_BGRA32 instance;
return instance;
@@ -344,18 +493,17 @@ ImageBitmapFormatUtils_BGRA32::ConvertFr
int rv = ABGRToARGB(aSrcBuffer, channels[0].mStride,
aDstBuffer, channels[0].mStride,
channels[0].mWidth, channels[0].mHeight);
if (NS_WARN_IF(rv != 0)) {
return nullptr;
}
- return CreateDefaultLayout(ImageBitmapFormat::BGRA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mStride);
}
UniquePtr<ImagePixelLayout>
ImageBitmapFormatUtils_BGRA32::ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat,
const uint8_t* aSrcBuffer,
const ImagePixelLayout* aSrcLayout,
@@ -369,18 +517,17 @@ ImageBitmapFormatUtils_BGRA32::ConvertFr
const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
MOZ_ASSERT(channels.Length() == aSrcFormat->GetChannelCount(),
"The channel count is wrong.");
const uint32_t length = channels[0].mHeight * channels[0].mStride;
memcpy(aDstBuffer, aSrcBuffer, length);
- return CreateDefaultLayout(ImageBitmapFormat::BGRA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mStride);
}
UniquePtr<ImagePixelLayout>
ImageBitmapFormatUtils_BGRA32::ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat,
const uint8_t* aSrcBuffer,
const ImagePixelLayout* aSrcLayout,
@@ -400,34 +547,53 @@ ImageBitmapFormatUtils_BGRA32::ConvertFr
aSrcBuffer + channels[2].mOffset, channels[2].mStride,
aDstBuffer, channels[0].mWidth * 4,
channels[0].mWidth, channels[0].mHeight);
if (NS_WARN_IF(rv != 0)) {
return nullptr;
}
- return CreateDefaultLayout(ImageBitmapFormat::BGRA32,
- channels[0].mWidth,
+ return CreateDefaultLayout(channels[0].mWidth,
channels[0].mHeight,
channels[0].mWidth * 4);
}
bool
ImageBitmapFormatUtils_BGRA32::CanConvertFrom(ImageBitmapFormat aSrcFormat)
{
if (aSrcFormat == ImageBitmapFormat::RGBA32 ||
aSrcFormat == ImageBitmapFormat::BGRA32 ||
aSrcFormat == ImageBitmapFormat::YUV420P) {
return true;
}
return false;
}
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_BGRA32::CreateDefaultLayout(uint32_t aWidth,
+ uint32_t aHeight,
+ uint32_t aStride)
+{
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(ImageBitmapFormat::RGBA32);
+ MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+
+ return format->CreateDefaultLayout(aWidth, aHeight, aStride);
+}
+
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_BGRA32::CreateCustomizedLayout(layers::Image* aImage)
+{
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(ImageBitmapFormat::RGBA32);
+ MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+
+ return format->CreateCustomizedLayout(aImage);
+}
+
/*
* ImageBitmapFormatUtils_YUV420P.
*/
/* static */ImageBitmapFormatUtils_YUV420P&
ImageBitmapFormatUtils_YUV420P::GetInstance()
{
static ImageBitmapFormatUtils_YUV420P instance;
return instance;
@@ -467,71 +633,171 @@ ImageBitmapFormatUtils_YUV420P::CanConve
aSrcFormat == ImageBitmapFormat::BGRA32 ||
aSrcFormat == ImageBitmapFormat::YUV420P) {
return true;
}
return false;
}
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_YUV420P::CreateDefaultLayout(uint32_t aWidth,
+ uint32_t aHeight,
+ uint32_t aStride)
+{
+ UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
+
+ // set mChannels
+ ChannelPixelLayout* ychannel = layout->AppendElement();
+ ChannelPixelLayout* uchannel = layout->AppendElement();
+ ChannelPixelLayout* vchannel = layout->AppendElement();
+ ychannel->mOffset = 0;
+ ychannel->mWidth = aWidth;
+ ychannel->mHeight = aHeight;
+ ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ ychannel->mStride = aStride;
+ ychannel->mSkip = 0; // aYSkip;
+
+ uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
+ uchannel->mWidth = aWidth / 2;
+ uchannel->mHeight = aHeight / 2;
+ uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ uchannel->mStride = aStride / 2;
+ uchannel->mSkip = 0; // aUSkip;
+
+ vchannel->mOffset = uchannel->mOffset + uchannel->mStride * uchannel->mHeight;
+ vchannel->mWidth = aWidth / 2;
+ vchannel->mHeight = aHeight / 2;
+ vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ vchannel->mStride = aStride / 2;
+ vchannel->mSkip = 0; // aVSkip;
+
+ return layout;
+}
+
+UniquePtr<ImagePixelLayout>
+ImageBitmapFormatUtils_YUV420P::CreateCustomizedLayout(layers::Image* aImage)
+{
+ MOZ_ASSERT(aImage, "Create layout from a null image.");
+
+ UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
+
+ // set mChannels
+ layers::PlanarYCbCrImage* ycbcrImage = static_cast<layers::PlanarYCbCrImage*> (aImage);
+ layers::PlanarYCbCrData const *ycbcrLayout = ycbcrImage->GetData();
+ if (!ycbcrLayout) {
+ // something wrong
+ return nullptr;
+ }
+
+ ChannelPixelLayout* ychannel = layout->AppendElement();
+ ChannelPixelLayout* uchannel = layout->AppendElement();
+ ChannelPixelLayout* vchannel = layout->AppendElement();
+
+ ychannel->mOffset = 0;
+ uchannel->mOffset = ychannel->mOffset + ycbcrLayout->mYStride * ycbcrLayout->mYSize.height;
+ vchannel->mOffset = uchannel->mOffset + ycbcrLayout->mCbCrStride * ycbcrLayout->mCbCrSize.height;
+ ychannel->mWidth = ycbcrLayout->mYSize.width;
+ ychannel->mHeight = ycbcrLayout->mYSize.height;
+ ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ ychannel->mStride = ycbcrLayout->mYStride;
+ ychannel->mSkip = ycbcrLayout->mYSkip;
+ uchannel->mWidth = ycbcrLayout->mCbCrSize.width;
+ uchannel->mHeight = ycbcrLayout->mCbCrSize.height;
+ uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ uchannel->mStride = ycbcrLayout->mCbCrStride;
+ uchannel->mSkip = ycbcrLayout->mCbSkip;
+ vchannel->mWidth = ycbcrLayout->mCbCrSize.width;
+ vchannel->mHeight = ycbcrLayout->mCbCrSize.height;
+ vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
+ vchannel->mStride = ycbcrLayout->mCbCrStride;
+ vchannel->mSkip = ycbcrLayout->mCrSkip;
+
+ return layout;
+}
+
+/*
+ * Global functions.
+ */
bool
IsSupportedFormat(ImageBitmapFormat aFormat)
{
if (aFormat == ImageBitmapFormat::RGBA32 ||
aFormat == ImageBitmapFormat::BGRA32) {
return true;
}
return false;
}
+UniquePtr<ImagePixelLayout>
+CreateDefaultLayout(ImageBitmapFormat aFormat, uint32_t aWidth,
+ uint32_t aHeight, uint32_t aStride)
+{
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(aFormat);
+ MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+
+ return format->CreateDefaultLayout(aWidth, aHeight, aStride);
+}
+
+UniquePtr<ImagePixelLayout>
+CreateCustomizedLayout(ImageBitmapFormat aFormat, layers::Image* aImage)
+{
+ MOZ_ASSERT(aImage, "Create layout from a null image.");
+
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(aFormat);
+ MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+
+ return format->CreateCustomizedLayout(aImage);
+}
+
uint8_t
GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)
{
- ImageBitmapFormatUtils* format = ImageBitmapFormatUtils::GetUtils(aFormat);
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(aFormat);
MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
return format->GetChannelCount();
}
uint32_t
CalculateNeededBufferSize(ImageBitmapFormat aFormat,
uint32_t aWidth, uint32_t aHeight)
{
- ImageBitmapFormatUtils* format = ImageBitmapFormatUtils::GetUtils(aFormat);
+ UtilsUniquePtr format = ImageBitmapFormatUtils::GetUtils(aFormat);
MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
return format->NeededBufferSize(aWidth, aHeight);
}
UniquePtr<ImagePixelLayout>
CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,
const uint8_t* aSrcBuffer,
const ImagePixelLayout* aSrcLayout,
ImageBitmapFormat aDstFormat,
uint8_t* aDstBuffer)
{
MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
- ImageBitmapFormatUtils* srcFormat = ImageBitmapFormatUtils::GetUtils(aSrcFormat);
- ImageBitmapFormatUtils* dstFormat = ImageBitmapFormatUtils::GetUtils(aDstFormat);
+ UtilsUniquePtr srcFormat = ImageBitmapFormatUtils::GetUtils(aSrcFormat);
+ UtilsUniquePtr dstFormat = ImageBitmapFormatUtils::GetUtils(aDstFormat);
MOZ_ASSERT(srcFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
MOZ_ASSERT(dstFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
- return srcFormat->ConvertTo(dstFormat, aSrcBuffer, aSrcLayout, aDstBuffer);
+ return srcFormat->ConvertTo(dstFormat.get(), aSrcBuffer, aSrcLayout, aDstBuffer);
}
ImageBitmapFormat
FindBestMatchingFromat(ImageBitmapFormat aSrcFormat,
const Sequence<ImageBitmapFormat>& aCandidates) {
for(auto& candidate : aCandidates) {
- ImageBitmapFormatUtils* candidateFormat = ImageBitmapFormatUtils::GetUtils(candidate);
+ UtilsUniquePtr candidateFormat = ImageBitmapFormatUtils::GetUtils(candidate);
MOZ_ASSERT(candidateFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
if (candidateFormat->CanConvertFrom(aSrcFormat)) {
return candidate;
}
}
return ImageBitmapFormat::EndGuard_;
--- a/dom/canvas/ImageBitmapUtils.h
+++ b/dom/canvas/ImageBitmapUtils.h
@@ -9,256 +9,36 @@
#include "mozilla/UniquePtr.h"
#include "nsTArrayForwardDeclare.h"
namespace mozilla {
namespace dom {
struct ChannelPixelLayout;
-class ImageBitmapFormatUtils;
-class ImageBitmapFormatUtils_RGBA32;
-class ImageBitmapFormatUtils_BGRA32;
-class ImageBitmapFormatUtils_YUV420P;
template<typename> class Sequence;
using ImagePixelLayout = nsTArray<ChannelPixelLayout>;
/*
- * ImageBitmapFormatUtils is an abstract class which provides interfaces to
- * extract information of each ImageBitmapFormat and interfaces to convert
- * image data between different ImageBitmapFormats. For each kind of
- * ImageBitmapFromat, we derive a subclass from the ImageBitmapFormatUtils to
- * implement functionalities that are subject to the specific ImageBitmapFormat.
- *
- * ImageBitmapFormatUtils is an abstract class and its sub-classes are designed
- * as singletons. The singleton instance of sub-classes could be initialized and
- * accessed via the ImageBitmapFormatUtils::GetUtils() static method. The
- * singleton instance is a static local variable which does not need to be
- * released manually and, with the C++11 static initialization, the
- * initialization is thread-safe.
- *
- * ImageBitmapFormatUtils and its sub-classes are designed to unify operations
- * of ImageBitmap-extensions over different kinds of ImageBitmapFormats; they
- * provide following functionalities:
- *
- * (1) Create default/customized ImagePixelLayout object of each kind of
- * ImageBitmapFormat.
- * (2) Store the channel counts of each ImageBitmapFormat.
- * (3) Calculate the needed buffer size of each kind of ImageBitmapFormat with
- * given width, height and stride.
- * (4) Perform color conversion between supported ImageBitmapFormats. We use
- * _double dispatching_ to identify the source format and destination format
- * at run time. The _double dispatching_ here is mainly implemented by
- * overriding the _convertTo_ method over the ImageBitmapFormatUtils class
- * hierarchy and overloading the _convertFrom_ methods over all sub-classes
- * of ImageBitmapFormatUtils.
+ * This function creates an ImagePixelLayout object which describes the
+ * default layout of the given ImageBitmapFormat with the given width, height
+ * and stride.
*/
-
-class ImageBitmapFormatUtils
-{
-public:
- // Do not delete the returned pointer.
- static ImageBitmapFormatUtils* GetUtils(ImageBitmapFormat aFormat);
-
- // This function creates an ImagePixelLayout object which describes the
- // default layout of the given ImageBitmapFormat with the given width, height
- // and stride.
- static UniquePtr<ImagePixelLayout>
- CreateDefaultLayout(ImageBitmapFormat aFormat, uint32_t aWidth, uint32_t aHeight, uint32_t aStride);
-
- // This function extracts information from the aImage parameter to customize
- // the ImagePixelLayout object, that is, this function creates a customized
- // ImagePixelLayout object which exactly describes the pixel layout of the
- // given aImage.
- static UniquePtr<ImagePixelLayout>
- CreateCustomizedLayout(ImageBitmapFormat aFormat, layers::Image* aImage);
-
-public:
- explicit ImageBitmapFormatUtils(uint32_t aChannels)
- : mChannels(aChannels)
- {
- }
-
- virtual ~ImageBitmapFormatUtils()
- {
- }
-
- // Get the needed buffer size to store image data in the current
- // ImageBitmapFormat with the given width and height.
- // The current ImageBitmapFormat is the format used to implement the concrete
- // subclass of which the current instance is initialized.
- virtual uint32_t NeededBufferSize(uint32_t width, uint32_t height) = 0;
-
- // Convert the source image data (stored in the aSrcBuffer and described by
- // the aSrcLayout) from the current ImageBitmapFormat to the given
- // ImageBitmapFormat, aDstFormat.
- // The converted image data is stored in the aDstBuffer and described by the
- // returned ImagePixelLayout object.
- virtual UniquePtr<ImagePixelLayout>
- ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
-
- // Convert the source RGBA32 source image data (stored in the aSrcBuffer and
- // described by the aSrcLayout) to the current ImageBitmapFormat.
- // The converted image data is stored in the aDstBuffer and described by the
- // returned ImagePixelLayout object.
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
-
- // Convert the source BGRA32 source image data (stored in the aSrcBuffer and
- // described by the aSrcLayout) to the current ImageBitmapFormat.
- // The converted image data is stored in the aDstBuffer and described by the
- // returned ImagePixelLayout object.
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
-
- // Convert the source YUV420P source image data (stored in the aSrcBuffer and
- // described by the aSrcLayout) to the current ImageBitmapFormat.
- // The converted image data is stored in the aDstBuffer and described by the
- // returned ImagePixelLayout object.
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
-
- // Check whether or not the current ImageBitmapFormat can be converted from
- // the given ImageBitmapFormat.
- virtual bool
- CanConvertFrom(ImageBitmapFormat aSrcFormat) = 0;
-
- // Get the number of channels.
- uint8_t GetChannelCount() const
- {
- return mChannels;
- }
-
-protected:
- const uint8_t mChannels;
-};
+UniquePtr<ImagePixelLayout>
+CreateDefaultLayout(ImageBitmapFormat aFormat, uint32_t aWidth, uint32_t aHeight, uint32_t aStride);
-class ImageBitmapFormatUtils_RGBA32 : public ImageBitmapFormatUtils
-{
-private:
- explicit ImageBitmapFormatUtils_RGBA32()
- : ImageBitmapFormatUtils(4)
- {
- }
-
- ~ImageBitmapFormatUtils_RGBA32() = default;
- ImageBitmapFormatUtils_RGBA32(ImageBitmapFormatUtils_RGBA32 const &) = delete;
- ImageBitmapFormatUtils_RGBA32(ImageBitmapFormatUtils_RGBA32&&) = delete;
- ImageBitmapFormatUtils_RGBA32& operator=(ImageBitmapFormatUtils_RGBA32 const &) = delete;
- ImageBitmapFormatUtils_RGBA32& operator=(ImageBitmapFormatUtils_RGBA32&&) = delete;
-
-public:
- static ImageBitmapFormatUtils_RGBA32& GetInstance();
-
- virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
- {
- return aWidth * aHeight * (uint32_t)mChannels;
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
- {
- return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual bool
- CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
-};
-
-class ImageBitmapFormatUtils_BGRA32 : public ImageBitmapFormatUtils
-{
-private:
- explicit ImageBitmapFormatUtils_BGRA32()
- : ImageBitmapFormatUtils(4)
- {
- }
-
- ~ImageBitmapFormatUtils_BGRA32() = default;
- ImageBitmapFormatUtils_BGRA32(ImageBitmapFormatUtils_BGRA32 const &) = delete;
- ImageBitmapFormatUtils_BGRA32(ImageBitmapFormatUtils_BGRA32&&) = delete;
- ImageBitmapFormatUtils_BGRA32& operator=(ImageBitmapFormatUtils_BGRA32 const &) = delete;
- ImageBitmapFormatUtils_BGRA32& operator=(ImageBitmapFormatUtils_BGRA32&&) = delete;
-
-public:
- static ImageBitmapFormatUtils_BGRA32& GetInstance();
-
- virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
- {
- return aWidth * aHeight * (uint32_t)mChannels;
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
- {
- return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual bool
- CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
-};
-
-class ImageBitmapFormatUtils_YUV420P : public ImageBitmapFormatUtils
-{
-private:
- explicit ImageBitmapFormatUtils_YUV420P()
- : ImageBitmapFormatUtils(3)
- {
- }
-
- ~ImageBitmapFormatUtils_YUV420P() = default;
- ImageBitmapFormatUtils_YUV420P(ImageBitmapFormatUtils_YUV420P const &) = delete;
- ImageBitmapFormatUtils_YUV420P(ImageBitmapFormatUtils_YUV420P&&) = delete;
- ImageBitmapFormatUtils_YUV420P& operator=(ImageBitmapFormatUtils_YUV420P const &) = delete;
- ImageBitmapFormatUtils_YUV420P& operator=(ImageBitmapFormatUtils_YUV420P&&) = delete;
-
-public:
- static ImageBitmapFormatUtils_YUV420P& GetInstance();
-
- virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override
- {
- return aWidth * aHeight + 2 * (aWidth / 2) * (aHeight / 2);
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertTo(ImageBitmapFormatUtils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override
- {
- return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
- }
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual UniquePtr<ImagePixelLayout>
- ConvertFrom(ImageBitmapFormatUtils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) override;
-
- virtual bool
- CanConvertFrom(ImageBitmapFormat aSrcFormat) override;
-};
+/*
+ * This function extracts information from the aImage parameter to customize
+ * the ImagePixelLayout object, that is, this function creates a customized
+ * ImagePixelLayout object which exactly describes the pixel layout of the
+ * given aImage.
+ */
+UniquePtr<ImagePixelLayout>
+CreateCustomizedLayout(ImageBitmapFormat aFormat, layers::Image* aImage);
/*
* Check whether or not the given ImageBitmapFormat is supported.
*/
bool
IsSupportedFormat(ImageBitmapFormat aFormat);
/*