1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
11 // C reference code that mimic the YUV assembly.
12 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
13 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
14 (((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
16 static inline void YuvPixel(uint8 y
,
21 int b
= kCoefficientsRgbY
[256+u
][0];
22 int g
= kCoefficientsRgbY
[256+u
][1];
23 int r
= kCoefficientsRgbY
[256+u
][2];
24 int a
= kCoefficientsRgbY
[256+u
][3];
26 b
= paddsw(b
, kCoefficientsRgbY
[512+v
][0]);
27 g
= paddsw(g
, kCoefficientsRgbY
[512+v
][1]);
28 r
= paddsw(r
, kCoefficientsRgbY
[512+v
][2]);
29 a
= paddsw(a
, kCoefficientsRgbY
[512+v
][3]);
31 b
= paddsw(b
, kCoefficientsRgbY
[y
][0]);
32 g
= paddsw(g
, kCoefficientsRgbY
[y
][1]);
33 r
= paddsw(r
, kCoefficientsRgbY
[y
][2]);
34 a
= paddsw(a
, kCoefficientsRgbY
[y
][3]);
41 *reinterpret_cast<uint32
*>(rgb_buf
) = (packuswb(b
)) |
47 void FastConvertYUVToRGB32Row_C(const uint8
* y_buf
,
52 unsigned int x_shift
) {
53 for (int x
= 0; x
< width
; x
+= 2) {
54 uint8 u
= u_buf
[x
>> x_shift
];
55 uint8 v
= v_buf
[x
>> x_shift
];
57 YuvPixel(y0
, u
, v
, rgb_buf
);
58 if ((x
+ 1) < width
) {
59 uint8 y1
= y_buf
[x
+ 1];
64 YuvPixel(y1
, u
, v
, rgb_buf
+ 4);
66 rgb_buf
+= 8; // Advance 2 pixels.
70 // 16.16 fixed point is used. A shift by 16 isolates the integer.
71 // A shift by 17 is used to further subsample the chrominence channels.
72 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits,
73 // for 1/65536 pixel accurate interpolation.
74 void ScaleYUVToRGB32Row_C(const uint8
* y_buf
,
81 for (int i
= 0; i
< width
; i
+= 2) {
82 int y
= y_buf
[x
>> 16];
83 int u
= u_buf
[(x
>> 17)];
84 int v
= v_buf
[(x
>> 17)];
85 YuvPixel(y
, u
, v
, rgb_buf
);
87 if ((i
+ 1) < width
) {
89 YuvPixel(y
, u
, v
, rgb_buf
+4);
96 void LinearScaleYUVToRGB32Row_C(const uint8
* y_buf
,
103 if (source_dx
>= 0x20000) {
106 for (int i
= 0; i
< width
; i
+= 2) {
107 int y0
= y_buf
[x
>> 16];
108 int y1
= y_buf
[(x
>> 16) + 1];
109 int u0
= u_buf
[(x
>> 17)];
110 int u1
= u_buf
[(x
>> 17) + 1];
111 int v0
= v_buf
[(x
>> 17)];
112 int v1
= v_buf
[(x
>> 17) + 1];
113 int y_frac
= (x
& 65535);
114 int uv_frac
= ((x
>> 1) & 65535);
115 int y
= (y_frac
* y1
+ (y_frac
^ 65535) * y0
) >> 16;
116 int u
= (uv_frac
* u1
+ (uv_frac
^ 65535) * u0
) >> 16;
117 int v
= (uv_frac
* v1
+ (uv_frac
^ 65535) * v0
) >> 16;
118 YuvPixel(y
, u
, v
, rgb_buf
);
120 if ((i
+ 1) < width
) {
122 y1
= y_buf
[(x
>> 16) + 1];
123 y_frac
= (x
& 65535);
124 y
= (y_frac
* y1
+ (y_frac
^ 65535) * y0
) >> 16;
125 YuvPixel(y
, u
, v
, rgb_buf
+4);