15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/simd/convert_yuv_to_rgb.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/simd/yuv_to_rgb_table.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media {
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// On Android, pixel layout is RGBA (see skia/include/core/SkColorPriv.h);
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h).
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Ideally, android should not use the functions here due to performance issue
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// (http://crbug.com/249980).
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_R32_SHIFT    0
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_G32_SHIFT    8
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_B32_SHIFT    16
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_A32_SHIFT    24
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define R_INDEX         0
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define G_INDEX         1
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define B_INDEX         2
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define A_INDEX         3
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_B32_SHIFT    0
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_G32_SHIFT    8
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_R32_SHIFT    16
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_A32_SHIFT    24
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define B_INDEX         0
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define G_INDEX         1
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define R_INDEX         2
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define A_INDEX         3
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void ConvertYUVToRGB32_C(uint8 y,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint8 u,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint8 v,
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                       uint8* rgb_buf,
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                       const int16 convert_table[1024][4]) {
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int b = convert_table[256+u][B_INDEX];
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int g = convert_table[256+u][G_INDEX];
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int r = convert_table[256+u][R_INDEX];
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int a = convert_table[256+u][A_INDEX];
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  b = paddsw(b, convert_table[512+v][B_INDEX]);
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  g = paddsw(g, convert_table[512+v][G_INDEX]);
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  r = paddsw(r, convert_table[512+v][R_INDEX]);
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  a = paddsw(a, convert_table[512+v][A_INDEX]);
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  b = paddsw(b, convert_table[y][B_INDEX]);
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  g = paddsw(g, convert_table[y][G_INDEX]);
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  r = paddsw(r, convert_table[y][R_INDEX]);
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  a = paddsw(a, convert_table[y][A_INDEX]);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  b >>= 6;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g >>= 6;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r >>= 6;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  a >>= 6;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) |
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(g) << SK_G32_SHIFT) |
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(r) << SK_R32_SHIFT) |
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(a) << SK_A32_SHIFT);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline void ConvertYUVAToARGB_C(uint8 y,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 u,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 v,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 a,
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                       uint8* rgb_buf,
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                       const int16 convert_table[1024][4]) {
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int b = convert_table[256+u][0];
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int g = convert_table[256+u][1];
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int r = convert_table[256+u][2];
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  b = paddsw(b, convert_table[512+v][0]);
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  g = paddsw(g, convert_table[512+v][1]);
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  r = paddsw(r, convert_table[512+v][2]);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  b = paddsw(b, convert_table[y][0]);
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  g = paddsw(g, convert_table[y][1]);
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  r = paddsw(r, convert_table[y][2]);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b >>= 6;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g >>= 6;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r >>= 6;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b = packuswb(b) * a >> 8;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g = packuswb(g) * a >> 8;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r = packuswb(r) * a >> 8;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) |
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (g << SK_G32_SHIFT) |
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (r << SK_R32_SHIFT) |
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (a << SK_A32_SHIFT);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertYUVToRGB32Row_C(const uint8* y_buf,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const uint8* u_buf,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const uint8* v_buf,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            uint8* rgb_buf,
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            ptrdiff_t width,
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            const int16 convert_table[1024][4]) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int x = 0; x < width; x += 2) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 u = u_buf[x >> 1];
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 v = v_buf[x >> 1];
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 y0 = y_buf[x];
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((x + 1) < width) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint8 y1 = y_buf[x + 1];
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;  // Advance 2 pixels.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ConvertYUVAToARGBRow_C(const uint8* y_buf,
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* u_buf,
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* v_buf,
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* a_buf,
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            uint8* rgba_buf,
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            ptrdiff_t width,
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            const int16 convert_table[1024][4]) {
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int x = 0; x < width; x += 2) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 u = u_buf[x >> 1];
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 v = v_buf[x >> 1];
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 y0 = y_buf[x];
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 a0 = a_buf[x];
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table);
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if ((x + 1) < width) {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      uint8 y1 = y_buf[x + 1];
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      uint8 a1 = a_buf[x + 1];
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table);
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rgba_buf += 8;  // Advance 2 pixels.
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 16.16 fixed point is used.  A shift by 16 isolates the integer.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A shift by 17 is used to further subsample the chrominence channels.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// & 0xffff isolates the fixed point fraction.  >> 2 to get the upper 2 bits,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for 1/65536 pixel accurate interpolation.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScaleYUVToRGB32Row_C(const uint8* y_buf,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const uint8* u_buf,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const uint8* v_buf,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          uint8* rgb_buf,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ptrdiff_t width,
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          ptrdiff_t source_dx,
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          const int16 convert_table[1024][4]) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x = 0;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < width; i += 2) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y = y_buf[x >> 16];
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u = u_buf[(x >> 17)];
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v = v_buf[(x >> 17)];
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += source_dx;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((i + 1) < width) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = y_buf[x >> 16];
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x += source_dx;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const uint8* u_buf,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const uint8* v_buf,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                uint8* rgb_buf,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                ptrdiff_t width,
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                ptrdiff_t source_dx,
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                const int16 convert_table[1024][4]) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid point-sampling for down-scaling by > 2:1.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int source_x = 0;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (source_dx >= 0x20000)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    source_x += 0x8000;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                      source_x, source_dx, convert_table);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const uint8* u_buf,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const uint8* v_buf,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         uint8* rgb_buf,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int dest_width,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int x,
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                         int source_dx,
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                         const int16 convert_table[1024][4]) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < dest_width; i += 2) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y0 = y_buf[x >> 16];
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y1 = y_buf[(x >> 16) + 1];
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u0 = u_buf[(x >> 17)];
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u1 = u_buf[(x >> 17) + 1];
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v0 = v_buf[(x >> 17)];
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v1 = v_buf[(x >> 17) + 1];
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y_frac = (x & 65535);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int uv_frac = ((x >> 1) & 65535);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += source_dx;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((i + 1) < dest_width) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y0 = y_buf[x >> 16];
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y1 = y_buf[(x >> 16) + 1];
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y_frac = (x & 65535);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x += source_dx;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertYUVToRGB32_C(const uint8* yplane,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const uint8* uplane,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const uint8* vplane,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         uint8* rgbframe,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int width,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int height,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int ystride,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int uvstride,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int rgbstride,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         YUVType yuv_type) {
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  unsigned int y_shift = GetVerticalShift(yuv_type);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int y = 0; y < height; ++y) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* rgb_row = rgbframe + y * rgbstride;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* y_ptr = yplane + y * ystride;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertYUVToRGB32Row_C(y_ptr,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           u_ptr,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           v_ptr,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           rgb_row,
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           width,
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           GetLookupTable(yuv_type));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ConvertYUVAToARGB_C(const uint8* yplane,
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* uplane,
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* vplane,
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* aplane,
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         uint8* rgbaframe,
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int width,
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int height,
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int ystride,
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int uvstride,
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int astride,
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int rgbastride,
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         YUVType yuv_type) {
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned int y_shift = yuv_type;
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int y = 0; y < height; y++) {
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8* rgba_row = rgbaframe + y * rgbastride;
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* y_ptr = yplane + y * ystride;
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* a_ptr = aplane + y * astride;
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ConvertYUVAToARGBRow_C(y_ptr,
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           u_ptr,
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           v_ptr,
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           a_ptr,
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           rgba_row,
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           width,
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           GetLookupTable(yuv_type));
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
275