Bumping manifests a=b2g-bump
[gecko.git] / gfx / ycbcr / YCbCrUtils.cpp
blob26fb95f03411df5cac93c1a7a575ae298afc7678
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/. */
6 #include "gfx2DGlue.h"
8 #include "YCbCrUtils.h"
9 #include "yuv_convert.h"
10 #include "ycbcr_to_rgb565.h"
12 namespace mozilla {
13 namespace gfx {
15 void
16 GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
17 SurfaceFormat& aSuggestedFormat,
18 IntSize& aSuggestedSize)
20 YUVType yuvtype =
21 TypeFromSize(aData.mYSize.width,
22 aData.mYSize.height,
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)
33 if (prescale &&
34 !IsScaleYCbCrToRGB565Fast(aData.mPicX,
35 aData.mPicY,
36 aData.mPicSize.width,
37 aData.mPicSize.height,
38 aSuggestedSize.width,
39 aSuggestedSize.height,
40 yuvtype,
41 FILTER_BILINEAR) &&
42 IsConvertYCbCrToRGB565Fast(aData.mPicX,
43 aData.mPicY,
44 aData.mPicSize.width,
45 aData.mPicSize.height,
46 yuvtype)) {
47 prescale = false;
49 #else
50 // yuv2rgb16 function not available
51 aSuggestedFormat = SurfaceFormat::B8G8R8X8;
52 #endif
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)
62 prescale = false;
64 if (!prescale) {
65 aSuggestedSize = aData.mPicSize;
69 void
70 ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
71 const SurfaceFormat& aDestFormat,
72 const IntSize& aDestSize,
73 unsigned char* aDestBuffer,
74 int32_t aStride)
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));
82 YUVType yuvtype =
83 TypeFromSize(aData.mYSize.width,
84 aData.mYSize.height,
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,
93 aData.mCbChannel,
94 aData.mCrChannel,
95 aDestBuffer,
96 aData.mPicX,
97 aData.mPicY,
98 aData.mPicSize.width,
99 aData.mPicSize.height,
100 aDestSize.width,
101 aDestSize.height,
102 aData.mYStride,
103 aData.mCbCrStride,
104 aStride,
105 yuvtype,
106 FILTER_BILINEAR);
107 } else
108 #endif
109 ScaleYCbCrToRGB32(aData.mYChannel, //
110 aData.mCbChannel,
111 aData.mCrChannel,
112 aDestBuffer,
113 aData.mPicSize.width,
114 aData.mPicSize.height,
115 aDestSize.width,
116 aDestSize.height,
117 aData.mYStride,
118 aData.mCbCrStride,
119 aStride,
120 yuvtype,
121 ROTATE_0,
122 FILTER_BILINEAR);
123 } else { // no prescale
124 #if defined(HAVE_YCBCR_TO_RGB565)
125 if (aDestFormat == SurfaceFormat::R5G6B5) {
126 ConvertYCbCrToRGB565(aData.mYChannel,
127 aData.mCbChannel,
128 aData.mCrChannel,
129 aDestBuffer,
130 aData.mPicX,
131 aData.mPicY,
132 aData.mPicSize.width,
133 aData.mPicSize.height,
134 aData.mYStride,
135 aData.mCbCrStride,
136 aStride,
137 yuvtype);
138 } else // aDestFormat != gfxImageFormat::RGB16_565
139 #endif
140 ConvertYCbCrToRGB32(aData.mYChannel, //
141 aData.mCbChannel,
142 aData.mCrChannel,
143 aDestBuffer,
144 aData.mPicX,
145 aData.mPicY,
146 aData.mPicSize.width,
147 aData.mPicSize.height,
148 aData.mYStride,
149 aData.mCbCrStride,
150 aStride,
151 yuvtype);