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