1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "YCbCrUtils.h"
9 #include "yuv_convert.h"
10 #include "ycbcr_to_rgb565.h"
16 GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData
& aData
,
17 SurfaceFormat
& aSuggestedFormat
,
18 IntSize
& aSuggestedSize
)
21 TypeFromSize(aData
.mYSize
.width
,
23 aData
.mCbCrSize
.width
,
24 aData
.mCbCrSize
.height
);
26 // 'prescale' is true if the scaling is to be done as part of the
27 // YCbCr to RGB conversion rather than on the RGB data when rendered.
28 bool prescale
= aSuggestedSize
.width
> 0 && aSuggestedSize
.height
> 0 &&
29 aSuggestedSize
!= aData
.mPicSize
;
31 if (aSuggestedFormat
== SurfaceFormat::R5G6B5
) {
32 #if defined(HAVE_YCBCR_TO_RGB565)
34 !IsScaleYCbCrToRGB565Fast(aData
.mPicX
,
37 aData
.mPicSize
.height
,
39 aSuggestedSize
.height
,
42 IsConvertYCbCrToRGB565Fast(aData
.mPicX
,
45 aData
.mPicSize
.height
,
50 // yuv2rgb16 function not available
51 aSuggestedFormat
= SurfaceFormat::B8G8R8X8
;
54 else if (aSuggestedFormat
!= SurfaceFormat::B8G8R8X8
) {
55 // No other formats are currently supported.
56 aSuggestedFormat
= SurfaceFormat::B8G8R8X8
;
58 if (aSuggestedFormat
== SurfaceFormat::B8G8R8X8
) {
59 /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data.
60 See bugs 639415 and 640073. */
61 if (aData
.mPicX
!= 0 || aData
.mPicY
!= 0 || yuvtype
== YV24
)
65 aSuggestedSize
= aData
.mPicSize
;
70 ConvertYCbCrToRGB(const layers::PlanarYCbCrData
& aData
,
71 const SurfaceFormat
& aDestFormat
,
72 const IntSize
& aDestSize
,
73 unsigned char* aDestBuffer
,
76 // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
77 // luma plane is odd sized.
78 MOZ_ASSERT((aData
.mCbCrSize
.width
== aData
.mYSize
.width
||
79 aData
.mCbCrSize
.width
== (aData
.mYSize
.width
+ 1) >> 1) &&
80 (aData
.mCbCrSize
.height
== aData
.mYSize
.height
||
81 aData
.mCbCrSize
.height
== (aData
.mYSize
.height
+ 1) >> 1));
83 TypeFromSize(aData
.mYSize
.width
,
85 aData
.mCbCrSize
.width
,
86 aData
.mCbCrSize
.height
);
88 // Convert from YCbCr to RGB now, scaling the image if needed.
89 if (aDestSize
!= aData
.mPicSize
) {
90 #if defined(HAVE_YCBCR_TO_RGB565)
91 if (aDestFormat
== SurfaceFormat::R5G6B5
) {
92 ScaleYCbCrToRGB565(aData
.mYChannel
,
99 aData
.mPicSize
.height
,
109 ScaleYCbCrToRGB32(aData
.mYChannel
, //
113 aData
.mPicSize
.width
,
114 aData
.mPicSize
.height
,
123 } else { // no prescale
124 #if defined(HAVE_YCBCR_TO_RGB565)
125 if (aDestFormat
== SurfaceFormat::R5G6B5
) {
126 ConvertYCbCrToRGB565(aData
.mYChannel
,
132 aData
.mPicSize
.width
,
133 aData
.mPicSize
.height
,
138 } else // aDestFormat != gfxImageFormat::RGB16_565
140 ConvertYCbCrToRGB32(aData
.mYChannel
, //
146 aData
.mPicSize
.width
,
147 aData
.mPicSize
.height
,