1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "ImageBitmapUtils.h"
8 #include "ImageBitmapColorUtils.h"
9 #include "ImageContainer.h"
10 #include "libyuv.h"
11 #include "mozilla/dom/ImageBitmapBinding.h"
12 #include "mozilla/Function.h"
13 #include "mozilla/gfx/2D.h"
14 
15 using namespace libyuv;
16 using namespace mozilla::gfx;
17 
18 namespace mozilla {
19 namespace dom {
20 namespace imagebitmapformat {
21 
22 class Utils;
23 class Utils_RGBA32;
24 class Utils_BGRA32;
25 class Utils_RGB24;
26 class Utils_BGR24;
27 class Utils_Gray8;
28 class Utils_YUV444P;
29 class Utils_YUV422P;
30 class Utils_YUV420P;
31 class Utils_YUV420SP_NV12;
32 class Utils_YUV420SP_NV21;
33 class Utils_HSV;
34 class Utils_Lab;
35 class Utils_Depth;
36 
GetBytesPerPixelValue(ChannelPixelLayoutDataType aDataType)37 static int GetBytesPerPixelValue(ChannelPixelLayoutDataType aDataType)
38 {
39   switch (aDataType)
40   {
41   case ChannelPixelLayoutDataType::Uint8:
42     return sizeof(uint8_t);
43   case ChannelPixelLayoutDataType::Int8:
44     return sizeof(int8_t);
45   case ChannelPixelLayoutDataType::Uint16:
46     return sizeof(uint16_t);
47   case ChannelPixelLayoutDataType::Int16:
48     return sizeof(int16_t);
49   case ChannelPixelLayoutDataType::Uint32:
50     return sizeof(uint32_t);
51   case ChannelPixelLayoutDataType::Int32:
52     return sizeof(int32_t);
53   case ChannelPixelLayoutDataType::Float32:
54     return sizeof(float);
55   case ChannelPixelLayoutDataType::Float64:
56     return sizeof(double);
57   default:
58     return 0;
59   }
60 }
61 
62 /*
63  * The UtilsUniquePtr is a UniquePtr to ImageBitmapFormatUtils with a customized
64  * deleter which does nothing. This is used as the return type of
65  * ImageBitmapFormatUtils::GetUtils to prevent users deleting the returned
66  * pointer.
67  */
operator ()mozilla::dom::imagebitmapformat::DoNotDelete68 struct DoNotDelete { void operator()(void* p) {} };
69 using UtilsUniquePtr = UniquePtr<Utils, DoNotDelete>;
70 
71 /*
72  * ImageBitmapFormatUtils is an abstract class which provides interfaces to
73  * extract information of each ImageBitmapFormat and interfaces to convert
74  * image data between different ImageBitmapFormats. For each kind of
75  * ImageBitmapFromat, we derive a subclass from the ImageBitmapFormatUtils to
76  * implement functionalities that are subject to the specific ImageBitmapFormat.
77  *
78  * ImageBitmapFormatUtils is an abstract class and its sub-classes are designed
79  * as singletons. The singleton instance of sub-classes could be initialized and
80  * accessed via the ImageBitmapFormatUtils::GetUtils() static method. The
81  * singleton instance is a static local variable which does not need to be
82  * released manually and, with the C++11 static initialization, the
83  * initialization is thread-safe.
84  *
85  * ImageBitmapFormatUtils and its sub-classes are designed to unify operations
86  * of ImageBitmap-extensions over different kinds of ImageBitmapFormats; they
87  * provide following functionalities:
88  *
89  * (1) Create default/customized ImagePixelLayout object of each kind of
90  *     ImageBitmapFormat.
91  * (2) Store the channel counts of each ImageBitmapFormat.
92  * (3) Calculate the needed buffer size of each kind of ImageBitmapFormat with
93  *     given width, height and stride.
94  * (4) Perform color conversion between supported ImageBitmapFormats. We use
95  *     _double dispatching_ to identify the source format and destination format
96  *     at run time. The _double dispatching_ here is mainly implemented by
97  *     overriding the _convertTo_ method over the ImageBitmapFormatUtils class
98  *     hierarchy and overloading the _convertFrom_ methods over all sub-classes
99  *     of ImageBitmapFormatUtils.
100  */
101 class Utils
102 {
103 public:
104   // Get the singleton utility instance of the given ImageBitmapFormat.
105   static UtilsUniquePtr GetUtils(ImageBitmapFormat aFormat);
106 
107   // Get the needed buffer size to store image data in the current
108   // ImageBitmapFormat with the given width and height.
109   // The current ImageBitmapFormat is the format used to implement the concrete
110   // subclass of which the current instance is initialized.
111   virtual uint32_t NeededBufferSize(uint32_t width, uint32_t height) = 0;
112 
113   // Creates a default ImagePixelLayout object of the current ImageBitmapFormat
114   // with the given width, height and stride.
115   virtual UniquePtr<ImagePixelLayout>
116   CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride) = 0;
117 
118   // Convert the source image data (stored in the aSrcBuffer and described by
119   // the aSrcLayout) from the current ImageBitmapFormat to the given
120   // ImageBitmapFormat, aDstFormat.
121   // The converted image data is stored in the aDstBuffer and described by the
122   // returned ImagePixelLayout object.
123   virtual UniquePtr<ImagePixelLayout>
124   ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
125 
126   // ConvertFrom():
127   // Convert the source image data (which is in the aSrcFormat format, the pixel
128   // layout is described by the aSrcLayout and the raw data is stored in the
129   // aSrcBuffer) to the current ImageBitmapFormat.
130   // The converted image data is stored in the aDstBuffer and described by the
131   // returned ImagePixelLayout object.
132   virtual UniquePtr<ImagePixelLayout>
133   ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
134 
135   virtual UniquePtr<ImagePixelLayout>
136   ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
137 
138   virtual UniquePtr<ImagePixelLayout>
139   ConvertFrom(Utils_RGB24* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
140 
141   virtual UniquePtr<ImagePixelLayout>
142   ConvertFrom(Utils_BGR24* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
143 
144   virtual UniquePtr<ImagePixelLayout>
145   ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
146 
147   virtual UniquePtr<ImagePixelLayout>
148   ConvertFrom(Utils_YUV444P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
149 
150   virtual UniquePtr<ImagePixelLayout>
151   ConvertFrom(Utils_YUV422P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
152 
153   virtual UniquePtr<ImagePixelLayout>
154   ConvertFrom(Utils_YUV420P* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
155 
156   virtual UniquePtr<ImagePixelLayout>
157   ConvertFrom(Utils_YUV420SP_NV12* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
158 
159   virtual UniquePtr<ImagePixelLayout>
160   ConvertFrom(Utils_YUV420SP_NV21* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
161 
162   virtual UniquePtr<ImagePixelLayout>
163   ConvertFrom(Utils_HSV* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
164 
165   virtual UniquePtr<ImagePixelLayout>
166   ConvertFrom(Utils_Lab* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
167 
168   virtual UniquePtr<ImagePixelLayout>
169   ConvertFrom(Utils_Depth* aSrcFormat, const uint8_t* aSrcBuffer, const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer) = 0;
170 
171   // Check whether or not the current ImageBitmapFormat can be converted from
172   // the given ImageBitmapFormat.
173   virtual bool
174   CanConvertFrom(ImageBitmapFormat aSrcFormat) = 0;
175 
176   // Get the number of channels.
GetChannelCount() const177   uint8_t GetChannelCount() const
178   {
179     return mChannels;
180   }
181 
182 protected:
Utils(uint32_t aChannels,ChannelPixelLayoutDataType aDataType)183   Utils(uint32_t aChannels,
184                          ChannelPixelLayoutDataType aDataType)
185   : mChannels(aChannels)
186   , mBytesPerPixelValue(GetBytesPerPixelValue(aDataType))
187   , mDataType(aDataType)
188   {
189   }
190 
~Utils()191   virtual ~Utils()
192   {
193   }
194 
195   const uint8_t mChannels;
196   const int mBytesPerPixelValue;
197   const ChannelPixelLayoutDataType mDataType;
198 };
199 
200 #define DECLARE_Utils(NAME)                          \
201 class Utils_ ## NAME : public Utils \
202 {                                                                     \
203 private:                                                              \
204   explicit Utils_ ## NAME ();                        \
205   ~Utils_ ## NAME () = default;                      \
206   Utils_ ## NAME (Utils_ ## NAME const &) = delete;             \
207   Utils_ ## NAME (Utils_ ## NAME &&) = delete;                  \
208   Utils_ ## NAME & operator=(Utils_ ## NAME const &) = delete;  \
209   Utils_ ## NAME & operator=(Utils_ ## NAME &&) = delete;       \
210                                                                                                   \
211 public:                                                     \
212   static Utils_ ## NAME & GetInstance();   \
213                                                             \
214   virtual uint32_t NeededBufferSize(uint32_t aWidth, uint32_t aHeight) override;  \
215                                                                                   \
216   virtual UniquePtr<ImagePixelLayout>                          \
217   CreateDefaultLayout(uint32_t, uint32_t, uint32_t) override;  \
218                                                                \
219   virtual UniquePtr<ImagePixelLayout>                                                             \
220   ConvertTo(Utils*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
221                                                                                                   \
222   virtual UniquePtr<ImagePixelLayout>                                                                       \
223   ConvertFrom(Utils_RGBA32*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override;  \
224                                                                                                             \
225   virtual UniquePtr<ImagePixelLayout>                                                                       \
226   ConvertFrom(Utils_BGRA32*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override;  \
227                                                                                                             \
228   virtual UniquePtr<ImagePixelLayout>                                                                     \
229   ConvertFrom(Utils_RGB24*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
230                                                                                                           \
231   virtual UniquePtr<ImagePixelLayout>                                                                     \
232   ConvertFrom(Utils_BGR24*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
233                                                                                                           \
234   virtual UniquePtr<ImagePixelLayout>                                                                     \
235   ConvertFrom(Utils_Gray8*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
236                                                                                                           \
237   virtual UniquePtr<ImagePixelLayout>                                                                       \
238   ConvertFrom(Utils_YUV444P*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
239                                                                                                             \
240   virtual UniquePtr<ImagePixelLayout>                                                                       \
241   ConvertFrom(Utils_YUV422P*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
242                                                                                                             \
243   virtual UniquePtr<ImagePixelLayout>                                                                       \
244   ConvertFrom(Utils_YUV420P*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
245                                                                                                             \
246   virtual UniquePtr<ImagePixelLayout>                                                                             \
247   ConvertFrom(Utils_YUV420SP_NV12*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
248                                                                                                                   \
249   virtual UniquePtr<ImagePixelLayout>                                                                             \
250   ConvertFrom(Utils_YUV420SP_NV21*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
251                                                                                                                   \
252   virtual UniquePtr<ImagePixelLayout>                                                                   \
253   ConvertFrom(Utils_HSV*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
254                                                                                                         \
255   virtual UniquePtr<ImagePixelLayout>                                                                   \
256   ConvertFrom(Utils_Lab*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
257                                                                                                         \
258   virtual UniquePtr<ImagePixelLayout>                                                                     \
259   ConvertFrom(Utils_Depth*, const uint8_t*, const ImagePixelLayout*, uint8_t*) override; \
260                                                                                                           \
261   virtual bool                                  \
262   CanConvertFrom(ImageBitmapFormat) override;   \
263 };
264 
265 DECLARE_Utils(RGBA32)
DECLARE_Utils(BGRA32)266 DECLARE_Utils(BGRA32)
267 DECLARE_Utils(RGB24)
268 DECLARE_Utils(BGR24)
269 DECLARE_Utils(Gray8)
270 DECLARE_Utils(YUV444P)
271 DECLARE_Utils(YUV422P)
272 DECLARE_Utils(YUV420P)
273 DECLARE_Utils(YUV420SP_NV12)
274 DECLARE_Utils(YUV420SP_NV21)
275 DECLARE_Utils(HSV)
276 DECLARE_Utils(Lab)
277 DECLARE_Utils(Depth)
278 
279 #undef DECLARE_Utils
280 
281 /*
282  * ImageBitmapFormatUtils.
283  */
284 /* static */ UtilsUniquePtr
285 Utils::GetUtils(ImageBitmapFormat aFormat)
286 {
287   switch(aFormat)
288   {
289   case ImageBitmapFormat::RGBA32:
290     return UtilsUniquePtr(&Utils_RGBA32::GetInstance());
291   case ImageBitmapFormat::BGRA32:
292     return UtilsUniquePtr(&Utils_BGRA32::GetInstance());
293   case ImageBitmapFormat::RGB24:
294     return UtilsUniquePtr(&Utils_RGB24::GetInstance());
295   case ImageBitmapFormat::BGR24:
296     return UtilsUniquePtr(&Utils_BGR24::GetInstance());
297   case ImageBitmapFormat::GRAY8:
298     return UtilsUniquePtr(&Utils_Gray8::GetInstance());
299   case ImageBitmapFormat::YUV444P:
300     return UtilsUniquePtr(&Utils_YUV444P::GetInstance());
301   case ImageBitmapFormat::YUV422P:
302     return UtilsUniquePtr(&Utils_YUV422P::GetInstance());
303   case ImageBitmapFormat::YUV420P:
304     return UtilsUniquePtr(&Utils_YUV420P::GetInstance());
305   case ImageBitmapFormat::YUV420SP_NV12:
306     return UtilsUniquePtr(&Utils_YUV420SP_NV12::GetInstance());
307   case ImageBitmapFormat::YUV420SP_NV21:
308     return UtilsUniquePtr(&Utils_YUV420SP_NV21::GetInstance());
309   case ImageBitmapFormat::HSV:
310     return UtilsUniquePtr(&Utils_HSV::GetInstance());
311   case ImageBitmapFormat::Lab:
312     return UtilsUniquePtr(&Utils_Lab::GetInstance());
313   case ImageBitmapFormat::DEPTH:
314     return UtilsUniquePtr(&Utils_Depth::GetInstance());
315   default:
316     return nullptr;
317   }
318 }
319 
320 /*
321  * Helper functions.
322  */
323 template<typename SrcType, typename DstType>
324 static UniquePtr<ImagePixelLayout>
CvtSimpleImgToSimpleImg(Utils * aSrcUtils,const SrcType * aSrcBuffer,const ImagePixelLayout * aSrcLayout,DstType * aDstBuffer,ImageBitmapFormat aDstFormat,int aDstChannelCount,mozilla::function<int (const SrcType *,int,DstType *,int,int,int)> converter)325 CvtSimpleImgToSimpleImg(Utils* aSrcUtils, const SrcType* aSrcBuffer,
326                         const ImagePixelLayout* aSrcLayout, DstType* aDstBuffer,
327                         ImageBitmapFormat aDstFormat, int aDstChannelCount,
328                         mozilla::function<int (const SrcType*, int, DstType*, int, int, int)> converter)
329 {
330   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
331   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
332   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
333   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
334 
335   const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
336   MOZ_ASSERT(channels.Length() == aSrcUtils->GetChannelCount(),
337              "The channel count is wrong.");
338 
339   const int dstStride = channels[0].mWidth * aDstChannelCount * sizeof(DstType);
340   int rv = converter(aSrcBuffer, channels[0].mStride,
341                      aDstBuffer, dstStride,
342                      channels[0].mWidth, channels[0].mHeight);
343 
344   if (NS_WARN_IF(rv != 0)) {
345     return nullptr;
346   }
347 
348   return CreateDefaultPixelLayout(aDstFormat, channels[0].mWidth,
349                                   channels[0].mHeight, dstStride);
350 }
351 
352 static UniquePtr<ImagePixelLayout>
CvtYUVImgToSimpleImg(Utils * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aDstFormat,int aDstChannelCount,mozilla::function<int (const uint8_t *,int,const uint8_t *,int,const uint8_t *,int,uint8_t *,int,int,int)> converter)353 CvtYUVImgToSimpleImg(Utils* aSrcUtils, const uint8_t* aSrcBuffer,
354                      const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
355                      ImageBitmapFormat aDstFormat, int aDstChannelCount,
356                      mozilla::function<int (const uint8_t*, int, const uint8_t*, int, const uint8_t*, int, uint8_t*, int, int, int)> converter)
357 {
358   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
359   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
360   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
361   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
362 
363   const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
364   MOZ_ASSERT(channels.Length() == aSrcUtils->GetChannelCount(),
365              "The channel count is wrong.");
366 
367   const int dstStride = channels[0].mWidth * aDstChannelCount * sizeof(uint8_t);
368   int rv = converter(aSrcBuffer + channels[0].mOffset, channels[0].mStride,
369                      aSrcBuffer + channels[1].mOffset, channels[1].mStride,
370                      aSrcBuffer + channels[2].mOffset, channels[2].mStride,
371                      aDstBuffer, dstStride,
372                      channels[0].mWidth, channels[0].mHeight);
373 
374   if (NS_WARN_IF(rv != 0)) {
375     return nullptr;
376   }
377 
378   return CreateDefaultPixelLayout(aDstFormat, channels[0].mWidth,
379                                   channels[0].mHeight, dstStride);
380 }
381 
382 static UniquePtr<ImagePixelLayout>
CvtNVImgToSimpleImg(Utils * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aDstFormat,int aDstChannelCount,mozilla::function<int (const uint8_t *,int,const uint8_t *,int,uint8_t *,int,int,int)> converter)383 CvtNVImgToSimpleImg(Utils* aSrcUtils, const uint8_t* aSrcBuffer,
384                     const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
385                     ImageBitmapFormat aDstFormat, int aDstChannelCount,
386                     mozilla::function<int (const uint8_t*, int, const uint8_t*, int, uint8_t*, int, int, int)> converter)
387 {
388   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
389   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
390   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
391   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
392 
393   const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
394   MOZ_ASSERT(channels.Length() == aSrcUtils->GetChannelCount(),
395              "The channel count is wrong.");
396 
397   const int dstStride = channels[0].mWidth * aDstChannelCount * sizeof(uint8_t);
398   int rv = converter(aSrcBuffer + channels[0].mOffset, channels[0].mStride,
399                      aSrcBuffer + channels[1].mOffset, channels[1].mStride,
400                      aDstBuffer, dstStride,
401                      channels[0].mWidth, channels[0].mHeight);
402 
403   if (NS_WARN_IF(rv != 0)) {
404     return nullptr;
405   }
406 
407   return CreateDefaultPixelLayout(aDstFormat, channels[0].mWidth,
408                                   channels[0].mHeight, dstStride);
409 }
410 
411 static UniquePtr<ImagePixelLayout>
CvtSimpleImgToYUVImg(Utils * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aDstFormat,mozilla::function<int (const uint8_t *,int,uint8_t *,int,uint8_t *,int,uint8_t *,int,int,int)> converter)412 CvtSimpleImgToYUVImg(Utils* aSrcUtils, const uint8_t* aSrcBuffer,
413                      const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
414                      ImageBitmapFormat aDstFormat,
415                      mozilla::function<int (const uint8_t*, int, uint8_t*, int, uint8_t*, int, uint8_t*, int, int, int)> converter)
416 {
417   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
418   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
419   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
420   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
421 
422   UniquePtr<ImagePixelLayout> layout =
423     CreateDefaultPixelLayout(aDstFormat, (*aSrcLayout)[0].mWidth,
424                              (*aSrcLayout)[0].mHeight, (*aSrcLayout)[0].mWidth);
425 
426   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout.");
427 
428   const nsTArray<ChannelPixelLayout>& channels = *layout;
429 
430   int rv = converter(aSrcBuffer, (*aSrcLayout)[0].mStride,
431                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
432                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
433                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
434                      channels[0].mWidth, channels[0].mHeight);
435 
436   if (NS_WARN_IF(rv != 0)) {
437     return nullptr;
438   }
439 
440   return layout;
441 }
442 
443 static UniquePtr<ImagePixelLayout>
CvtSimpleImgToNVImg(Utils * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aDstFormat,mozilla::function<int (const uint8_t *,int,uint8_t *,int,uint8_t *,int,int,int)> converter)444 CvtSimpleImgToNVImg(Utils* aSrcUtils, const uint8_t* aSrcBuffer,
445                     const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
446                     ImageBitmapFormat aDstFormat,
447                     mozilla::function<int (const uint8_t*, int, uint8_t*, int, uint8_t*, int, int, int)> converter)
448 {
449   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
450   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
451   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
452   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
453 
454   UniquePtr<ImagePixelLayout> layout =
455     CreateDefaultPixelLayout(aDstFormat, (*aSrcLayout)[0].mWidth,
456                              (*aSrcLayout)[0].mHeight, (*aSrcLayout)[0].mWidth);
457 
458   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout.");
459 
460   const nsTArray<ChannelPixelLayout>& channels = *layout;
461 
462   int rv = converter(aSrcBuffer, (*aSrcLayout)[0].mStride,
463                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
464                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
465                      channels[0].mWidth, channels[0].mHeight);
466 
467   if (NS_WARN_IF(rv != 0)) {
468     return nullptr;
469   }
470 
471   return layout;
472 }
473 
474 template<class SrcUtilsType, class DstUtilsType>
475 static UniquePtr<ImagePixelLayout>
TwoPassConversion(SrcUtilsType * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aMiddleFormat,DstUtilsType * aDstUtils)476 TwoPassConversion(SrcUtilsType* aSrcUtils, const uint8_t* aSrcBuffer,
477                   const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
478                   ImageBitmapFormat aMiddleFormat, DstUtilsType* aDstUtils)
479 {
480   MOZ_ASSERT(aSrcUtils, "Convert color from a null source utility.");
481   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
482   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
483   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
484 
485   // I444 -> I420 -> I422
486   UtilsUniquePtr yuv420PUtils = Utils::GetUtils(aMiddleFormat);
487   UniquePtr<uint8_t> yuv420PBuffer(new uint8_t[yuv420PUtils->NeededBufferSize((*aSrcLayout)[0].mWidth, (*aSrcLayout)[0].mHeight)]);
488   UniquePtr<ImagePixelLayout> yuv420PLayout = yuv420PUtils->ConvertFrom(aSrcUtils, aSrcBuffer, aSrcLayout, yuv420PBuffer.get());
489   return yuv420PUtils->ConvertTo(aDstUtils, yuv420PBuffer.get(), yuv420PLayout.get(), aDstBuffer);
490 }
491 
492 static UniquePtr<ImagePixelLayout>
PureCopy(Utils * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer,ImageBitmapFormat aDstFormat)493 PureCopy(Utils* aSrcUtils, const uint8_t* aSrcBuffer,
494          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer,
495          ImageBitmapFormat aDstFormat)
496 {
497   MOZ_ASSERT(aSrcUtils, "Convert color from a null utility object.");
498   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
499   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
500   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
501 
502   const nsTArray<ChannelPixelLayout>& channels = *aSrcLayout;
503   MOZ_ASSERT(channels.Length() == aSrcUtils->GetChannelCount(),
504              "The channel count is wrong.");
505 
506 
507   uint32_t length = 0;
508 
509   if (aDstFormat == ImageBitmapFormat::RGBA32 ||
510       aDstFormat == ImageBitmapFormat::BGRA32 ||
511       aDstFormat == ImageBitmapFormat::RGB24 ||
512       aDstFormat == ImageBitmapFormat::BGR24 ||
513       aDstFormat == ImageBitmapFormat::GRAY8 ||
514       aDstFormat == ImageBitmapFormat::HSV ||
515       aDstFormat == ImageBitmapFormat::Lab ||
516       aDstFormat == ImageBitmapFormat::DEPTH) {
517     length = channels[0].mHeight * channels[0].mStride;
518   } else if (aDstFormat == ImageBitmapFormat::YUV444P ||
519              aDstFormat == ImageBitmapFormat::YUV422P ||
520              aDstFormat == ImageBitmapFormat::YUV420P) {
521     length = channels[0].mHeight * channels[0].mStride +
522              channels[1].mHeight * channels[1].mStride +
523              channels[2].mHeight * channels[2].mStride;
524   } else if (aDstFormat == ImageBitmapFormat::YUV420SP_NV12 ||
525              aDstFormat == ImageBitmapFormat::YUV420SP_NV21) {
526     length = channels[0].mHeight * channels[0].mStride +
527              channels[1].mHeight * channels[1].mStride;
528   }
529 
530   memcpy(aDstBuffer, aSrcBuffer, length);
531 
532   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(*aSrcLayout));
533   return layout;
534 }
535 
536 UniquePtr<ImagePixelLayout>
CreateDefaultLayoutForSimpleImage(uint32_t aWidth,uint32_t aHeight,uint32_t aStride,int aChannels,int aBytesPerPixelValue,ChannelPixelLayoutDataType aDataType)537 CreateDefaultLayoutForSimpleImage(uint32_t aWidth, uint32_t aHeight,
538                                   uint32_t aStride, int aChannels,
539                                   int aBytesPerPixelValue,
540                                   ChannelPixelLayoutDataType aDataType)
541 {
542   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(aChannels));
543 
544   // set mChannels
545   for (uint8_t i = 0; i < aChannels; ++i) {
546     ChannelPixelLayout* channel = layout->AppendElement();
547     channel->mOffset = i * aBytesPerPixelValue;
548     channel->mWidth = aWidth;
549     channel->mHeight = aHeight;
550     channel->mDataType = aDataType; //ChannelPixelLayoutDataType::Uint8;
551     channel->mStride = aStride;
552     channel->mSkip = aChannels - 1;
553   }
554 
555   return layout;
556 }
557 
558 /*
559  * Utils_RGBA32.
560  */
561 /* static */Utils_RGBA32&
GetInstance()562 Utils_RGBA32::GetInstance()
563 {
564   static Utils_RGBA32 instance;
565   return instance;
566 }
567 
Utils_RGBA32()568 Utils_RGBA32::Utils_RGBA32()
569 : Utils(4, ChannelPixelLayoutDataType::Uint8)
570 {
571 }
572 
573 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)574 Utils_RGBA32::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
575 {
576   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
577 }
578 
579 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)580 Utils_RGBA32::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
581                         const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
582 {
583   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
584 }
585 
586 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)587 Utils_RGBA32::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
588                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
589 {
590   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32);
591 }
592 
593 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)594 Utils_RGBA32::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
595                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
596 {
597   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &libyuv::ABGRToARGB);
598 }
599 
600 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)601 Utils_RGBA32::ConvertFrom(Utils_RGB24* aSrcFormat, const uint8_t* aSrcBuffer,
602                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
603 {
604   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &RGB24ToRGBA32);
605 }
606 
607 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)608 Utils_RGBA32::ConvertFrom(Utils_BGR24* aSrcFormat, const uint8_t* aSrcBuffer,
609                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
610 {
611   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &BGR24ToRGBA32);
612 }
613 
614 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)615 Utils_RGBA32::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
616                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
617 {
618   return nullptr;
619 }
620 
621 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)622 Utils_RGBA32::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
623                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
624 {
625   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &YUV444PToRGBA32);
626 }
627 
628 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)629 Utils_RGBA32::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
630                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
631 {
632   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &YUV422PToRGBA32);
633 }
634 
635 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)636 Utils_RGBA32::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
637                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
638 {
639   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &libyuv::I420ToABGR);
640 }
641 
642 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)643 Utils_RGBA32::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
644                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
645 {
646   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &NV12ToRGBA32);
647 }
648 
649 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)650 Utils_RGBA32::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
651                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
652 {
653   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &NV21ToRGBA32);
654 }
655 
656 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)657 Utils_RGBA32::ConvertFrom(Utils_HSV* aSrcFormat, const uint8_t* aSrcBuffer,
658                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
659 {
660   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &HSVToRGBA32);
661 }
662 
663 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)664 Utils_RGBA32::ConvertFrom(Utils_Lab* aSrcFormat, const uint8_t* aSrcBuffer,
665                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
666 {
667   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGBA32, 4, &LabToRGBA32);
668 }
669 
670 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)671 Utils_RGBA32::ConvertFrom(Utils_Depth* aSrcFormat, const uint8_t* aSrcBuffer,
672                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
673 {
674   return nullptr;
675 }
676 
677 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)678 Utils_RGBA32::CanConvertFrom(ImageBitmapFormat aSrcFormat)
679 {
680   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
681       aSrcFormat == ImageBitmapFormat::DEPTH) {
682     return false;
683   }
684 
685   return true;
686 }
687 
688 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)689 Utils_RGBA32::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
690 {
691   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
692 }
693 
694 /*
695  * Utils_BGRA32.
696  */
697 /* static */Utils_BGRA32&
GetInstance()698 Utils_BGRA32::GetInstance()
699 {
700   static Utils_BGRA32 instance;
701   return instance;
702 }
703 
Utils_BGRA32()704 Utils_BGRA32::Utils_BGRA32()
705 : Utils(4, ChannelPixelLayoutDataType::Uint8)
706 {
707 }
708 
709 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)710 Utils_BGRA32::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
711 {
712   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
713 }
714 
715 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)716 Utils_BGRA32::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
717                         const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
718 {
719   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
720 }
721 
722 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)723 Utils_BGRA32::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
724                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
725 {
726   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &libyuv::ABGRToARGB);
727 }
728 
729 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)730 Utils_BGRA32::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
731                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
732 {
733   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32);
734 }
735 
736 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)737 Utils_BGRA32::ConvertFrom(Utils_RGB24* aSrcFormat, const uint8_t* aSrcBuffer,
738                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
739 {
740   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &RGB24ToBGRA32);
741 }
742 
743 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)744 Utils_BGRA32::ConvertFrom(Utils_BGR24* aSrcFormat, const uint8_t* aSrcBuffer,
745                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
746 {
747   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &BGR24ToBGRA32);
748 }
749 
750 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)751 Utils_BGRA32::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
752                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
753 {
754   return nullptr;
755 }
756 
757 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)758 Utils_BGRA32::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
759                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
760 {
761   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &YUV444PToBGRA32);
762 }
763 
764 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)765 Utils_BGRA32::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
766                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
767 {
768   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &libyuv::I422ToARGB);
769 }
770 
771 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)772 Utils_BGRA32::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
773                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
774 {
775   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &libyuv::I420ToARGB);
776 }
777 
778 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)779 Utils_BGRA32::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
780                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
781 {
782   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &libyuv::NV12ToARGB);
783 }
784 
785 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)786 Utils_BGRA32::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
787                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
788 {
789   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &libyuv::NV21ToARGB);
790 }
791 
792 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)793 Utils_BGRA32::ConvertFrom(Utils_HSV* aSrcFormat, const uint8_t* aSrcBuffer,
794                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
795 {
796   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &HSVToBGRA32);
797 }
798 
799 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)800 Utils_BGRA32::ConvertFrom(Utils_Lab* aSrcFormat, const uint8_t* aSrcBuffer,
801                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
802 {
803   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGRA32, 4, &LabToBGRA32);
804 }
805 
806 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)807 Utils_BGRA32::ConvertFrom(Utils_Depth* aSrcFormat, const uint8_t* aSrcBuffer,
808                           const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
809 {
810   return nullptr;
811 }
812 
813 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)814 Utils_BGRA32::CanConvertFrom(ImageBitmapFormat aSrcFormat)
815 {
816   if (aSrcFormat == ImageBitmapFormat::RGBA32 ||
817       aSrcFormat == ImageBitmapFormat::BGRA32 ||
818       aSrcFormat == ImageBitmapFormat::YUV420P) {
819     return true;
820   }
821 
822   return false;
823 }
824 
825 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)826 Utils_BGRA32::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
827 {
828   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
829 }
830 
831 /*
832  * Utils_RGB24.
833  */
834 /* static */Utils_RGB24&
GetInstance()835 Utils_RGB24::GetInstance()
836 {
837   static Utils_RGB24 instance;
838   return instance;
839 }
840 
Utils_RGB24()841 Utils_RGB24::Utils_RGB24()
842 : Utils(3, ChannelPixelLayoutDataType::Uint8)
843 {
844 }
845 
846 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)847 Utils_RGB24::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
848 {
849   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
850 }
851 
852 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)853 Utils_RGB24::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
854                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
855 {
856   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
857 }
858 
859 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)860 Utils_RGB24::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
861                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
862 {
863   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &RGBA32ToRGB24);
864 }
865 
866 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)867 Utils_RGB24::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
868                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
869 {
870   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &BGRA32ToRGB24);
871 }
872 
873 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)874 Utils_RGB24::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
875                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
876 {
877   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24);
878 }
879 
880 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)881 Utils_RGB24::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
882                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
883 {
884   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &BGR24ToRGB24);
885 }
886 
887 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)888 Utils_RGB24::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
889                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
890 {
891   return nullptr;
892 }
893 
894 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)895 Utils_RGB24::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
896                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
897 {
898   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &YUV444PToRGB24);
899 }
900 
901 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)902 Utils_RGB24::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
903                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
904 {
905   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &YUV422PToRGB24);
906 }
907 
908 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)909 Utils_RGB24::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
910                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
911 {
912   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &YUV420PToRGB24);
913 }
914 
915 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)916 Utils_RGB24::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
917                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
918 {
919   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &NV12ToRGB24);
920 }
921 
922 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)923 Utils_RGB24::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
924                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
925 {
926   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &NV21ToRGB24);
927 }
928 
929 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)930 Utils_RGB24::ConvertFrom(Utils_HSV* aSrcFormat, const uint8_t* aSrcBuffer,
931                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
932 {
933   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &HSVToRGB24);
934 }
935 
936 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)937 Utils_RGB24::ConvertFrom(Utils_Lab* aSrcFormat, const uint8_t* aSrcBuffer,
938                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
939 {
940   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, 3, &LabToRGB24);
941 }
942 
943 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)944 Utils_RGB24::ConvertFrom(Utils_Depth* aSrcFormat, const uint8_t* aSrcBuffer,
945                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
946 {
947   return nullptr;
948 }
949 
950 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)951 Utils_RGB24::CanConvertFrom(ImageBitmapFormat aSrcFormat)
952 {
953   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
954       aSrcFormat == ImageBitmapFormat::DEPTH) {
955     return false;
956   }
957 
958   return true;
959 }
960 
961 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)962 Utils_RGB24::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
963 {
964   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
965 }
966 
967 /*
968  * Utils_BGR24.
969  */
970 /* static */Utils_BGR24&
GetInstance()971 Utils_BGR24::GetInstance()
972 {
973   static Utils_BGR24 instance;
974   return instance;
975 }
976 
Utils_BGR24()977 Utils_BGR24::Utils_BGR24()
978 : Utils(3, ChannelPixelLayoutDataType::Uint8)
979 {
980 }
981 
982 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)983 Utils_BGR24::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
984 {
985   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
986 }
987 
988 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)989 Utils_BGR24::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
990                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
991 {
992   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
993 }
994 
995 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)996 Utils_BGR24::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
997                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
998 {
999   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &RGBA32ToBGR24);
1000 }
1001 
1002 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1003 Utils_BGR24::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
1004                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1005 {
1006   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &BGRA32ToBGR24);
1007 }
1008 
1009 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1010 Utils_BGR24::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1011                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1012 {
1013   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &RGB24ToBGR24);
1014 }
1015 
1016 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1017 Utils_BGR24::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1018                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1019 {
1020   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24);
1021 }
1022 
1023 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1024 Utils_BGR24::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
1025                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1026 {
1027   return nullptr;
1028 }
1029 
1030 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1031 Utils_BGR24::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
1032                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1033 {
1034   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &YUV444PToBGR24);
1035 }
1036 
1037 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1038 Utils_BGR24::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
1039                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1040 {
1041   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &YUV422PToBGR24);
1042 }
1043 
1044 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1045 Utils_BGR24::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
1046                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1047 {
1048   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &YUV420PToBGR24);
1049 }
1050 
1051 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1052 Utils_BGR24::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
1053                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1054 {
1055   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &NV12ToBGR24);
1056 }
1057 
1058 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1059 Utils_BGR24::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
1060                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1061 {
1062   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &NV21ToBGR24);
1063 }
1064 
1065 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1066 Utils_BGR24::ConvertFrom(Utils_HSV* aSrcFormat, const uint8_t* aSrcBuffer,
1067                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1068 {
1069   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &HSVToBGR24);
1070 }
1071 
1072 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1073 Utils_BGR24::ConvertFrom(Utils_Lab* aSrcFormat, const uint8_t* aSrcBuffer,
1074                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1075 {
1076   return CvtSimpleImgToSimpleImg<float, uint8_t>(aSrcFormat, (const float*)aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::BGR24, 3, &LabToBGR24);
1077 }
1078 
1079 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1080 Utils_BGR24::ConvertFrom(Utils_Depth* aSrcFormat, const uint8_t* aSrcBuffer,
1081                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1082 {
1083   return nullptr;
1084 }
1085 
1086 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)1087 Utils_BGR24::CanConvertFrom(ImageBitmapFormat aSrcFormat)
1088 {
1089   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
1090       aSrcFormat == ImageBitmapFormat::DEPTH) {
1091     return false;
1092   }
1093 
1094   return true;
1095 }
1096 
1097 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)1098 Utils_BGR24::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
1099 {
1100   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
1101 }
1102 
1103 /*
1104  * Utils_Gray8.
1105  */
1106 /* static */Utils_Gray8&
GetInstance()1107 Utils_Gray8::GetInstance()
1108 {
1109   static Utils_Gray8 instance;
1110   return instance;
1111 }
1112 
Utils_Gray8()1113 Utils_Gray8::Utils_Gray8()
1114 : Utils(1, ChannelPixelLayoutDataType::Uint8)
1115 {
1116 }
1117 
1118 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)1119 Utils_Gray8::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
1120 {
1121   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
1122 }
1123 
1124 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1125 Utils_Gray8::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
1126                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1127 {
1128   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
1129 }
1130 
1131 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1132 Utils_Gray8::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
1133                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1134 {
1135   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &RGBA32ToGray8);
1136 }
1137 
1138 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1139 Utils_Gray8::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
1140                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1141 {
1142   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcFormat, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &BGRA32ToGray8);
1143 }
1144 
1145 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1146 Utils_Gray8::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1147                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1148 {
1149   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &RGB24ToGray8);
1150 }
1151 
1152 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1153 Utils_Gray8::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1154                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1155 {
1156   return CvtSimpleImgToSimpleImg<uint8_t, uint8_t>(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &BGR24ToGray8);
1157 }
1158 
1159 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1160 Utils_Gray8::ConvertFrom(Utils_Gray8* aSrcUtils, const uint8_t* aSrcBuffer,
1161                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1162 {
1163   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8);
1164 }
1165 
1166 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1167 Utils_Gray8::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
1168                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1169 {
1170   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &YUV444PToGray8);
1171 }
1172 
1173 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1174 Utils_Gray8::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
1175                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1176 {
1177   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &YUV422PToGray8);
1178 }
1179 
1180 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1181 Utils_Gray8::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
1182                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1183 {
1184   return CvtYUVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &YUV420PToGray8);
1185 }
1186 
1187 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1188 Utils_Gray8::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
1189                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1190 {
1191   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &NV12ToGray8);
1192 }
1193 
1194 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1195 Utils_Gray8::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
1196                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1197 {
1198   return CvtNVImgToSimpleImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::GRAY8, 1, &NV21ToGray8);
1199 }
1200 
1201 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1202 Utils_Gray8::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
1203                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1204 {
1205   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1206 }
1207 
1208 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1209 Utils_Gray8::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
1210                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1211 {
1212   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1213 }
1214 
1215 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1216 Utils_Gray8::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
1217                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1218 {
1219   return nullptr;
1220 }
1221 
1222 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)1223 Utils_Gray8::CanConvertFrom(ImageBitmapFormat aSrcFormat)
1224 {
1225   if (aSrcFormat == ImageBitmapFormat::DEPTH) {
1226     return false;
1227   }
1228 
1229   return true;
1230 }
1231 
1232 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)1233 Utils_Gray8::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
1234 {
1235   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
1236 }
1237 
1238 /*
1239  * class Utils_YUV444P.
1240  */
1241 /* static */Utils_YUV444P&
GetInstance()1242 Utils_YUV444P::GetInstance()
1243 {
1244   static Utils_YUV444P instance;
1245   return instance;
1246 }
1247 
Utils_YUV444P()1248 Utils_YUV444P::Utils_YUV444P()
1249 : Utils(3, ChannelPixelLayoutDataType::Uint8)
1250 {
1251 }
1252 
1253 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)1254 Utils_YUV444P::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
1255 {
1256   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
1257 }
1258 
1259 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1260 Utils_YUV444P::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
1261                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1262 {
1263   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
1264 }
1265 
1266 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1267 Utils_YUV444P::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
1268                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1269 {
1270   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV444P, &RGBA32ToYUV444P);
1271 }
1272 
1273 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1274 Utils_YUV444P::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
1275                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1276 {
1277   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV444P, &libyuv::ARGBToI444);
1278 }
1279 
1280 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1281 Utils_YUV444P::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1282                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1283 {
1284   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV444P, &RGB24ToYUV444P);
1285 }
1286 
1287 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1288 Utils_YUV444P::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1289                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1290 {
1291   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV444P, &BGR24ToYUV444P);
1292 }
1293 
1294 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1295 Utils_YUV444P::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
1296                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1297 {
1298   return nullptr;
1299 }
1300 
1301 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1302 Utils_YUV444P::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
1303                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1304 {
1305   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV444P);
1306 }
1307 
1308 // TODO: optimize me.
1309 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1310 Utils_YUV444P::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
1311                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1312 {
1313   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1314 }
1315 
1316 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1317 Utils_YUV444P::ConvertFrom(Utils_YUV420P*, const uint8_t* aSrcBuffer,
1318                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1319 {
1320   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1321   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1322   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1323 
1324   UniquePtr<ImagePixelLayout> layout =
1325     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1326                         (*aSrcLayout)[0].mHeight,
1327                         (*aSrcLayout)[0].mWidth);
1328 
1329   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV444P");
1330 
1331   const nsTArray<ChannelPixelLayout>& channels = *layout;
1332 
1333   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1334 
1335   int rv = I420ToI444(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1336                       aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1337                       aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
1338                       aDstBuffer + channels[0].mOffset, channels[0].mStride,
1339                       aDstBuffer + channels[1].mOffset, channels[1].mStride,
1340                       aDstBuffer + channels[2].mOffset, channels[2].mStride,
1341                       channels[0].mWidth, channels[0].mHeight);
1342 
1343   if (NS_WARN_IF(rv != 0)) {
1344     return nullptr;
1345   }
1346 
1347   return layout;
1348 }
1349 
1350 // TODO: optimize me.
1351 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1352 Utils_YUV444P::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
1353                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1354 {
1355   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1356 }
1357 
1358 // TODO: optimize me.
1359 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1360 Utils_YUV444P::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
1361                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1362 {
1363   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1364 }
1365 
1366 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1367 Utils_YUV444P::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
1368                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1369 {
1370   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1371 }
1372 
1373 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1374 Utils_YUV444P::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
1375                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1376 {
1377   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1378 }
1379 
1380 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1381 Utils_YUV444P::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
1382                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1383 {
1384   return nullptr;
1385 }
1386 
1387 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)1388 Utils_YUV444P::CanConvertFrom(ImageBitmapFormat aSrcFormat)
1389 {
1390   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
1391       aSrcFormat == ImageBitmapFormat::DEPTH) {
1392     return false;
1393   }
1394 
1395   return true;
1396 }
1397 
1398 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)1399 Utils_YUV444P::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
1400 {
1401   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
1402 
1403   // set mChannels
1404   ChannelPixelLayout* ychannel = layout->AppendElement();
1405   ChannelPixelLayout* uchannel = layout->AppendElement();
1406   ChannelPixelLayout* vchannel = layout->AppendElement();
1407   ychannel->mOffset = 0;
1408   ychannel->mWidth  = aWidth;
1409   ychannel->mHeight = aHeight;
1410   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1411   ychannel->mStride = aStride;
1412   ychannel->mSkip   = 0; // aYSkip;
1413 
1414   uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
1415   uchannel->mWidth  = aWidth;
1416   uchannel->mHeight = aHeight;
1417   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1418   uchannel->mStride = aStride;
1419   uchannel->mSkip   = 0; // aUSkip;
1420 
1421   vchannel->mOffset = uchannel->mOffset + uchannel->mStride * uchannel->mHeight;
1422   vchannel->mWidth  = aWidth;
1423   vchannel->mHeight = aHeight;
1424   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1425   vchannel->mStride = aStride;
1426   vchannel->mSkip   = 0; // aVSkip;
1427 
1428   return layout;
1429 }
1430 
1431 /*
1432  * class Utils_YUV422P.
1433  */
1434 /* static */Utils_YUV422P&
GetInstance()1435 Utils_YUV422P::GetInstance()
1436 {
1437   static Utils_YUV422P instance;
1438   return instance;
1439 }
1440 
Utils_YUV422P()1441 Utils_YUV422P::Utils_YUV422P()
1442 : Utils(3, ChannelPixelLayoutDataType::Uint8)
1443 {
1444 }
1445 
1446 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)1447 Utils_YUV422P::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
1448 {
1449   return aWidth * aHeight * mBytesPerPixelValue +
1450          2 * ((aWidth + 1) / 2) * aHeight * mBytesPerPixelValue;
1451 }
1452 
1453 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1454 Utils_YUV422P::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
1455                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1456 {
1457   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
1458 }
1459 
1460 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1461 Utils_YUV422P::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
1462                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1463 {
1464   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV422P, &RGBA32ToYUV422P);
1465 }
1466 
1467 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1468 Utils_YUV422P::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
1469                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1470 {
1471   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV422P, &libyuv::ARGBToI422);
1472 }
1473 
1474 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1475 Utils_YUV422P::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1476                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1477 {
1478   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV422P, &RGB24ToYUV422P);
1479 }
1480 
1481 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1482 Utils_YUV422P::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1483                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1484 {
1485   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV422P, &BGR24ToYUV422P);
1486 }
1487 
1488 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1489 Utils_YUV422P::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
1490                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1491 {
1492   return nullptr;
1493 }
1494 
1495 // TODO: optimize me.
1496 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1497 Utils_YUV422P::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
1498                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1499 {
1500   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1501 }
1502 
1503 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1504 Utils_YUV422P::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
1505                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1506 {
1507   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV422P);
1508 }
1509 
1510 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1511 Utils_YUV422P::ConvertFrom(Utils_YUV420P*, const uint8_t* aSrcBuffer,
1512                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1513 {
1514   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1515   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1516   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1517 
1518   UniquePtr<ImagePixelLayout> layout =
1519     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1520                         (*aSrcLayout)[0].mHeight,
1521                         (*aSrcLayout)[0].mWidth);
1522 
1523   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV422P");
1524 
1525   const nsTArray<ChannelPixelLayout>& channels = *layout;
1526 
1527   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1528 
1529   libyuv::I420ToI422(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1530                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1531                      aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
1532                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1533                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1534                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
1535                      channels[0].mWidth, channels[0].mHeight);
1536 
1537   return layout;
1538 }
1539 
1540 // TODO: optimize me.
1541 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1542 Utils_YUV422P::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
1543                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1544 {
1545   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1546 }
1547 
1548 // TODO: optimize me.
1549 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1550 Utils_YUV422P::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
1551                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1552 {
1553   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1554 }
1555 
1556 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1557 Utils_YUV422P::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
1558                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1559 {
1560   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1561 }
1562 
1563 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1564 Utils_YUV422P::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
1565                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1566 {
1567   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1568 }
1569 
1570 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1571 Utils_YUV422P::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
1572                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1573 {
1574   return nullptr;
1575 }
1576 
1577 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)1578 Utils_YUV422P::CanConvertFrom(ImageBitmapFormat aSrcFormat)
1579 {
1580   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
1581       aSrcFormat == ImageBitmapFormat::DEPTH) {
1582     return false;
1583   }
1584 
1585   return true;
1586 }
1587 
1588 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)1589 Utils_YUV422P::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
1590 {
1591   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
1592 
1593   // set mChannels
1594   ChannelPixelLayout* ychannel = layout->AppendElement();
1595   ChannelPixelLayout* uchannel = layout->AppendElement();
1596   ChannelPixelLayout* vchannel = layout->AppendElement();
1597   ychannel->mOffset = 0;
1598   ychannel->mWidth  = aWidth;
1599   ychannel->mHeight = aHeight;
1600   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1601   ychannel->mStride = aStride;
1602   ychannel->mSkip   = 0; // aYSkip;
1603 
1604   uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
1605   uchannel->mWidth  = (aWidth + 1) / 2;
1606   uchannel->mHeight = aHeight;
1607   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1608   uchannel->mStride = (aStride + 1) / 2;
1609   uchannel->mSkip   = 0; // aUSkip;
1610 
1611   vchannel->mOffset = uchannel->mOffset + uchannel->mStride * uchannel->mHeight;
1612   vchannel->mWidth  = (aWidth + 1) / 2;
1613   vchannel->mHeight = aHeight;
1614   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1615   vchannel->mStride = (aStride + 1) / 2;
1616   vchannel->mSkip   = 0; // aVSkip;
1617 
1618   return layout;
1619 }
1620 
1621 /*
1622  * Utils_YUV420P.
1623  */
1624 /* static */Utils_YUV420P&
GetInstance()1625 Utils_YUV420P::GetInstance()
1626 {
1627   static Utils_YUV420P instance;
1628   return instance;
1629 }
1630 
Utils_YUV420P()1631 Utils_YUV420P::Utils_YUV420P()
1632 : Utils(3, ChannelPixelLayoutDataType::Uint8)
1633 {
1634 }
1635 
1636 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)1637 Utils_YUV420P::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
1638 {
1639   return aWidth * aHeight * mBytesPerPixelValue +
1640          2 * ((aWidth + 1) / 2) * ((aHeight + 1) / 2) * mBytesPerPixelValue;
1641 }
1642 
1643 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1644 Utils_YUV420P::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
1645                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1646 {
1647   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
1648 }
1649 
1650 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1651 Utils_YUV420P::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
1652                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1653 {
1654   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, &libyuv::ABGRToI420);
1655 }
1656 
1657 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1658 Utils_YUV420P::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
1659                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1660 {
1661   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, &libyuv::ARGBToI420);
1662 }
1663 
1664 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1665 Utils_YUV420P::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1666                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1667 {
1668   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, &RGB24ToYUV420P);
1669 }
1670 
1671 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1672 Utils_YUV420P::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1673                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1674 {
1675   return CvtSimpleImgToYUVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, &BGR24ToYUV420P);
1676 }
1677 
1678 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1679 Utils_YUV420P::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
1680                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1681 {
1682   return nullptr;
1683 }
1684 
1685 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1686 Utils_YUV420P::ConvertFrom(Utils_YUV444P*, const uint8_t* aSrcBuffer,
1687                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1688 {
1689   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1690   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1691   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1692 
1693   UniquePtr<ImagePixelLayout> layout =
1694     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1695                         (*aSrcLayout)[0].mHeight,
1696                         (*aSrcLayout)[0].mWidth);
1697 
1698   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420P");
1699 
1700   const nsTArray<ChannelPixelLayout>& channels = *layout;
1701 
1702   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1703 
1704   libyuv::I444ToI420(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1705                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1706                      aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
1707                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1708                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1709                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
1710                      channels[0].mWidth, channels[0].mHeight);
1711 
1712   return layout;
1713 }
1714 
1715 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1716 Utils_YUV420P::ConvertFrom(Utils_YUV422P*, const uint8_t* aSrcBuffer,
1717                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1718 {
1719   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1720   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1721   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1722 
1723   UniquePtr<ImagePixelLayout> layout =
1724     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1725                         (*aSrcLayout)[0].mHeight,
1726                         (*aSrcLayout)[0].mWidth);
1727 
1728   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420P");
1729 
1730   const nsTArray<ChannelPixelLayout>& channels = *layout;
1731 
1732   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1733 
1734   libyuv::I422ToI420(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1735                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1736                      aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
1737                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1738                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1739                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
1740                      channels[0].mWidth, channels[0].mHeight);
1741 
1742   return layout;
1743 }
1744 
1745 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1746 Utils_YUV420P::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
1747                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1748 {
1749   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P);
1750 }
1751 
1752 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1753 Utils_YUV420P::ConvertFrom(Utils_YUV420SP_NV12*, const uint8_t* aSrcBuffer,
1754                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1755 {
1756   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1757   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1758   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1759 
1760   UniquePtr<ImagePixelLayout> layout =
1761     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1762                         (*aSrcLayout)[0].mHeight,
1763                         (*aSrcLayout)[0].mWidth);
1764 
1765   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420P");
1766 
1767   const nsTArray<ChannelPixelLayout>& channels = *layout;
1768 
1769   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1770 
1771   libyuv::NV12ToI420(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1772                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1773                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1774                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1775                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
1776                      channels[0].mWidth, channels[0].mHeight);
1777 
1778   return layout;
1779 }
1780 
1781 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1782 Utils_YUV420P::ConvertFrom(Utils_YUV420SP_NV21*, const uint8_t* aSrcBuffer,
1783                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1784 {
1785   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1786   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1787   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1788 
1789   UniquePtr<ImagePixelLayout> layout =
1790     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1791                         (*aSrcLayout)[0].mHeight,
1792                         (*aSrcLayout)[0].mWidth);
1793 
1794   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420P");
1795 
1796   const nsTArray<ChannelPixelLayout>& channels = *layout;
1797 
1798   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1799 
1800   libyuv::NV21ToI420(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1801                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1802                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1803                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1804                      aDstBuffer + channels[2].mOffset, channels[2].mStride,
1805                      channels[0].mWidth, channels[0].mHeight);
1806 
1807   return layout;
1808 }
1809 
1810 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1811 Utils_YUV420P::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
1812                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1813 {
1814   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1815 }
1816 
1817 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1818 Utils_YUV420P::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
1819                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1820 {
1821   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
1822 }
1823 
1824 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1825 Utils_YUV420P::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
1826                            const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1827 {
1828   return nullptr;
1829 }
1830 
1831 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)1832 Utils_YUV420P::CanConvertFrom(ImageBitmapFormat aSrcFormat)
1833 {
1834   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
1835       aSrcFormat == ImageBitmapFormat::DEPTH) {
1836     return false;
1837   }
1838 
1839   return true;
1840 }
1841 
1842 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)1843 Utils_YUV420P::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
1844 {
1845   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
1846 
1847   // set mChannels
1848   ChannelPixelLayout* ychannel = layout->AppendElement();
1849   ChannelPixelLayout* uchannel = layout->AppendElement();
1850   ChannelPixelLayout* vchannel = layout->AppendElement();
1851   ychannel->mOffset = 0;
1852   ychannel->mWidth  = aWidth;
1853   ychannel->mHeight = aHeight;
1854   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1855   ychannel->mStride = aStride;
1856   ychannel->mSkip   = 0; // aYSkip;
1857 
1858   uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
1859   uchannel->mWidth  = (aWidth + 1) / 2;
1860   uchannel->mHeight = (aHeight + 1) / 2;
1861   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1862   uchannel->mStride = (aStride + 1) / 2;
1863   uchannel->mSkip   = 0; // aUSkip;
1864 
1865   vchannel->mOffset = uchannel->mOffset + uchannel->mStride * uchannel->mHeight;
1866   vchannel->mWidth  = (aWidth + 1) / 2;
1867   vchannel->mHeight = (aHeight + 1) / 2;
1868   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
1869   vchannel->mStride = (aStride + 1) / 2;
1870   vchannel->mSkip   = 0; // aVSkip;
1871 
1872   return layout;
1873 }
1874 
1875 /*
1876  * class Utils_YUV420SP_NV12.
1877  */
1878 /* static */Utils_YUV420SP_NV12&
GetInstance()1879 Utils_YUV420SP_NV12::GetInstance()
1880 {
1881   static Utils_YUV420SP_NV12 instance;
1882   return instance;
1883 }
1884 
Utils_YUV420SP_NV12()1885 Utils_YUV420SP_NV12::Utils_YUV420SP_NV12()
1886 : Utils(3, ChannelPixelLayoutDataType::Uint8)
1887 {
1888 }
1889 
1890 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)1891 Utils_YUV420SP_NV12::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
1892 {
1893   return aWidth * aHeight * mBytesPerPixelValue +
1894          2 * ((aWidth + 1) / 2) * ((aHeight + 1) / 2) * mBytesPerPixelValue;
1895 }
1896 
1897 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1898 Utils_YUV420SP_NV12::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
1899                                const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1900 {
1901   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
1902 }
1903 
1904 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1905 Utils_YUV420SP_NV12::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
1906                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1907 {
1908   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV12, &RGBA32ToNV12);
1909 }
1910 
1911 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1912 Utils_YUV420SP_NV12::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
1913                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1914 {
1915   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV12, &libyuv::ARGBToNV12);
1916 }
1917 
1918 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1919 Utils_YUV420SP_NV12::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
1920                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1921 {
1922   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV12, &RGB24ToNV12);
1923 }
1924 
1925 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1926 Utils_YUV420SP_NV12::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
1927                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1928 {
1929   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV12, &BGR24ToNV12);
1930 }
1931 
1932 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1933 Utils_YUV420SP_NV12::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
1934                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1935 {
1936   return nullptr;
1937 }
1938 
1939 // TODO: optimize me.
1940 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1941 Utils_YUV420SP_NV12::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
1942                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1943 {
1944   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1945 }
1946 
1947 // TODO: optimize me.
1948 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1949 Utils_YUV420SP_NV12::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
1950                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1951 {
1952   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1953 }
1954 
1955 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1956 Utils_YUV420SP_NV12::ConvertFrom(Utils_YUV420P*, const uint8_t* aSrcBuffer,
1957                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1958 {
1959   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
1960   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
1961   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
1962 
1963   UniquePtr<ImagePixelLayout> layout =
1964     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
1965                         (*aSrcLayout)[0].mHeight,
1966                         (*aSrcLayout)[0].mWidth);
1967 
1968   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420SP_NV12");
1969 
1970   const nsTArray<ChannelPixelLayout>& channels = *layout;
1971 
1972   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
1973 
1974   libyuv::I420ToNV12(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
1975                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
1976                      aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
1977                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
1978                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
1979                      channels[0].mWidth, channels[0].mHeight);
1980 
1981   return layout;
1982 }
1983 
1984 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1985 Utils_YUV420SP_NV12::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
1986                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1987 {
1988   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV12);
1989 }
1990 
1991 // TODO: optimize me.
1992 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)1993 Utils_YUV420SP_NV12::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
1994                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
1995 {
1996   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
1997 }
1998 
1999 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2000 Utils_YUV420SP_NV12::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
2001                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2002 {
2003   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2004 }
2005 
2006 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2007 Utils_YUV420SP_NV12::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
2008                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2009 {
2010   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2011 }
2012 
2013 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2014 Utils_YUV420SP_NV12::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
2015                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2016 {
2017   return nullptr;
2018 }
2019 
2020 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)2021 Utils_YUV420SP_NV12::CanConvertFrom(ImageBitmapFormat aSrcFormat)
2022 {
2023   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
2024       aSrcFormat == ImageBitmapFormat::DEPTH) {
2025     return false;
2026   }
2027 
2028   return true;
2029 }
2030 
2031 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2032 Utils_YUV420SP_NV12::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
2033 {
2034   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
2035 
2036   // set mChannels
2037   ChannelPixelLayout* ychannel = layout->AppendElement();
2038   ChannelPixelLayout* uchannel = layout->AppendElement();
2039   ChannelPixelLayout* vchannel = layout->AppendElement();
2040   ychannel->mOffset = 0;
2041   ychannel->mWidth  = aWidth;
2042   ychannel->mHeight = aHeight;
2043   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2044   ychannel->mStride = aStride;
2045   ychannel->mSkip   = 0; // aYSkip;
2046 
2047   uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
2048   uchannel->mWidth  = (aWidth + 1) / 2;
2049   uchannel->mHeight = (aHeight + 1) / 2;
2050   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2051   uchannel->mStride = uchannel->mWidth * 2;
2052   uchannel->mSkip   = 1; // aUSkip;
2053 
2054   vchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight + 1;
2055   vchannel->mWidth  = (aWidth + 1) / 2;
2056   vchannel->mHeight = (aHeight + 1) / 2;
2057   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2058   vchannel->mStride = vchannel->mWidth * 2;
2059   vchannel->mSkip   = 1; // aVSkip;
2060 
2061   return layout;
2062 }
2063 
2064 /*
2065  * class Utils_YUV420SP_NV21.
2066  */
2067 /* static */Utils_YUV420SP_NV21&
GetInstance()2068 Utils_YUV420SP_NV21::GetInstance()
2069 {
2070   static Utils_YUV420SP_NV21 instance;
2071   return instance;
2072 }
2073 
Utils_YUV420SP_NV21()2074 Utils_YUV420SP_NV21::Utils_YUV420SP_NV21()
2075 : Utils(3, ChannelPixelLayoutDataType::Uint8)
2076 {
2077 }
2078 
2079 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)2080 Utils_YUV420SP_NV21::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
2081 {
2082   return aWidth * aHeight * mBytesPerPixelValue +
2083          2 * ((aWidth + 1) / 2) * ((aHeight + 1) / 2) * mBytesPerPixelValue;
2084 }
2085 
2086 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2087 Utils_YUV420SP_NV21::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
2088                                const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2089 {
2090   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
2091 }
2092 
2093 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2094 Utils_YUV420SP_NV21::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
2095                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2096 {
2097   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV21, &RGBA32ToNV21);
2098 }
2099 
2100 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2101 Utils_YUV420SP_NV21::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
2102                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2103 {
2104   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV21, &libyuv::ARGBToNV21);
2105 }
2106 
2107 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2108 Utils_YUV420SP_NV21::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
2109                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2110 {
2111   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV21, &RGB24ToNV21);
2112 }
2113 
2114 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2115 Utils_YUV420SP_NV21::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
2116                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2117 {
2118   return CvtSimpleImgToNVImg(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV21, &BGR24ToNV21);
2119 }
2120 
2121 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2122 Utils_YUV420SP_NV21::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
2123                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2124 {
2125   return nullptr;
2126 }
2127 
2128 // TODO: optimize me.
2129 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2130 Utils_YUV420SP_NV21::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
2131                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2132 {
2133   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
2134 }
2135 
2136 // TODO: optimize me.
2137 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2138 Utils_YUV420SP_NV21::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
2139                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2140 {
2141   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
2142 }
2143 
2144 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P *,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2145 Utils_YUV420SP_NV21::ConvertFrom(Utils_YUV420P*, const uint8_t* aSrcBuffer,
2146                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2147 {
2148   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
2149   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
2150   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
2151 
2152   UniquePtr<ImagePixelLayout> layout =
2153     CreateDefaultLayout((*aSrcLayout)[0].mWidth,
2154                         (*aSrcLayout)[0].mHeight,
2155                         (*aSrcLayout)[0].mWidth);
2156 
2157   MOZ_ASSERT(layout, "Cannot create a ImagePixelLayout of YUV420SP_NV21");
2158 
2159   const nsTArray<ChannelPixelLayout>& channels = *layout;
2160 
2161   const nsTArray<ChannelPixelLayout>& srcChannels = *aSrcLayout;
2162 
2163   libyuv::I420ToNV21(aSrcBuffer + srcChannels[0].mOffset, srcChannels[0].mStride,
2164                      aSrcBuffer + srcChannels[1].mOffset, srcChannels[1].mStride,
2165                      aSrcBuffer + srcChannels[2].mOffset, srcChannels[2].mStride,
2166                      aDstBuffer + channels[0].mOffset, channels[0].mStride,
2167                      aDstBuffer + channels[1].mOffset, channels[1].mStride,
2168                      channels[0].mWidth, channels[0].mHeight);
2169 
2170   return layout;
2171 }
2172 
2173 // TODO: optimize me.
2174 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2175 Utils_YUV420SP_NV21::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
2176                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2177 {
2178   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420P, this);
2179 }
2180 
2181 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2182 Utils_YUV420SP_NV21::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
2183                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2184 {
2185   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::YUV420SP_NV21);
2186 }
2187 
2188 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2189 Utils_YUV420SP_NV21::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
2190                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2191 {
2192   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2193 }
2194 
2195 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2196 Utils_YUV420SP_NV21::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
2197                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2198 {
2199   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2200 }
2201 
2202 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2203 Utils_YUV420SP_NV21::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
2204                                  const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2205 {
2206   return nullptr;
2207 }
2208 
2209 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)2210 Utils_YUV420SP_NV21::CanConvertFrom(ImageBitmapFormat aSrcFormat)
2211 {
2212   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
2213       aSrcFormat == ImageBitmapFormat::DEPTH) {
2214     return false;
2215   }
2216 
2217   return true;
2218 }
2219 
2220 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2221 Utils_YUV420SP_NV21::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
2222 {
2223   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(mChannels));
2224 
2225   // set mChannels
2226   ChannelPixelLayout* ychannel = layout->AppendElement();
2227   ChannelPixelLayout* vchannel = layout->AppendElement(); // v is the 2nd channel.
2228   ChannelPixelLayout* uchannel = layout->AppendElement(); // u is the 3rd channel.
2229   ychannel->mOffset = 0;
2230   ychannel->mWidth  = aWidth;
2231   ychannel->mHeight = aHeight;
2232   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2233   ychannel->mStride = aStride;
2234   ychannel->mSkip   = 0; // aYSkip;
2235 
2236   vchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight;
2237   vchannel->mWidth  = (aWidth + 1) / 2;
2238   vchannel->mHeight = (aHeight + 1) / 2;
2239   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2240   vchannel->mStride = vchannel->mWidth * 2;
2241   vchannel->mSkip   = 1; // aVSkip;
2242 
2243   uchannel->mOffset = ychannel->mOffset + ychannel->mStride * ychannel->mHeight + 1;
2244   uchannel->mWidth  = (aWidth + 1) / 2;
2245   uchannel->mHeight = (aHeight + 1) / 2;
2246   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2247   uchannel->mStride = uchannel->mWidth * 2;
2248   uchannel->mSkip   = 1; // aUSkip;
2249 
2250   return layout;
2251 }
2252 
2253 /*
2254  * Utils_HSV.
2255  */
2256 /* static */Utils_HSV&
GetInstance()2257 Utils_HSV::GetInstance()
2258 {
2259   static Utils_HSV instance;
2260   return instance;
2261 }
2262 
Utils_HSV()2263 Utils_HSV::Utils_HSV()
2264 : Utils(3, ChannelPixelLayoutDataType::Float32)
2265 {
2266 }
2267 
2268 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)2269 Utils_HSV::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
2270 {
2271   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
2272 }
2273 
2274 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2275 Utils_HSV::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
2276                      const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2277 {
2278   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
2279 }
2280 
2281 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2282 Utils_HSV::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
2283                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2284 {
2285   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcFormat, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::HSV, 3, &RGBA32ToHSV);
2286 }
2287 
2288 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2289 Utils_HSV::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
2290                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2291 {
2292   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcFormat, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::HSV, 3, &BGRA32ToHSV);
2293 }
2294 
2295 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2296 Utils_HSV::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
2297                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2298 {
2299   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::HSV, 3, &RGB24ToHSV);
2300 }
2301 
2302 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2303 Utils_HSV::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
2304                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2305 {
2306   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::HSV, 3, &BGR24ToHSV);
2307 }
2308 
2309 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2310 Utils_HSV::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
2311                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2312 {
2313   return nullptr;
2314 }
2315 
2316 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2317 Utils_HSV::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
2318                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2319 {
2320   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2321 }
2322 
2323 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2324 Utils_HSV::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
2325                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2326 {
2327   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2328 }
2329 
2330 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2331 Utils_HSV::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
2332                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2333 {
2334   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2335 }
2336 
2337 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2338 Utils_HSV::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
2339                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2340 {
2341   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2342 }
2343 
2344 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2345 Utils_HSV::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
2346                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2347 {
2348   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2349 }
2350 
2351 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2352 Utils_HSV::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
2353                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2354 {
2355   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::HSV);
2356 }
2357 
2358 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2359 Utils_HSV::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
2360                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2361 {
2362   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2363 }
2364 
2365 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2366 Utils_HSV::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
2367                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2368 {
2369   return nullptr;
2370 }
2371 
2372 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)2373 Utils_HSV::CanConvertFrom(ImageBitmapFormat aSrcFormat)
2374 {
2375   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
2376       aSrcFormat == ImageBitmapFormat::DEPTH) {
2377     return false;
2378   }
2379 
2380   return true;
2381 }
2382 
2383 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2384 Utils_HSV::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
2385 {
2386   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
2387 }
2388 
2389 /*
2390  * Utils_Lab.
2391  */
2392 /* static */Utils_Lab&
GetInstance()2393 Utils_Lab::GetInstance()
2394 {
2395   static Utils_Lab instance;
2396   return instance;
2397 }
2398 
Utils_Lab()2399 Utils_Lab::Utils_Lab()
2400 : Utils(3, ChannelPixelLayoutDataType::Float32)
2401 {
2402 }
2403 
2404 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)2405 Utils_Lab::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
2406 {
2407   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
2408 }
2409 
2410 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2411 Utils_Lab::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
2412                      const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2413 {
2414   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
2415 }
2416 
2417 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2418 Utils_Lab::ConvertFrom(Utils_RGBA32* aSrcUtils, const uint8_t* aSrcBuffer,
2419                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2420 {
2421   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::Lab, 3, &RGBA32ToLab);
2422 }
2423 
2424 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2425 Utils_Lab::ConvertFrom(Utils_BGRA32* aSrcUtils, const uint8_t* aSrcBuffer,
2426                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2427 {
2428   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::Lab, 3, &BGRA32ToLab);
2429 }
2430 
2431 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2432 Utils_Lab::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
2433                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2434 {
2435   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::Lab, 3, &RGB24ToLab);
2436 }
2437 
2438 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2439 Utils_Lab::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
2440                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2441 {
2442   return CvtSimpleImgToSimpleImg<uint8_t, float>(aSrcUtils, aSrcBuffer, aSrcLayout, (float*)aDstBuffer, ImageBitmapFormat::Lab, 3, &BGR24ToLab);
2443 }
2444 
2445 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2446 Utils_Lab::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
2447                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2448 {
2449   return nullptr;
2450 }
2451 
2452 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2453 Utils_Lab::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
2454                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2455 {
2456   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2457 }
2458 
2459 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2460 Utils_Lab::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
2461                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2462 {
2463   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2464 }
2465 
2466 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2467 Utils_Lab::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
2468                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2469 {
2470   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2471 }
2472 
2473 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2474 Utils_Lab::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
2475                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2476 {
2477   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2478 }
2479 
2480 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2481 Utils_Lab::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
2482                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2483 {
2484   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2485 }
2486 
2487 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2488 Utils_Lab::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
2489                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2490 {
2491   return TwoPassConversion(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::RGB24, this);
2492 }
2493 
2494 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2495 Utils_Lab::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
2496                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2497 {
2498   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::Lab);
2499 }
2500 
2501 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2502 Utils_Lab::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
2503                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2504 {
2505   return nullptr;
2506 }
2507 
2508 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)2509 Utils_Lab::CanConvertFrom(ImageBitmapFormat aSrcFormat)
2510 {
2511   if (aSrcFormat == ImageBitmapFormat::GRAY8 ||
2512       aSrcFormat == ImageBitmapFormat::DEPTH) {
2513     return false;
2514   }
2515 
2516   return true;
2517 }
2518 
2519 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2520 Utils_Lab::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
2521 {
2522   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
2523 }
2524 
2525 /*
2526  * Utils_Depth.
2527  */
2528 /* static */Utils_Depth&
GetInstance()2529 Utils_Depth::GetInstance()
2530 {
2531   static Utils_Depth instance;
2532   return instance;
2533 }
2534 
Utils_Depth()2535 Utils_Depth::Utils_Depth()
2536 : Utils(1, ChannelPixelLayoutDataType::Uint16)
2537 {
2538 }
2539 
2540 uint32_t
NeededBufferSize(uint32_t aWidth,uint32_t aHeight)2541 Utils_Depth::NeededBufferSize(uint32_t aWidth, uint32_t aHeight)
2542 {
2543   return aWidth * aHeight * (uint32_t)mChannels * mBytesPerPixelValue;
2544 }
2545 
2546 UniquePtr<ImagePixelLayout>
ConvertTo(Utils * aDstFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2547 Utils_Depth::ConvertTo(Utils* aDstFormat, const uint8_t* aSrcBuffer,
2548                        const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2549 {
2550   return aDstFormat->ConvertFrom(this, aSrcBuffer, aSrcLayout, aDstBuffer);
2551 }
2552 
2553 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGBA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2554 Utils_Depth::ConvertFrom(Utils_RGBA32* aSrcFormat, const uint8_t* aSrcBuffer,
2555                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2556 {
2557   return nullptr;
2558 }
2559 
2560 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGRA32 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2561 Utils_Depth::ConvertFrom(Utils_BGRA32* aSrcFormat, const uint8_t* aSrcBuffer,
2562                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2563 {
2564   return nullptr;
2565 }
2566 
2567 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_RGB24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2568 Utils_Depth::ConvertFrom(Utils_RGB24* aSrcUtils, const uint8_t* aSrcBuffer,
2569                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2570 {
2571   return nullptr;
2572 }
2573 
2574 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_BGR24 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2575 Utils_Depth::ConvertFrom(Utils_BGR24* aSrcUtils, const uint8_t* aSrcBuffer,
2576                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2577 {
2578   return nullptr;
2579 }
2580 
2581 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Gray8 * aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2582 Utils_Depth::ConvertFrom(Utils_Gray8* aSrcFormat, const uint8_t* aSrcBuffer,
2583                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2584 {
2585   return nullptr;
2586 }
2587 
2588 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV444P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2589 Utils_Depth::ConvertFrom(Utils_YUV444P* aSrcUtils, const uint8_t* aSrcBuffer,
2590                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2591 {
2592   return nullptr;
2593 }
2594 
2595 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV422P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2596 Utils_Depth::ConvertFrom(Utils_YUV422P* aSrcUtils, const uint8_t* aSrcBuffer,
2597                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2598 {
2599   return nullptr;
2600 }
2601 
2602 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420P * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2603 Utils_Depth::ConvertFrom(Utils_YUV420P* aSrcUtils, const uint8_t* aSrcBuffer,
2604                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2605 {
2606   return nullptr;
2607 }
2608 
2609 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV12 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2610 Utils_Depth::ConvertFrom(Utils_YUV420SP_NV12* aSrcUtils, const uint8_t* aSrcBuffer,
2611                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2612 {
2613   return nullptr;
2614 }
2615 
2616 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_YUV420SP_NV21 * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2617 Utils_Depth::ConvertFrom(Utils_YUV420SP_NV21* aSrcUtils, const uint8_t* aSrcBuffer,
2618                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2619 {
2620   return nullptr;
2621 }
2622 
2623 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_HSV * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2624 Utils_Depth::ConvertFrom(Utils_HSV* aSrcUtils, const uint8_t* aSrcBuffer,
2625                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2626 {
2627   return nullptr;
2628 }
2629 
2630 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Lab * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2631 Utils_Depth::ConvertFrom(Utils_Lab* aSrcUtils, const uint8_t* aSrcBuffer,
2632                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2633 {
2634   return nullptr;
2635 }
2636 
2637 UniquePtr<ImagePixelLayout>
ConvertFrom(Utils_Depth * aSrcUtils,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,uint8_t * aDstBuffer)2638 Utils_Depth::ConvertFrom(Utils_Depth* aSrcUtils, const uint8_t* aSrcBuffer,
2639                          const ImagePixelLayout* aSrcLayout, uint8_t* aDstBuffer)
2640 {
2641   return PureCopy(aSrcUtils, aSrcBuffer, aSrcLayout, aDstBuffer, ImageBitmapFormat::DEPTH);
2642 }
2643 
2644 bool
CanConvertFrom(ImageBitmapFormat aSrcFormat)2645 Utils_Depth::CanConvertFrom(ImageBitmapFormat aSrcFormat)
2646 {
2647   if (aSrcFormat == ImageBitmapFormat::DEPTH ) {
2648     return true;
2649   }
2650 
2651   return false;
2652 }
2653 
2654 UniquePtr<ImagePixelLayout>
CreateDefaultLayout(uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2655 Utils_Depth::CreateDefaultLayout(uint32_t aWidth, uint32_t aHeight, uint32_t aStride)
2656 {
2657   return CreateDefaultLayoutForSimpleImage(aWidth, aHeight, aStride, mChannels, mBytesPerPixelValue, mDataType);
2658 }
2659 
2660 } // namespace imagebitmapformat
2661 
2662 /*
2663  * Global functions.
2664  */
2665 
2666 using namespace mozilla::dom::imagebitmapformat;
2667 
2668 UniquePtr<ImagePixelLayout>
CreateDefaultPixelLayout(ImageBitmapFormat aFormat,uint32_t aWidth,uint32_t aHeight,uint32_t aStride)2669 CreateDefaultPixelLayout(ImageBitmapFormat aFormat, uint32_t aWidth,
2670                          uint32_t aHeight, uint32_t aStride)
2671 {
2672   UtilsUniquePtr format = Utils::GetUtils(aFormat);
2673   MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
2674 
2675   return format->CreateDefaultLayout(aWidth, aHeight, aStride);
2676 }
2677 
2678 UniquePtr<ImagePixelLayout>
CreatePixelLayoutFromPlanarYCbCrData(const layers::PlanarYCbCrData * aData)2679 CreatePixelLayoutFromPlanarYCbCrData(const layers::PlanarYCbCrData* aData)
2680 {
2681   if (!aData) {
2682     // something wrong
2683     return nullptr;
2684   }
2685 
2686   UniquePtr<ImagePixelLayout> layout(new ImagePixelLayout(3));
2687 
2688   ChannelPixelLayout* ychannel = layout->AppendElement();
2689   ChannelPixelLayout* uchannel = layout->AppendElement();
2690   ChannelPixelLayout* vchannel = layout->AppendElement();
2691 
2692   ychannel->mOffset = 0;
2693 
2694   if (aData->mCrChannel - aData->mCbChannel > 0) {
2695     uchannel->mOffset = ychannel->mOffset + (aData->mCbChannel - aData->mYChannel);
2696     vchannel->mOffset = uchannel->mOffset + (aData->mCrChannel - aData->mCbChannel);
2697   } else {
2698     uchannel->mOffset = ychannel->mOffset + (aData->mCrChannel - aData->mYChannel);
2699     vchannel->mOffset = uchannel->mOffset + (aData->mCbChannel - aData->mCrChannel);
2700   }
2701 
2702   ychannel->mWidth = aData->mYSize.width;
2703   ychannel->mHeight = aData->mYSize.height;
2704   ychannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2705   ychannel->mStride = aData->mYStride;
2706   ychannel->mSkip = aData->mYSkip;
2707 
2708   uchannel->mWidth = aData->mCbCrSize.width;
2709   uchannel->mHeight = aData->mCbCrSize.height;
2710   uchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2711   uchannel->mStride = aData->mCbCrStride;
2712   uchannel->mSkip = aData->mCbSkip;
2713 
2714   vchannel->mWidth = aData->mCbCrSize.width;
2715   vchannel->mHeight = aData->mCbCrSize.height;
2716   vchannel->mDataType = ChannelPixelLayoutDataType::Uint8;
2717   vchannel->mStride = aData->mCbCrStride;
2718   vchannel->mSkip = aData->mCrSkip;
2719 
2720   return layout;
2721 }
2722 
2723 uint8_t
GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)2724 GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)
2725 {
2726   UtilsUniquePtr format = Utils::GetUtils(aFormat);
2727   MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
2728 
2729   return format->GetChannelCount();
2730 }
2731 
2732 uint32_t
CalculateImageBufferSize(ImageBitmapFormat aFormat,uint32_t aWidth,uint32_t aHeight)2733 CalculateImageBufferSize(ImageBitmapFormat aFormat,
2734                          uint32_t aWidth, uint32_t aHeight)
2735 {
2736   UtilsUniquePtr format = Utils::GetUtils(aFormat);
2737   MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
2738 
2739   return format->NeededBufferSize(aWidth, aHeight);
2740 }
2741 
2742 UniquePtr<ImagePixelLayout>
CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,const uint8_t * aSrcBuffer,const ImagePixelLayout * aSrcLayout,ImageBitmapFormat aDstFormat,uint8_t * aDstBuffer)2743 CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,
2744                         const uint8_t* aSrcBuffer,
2745                         const ImagePixelLayout* aSrcLayout,
2746                         ImageBitmapFormat aDstFormat,
2747                         uint8_t* aDstBuffer)
2748 {
2749   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
2750   MOZ_ASSERT(aSrcLayout, "Convert color from a null layout.");
2751   MOZ_ASSERT(aDstBuffer, "Convert color to a null buffer.");
2752 
2753   UtilsUniquePtr srcFormat = Utils::GetUtils(aSrcFormat);
2754   UtilsUniquePtr dstFormat = Utils::GetUtils(aDstFormat);
2755   MOZ_ASSERT(srcFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
2756   MOZ_ASSERT(dstFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
2757 
2758   return srcFormat->ConvertTo(dstFormat.get(), aSrcBuffer, aSrcLayout, aDstBuffer);
2759 }
2760 
2761 ImageBitmapFormat
FindBestMatchingFromat(ImageBitmapFormat aSrcFormat,const Sequence<ImageBitmapFormat> & aCandidates)2762 FindBestMatchingFromat(ImageBitmapFormat aSrcFormat,
2763                        const Sequence<ImageBitmapFormat>& aCandidates) {
2764 
2765   for(auto& candidate : aCandidates) {
2766     UtilsUniquePtr candidateFormat = Utils::GetUtils(candidate);
2767     MOZ_ASSERT(candidateFormat, "Cannot get a valid ImageBitmapFormatUtils instance.");
2768 
2769     if (candidateFormat->CanConvertFrom(aSrcFormat)) {
2770       return candidate;
2771     }
2772   }
2773 
2774   return ImageBitmapFormat::EndGuard_;
2775 }
2776 
2777 } // namespace dom
2778 } // namespace mozilla
2779