convert_yuv_to_rgb_c.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_B32_SHIFT    0
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_G32_SHIFT    8
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_R32_SHIFT    16
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define SK_A32_SHIFT    24
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void ConvertYUVToRGB32_C(uint8 y,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint8 u,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint8 v,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint8* rgb_buf) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int b = kCoefficientsRgbY[256+u][0];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int g = kCoefficientsRgbY[256+u][1];
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int r = kCoefficientsRgbY[256+u][2];
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int a = kCoefficientsRgbY[256+u][3];
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  b = paddsw(b, kCoefficientsRgbY[512+v][0]);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g = paddsw(g, kCoefficientsRgbY[512+v][1]);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r = paddsw(r, kCoefficientsRgbY[512+v][2]);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  a = paddsw(a, kCoefficientsRgbY[512+v][3]);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  b = paddsw(b, kCoefficientsRgbY[y][0]);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g = paddsw(g, kCoefficientsRgbY[y][1]);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r = paddsw(r, kCoefficientsRgbY[y][2]);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  a = paddsw(a, kCoefficientsRgbY[y][3]);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  b >>= 6;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g >>= 6;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r >>= 6;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  a >>= 6;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) |
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(g) << SK_G32_SHIFT) |
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(r) << SK_R32_SHIFT) |
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (packuswb(a) << SK_A32_SHIFT);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline void ConvertYUVAToARGB_C(uint8 y,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 u,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 v,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8 a,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       uint8* rgb_buf) {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int b = kCoefficientsRgbY[256+u][0];
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int g = kCoefficientsRgbY[256+u][1];
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int r = kCoefficientsRgbY[256+u][2];
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b = paddsw(b, kCoefficientsRgbY[512+v][0]);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g = paddsw(g, kCoefficientsRgbY[512+v][1]);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r = paddsw(r, kCoefficientsRgbY[512+v][2]);
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b = paddsw(b, kCoefficientsRgbY[y][0]);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g = paddsw(g, kCoefficientsRgbY[y][1]);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r = paddsw(r, kCoefficientsRgbY[y][2]);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b >>= 6;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g >>= 6;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r >>= 6;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  b = packuswb(b) * a >> 8;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g = packuswb(g) * a >> 8;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  r = packuswb(r) * a >> 8;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) |
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (g << SK_G32_SHIFT) |
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (r << SK_R32_SHIFT) |
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        (a << SK_A32_SHIFT);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertYUVToRGB32Row_C(const uint8* y_buf,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const uint8* u_buf,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const uint8* v_buf,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            uint8* rgb_buf,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            ptrdiff_t width) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int x = 0; x < width; x += 2) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 u = u_buf[x >> 1];
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 v = v_buf[x >> 1];
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 y0 = y_buf[x];
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertYUVToRGB32_C(y0, u, v, rgb_buf);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((x + 1) < width) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint8 y1 = y_buf[x + 1];
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;  // Advance 2 pixels.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ConvertYUVAToARGBRow_C(const uint8* y_buf,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* u_buf,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* v_buf,
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const uint8* a_buf,
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            uint8* rgba_buf,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            ptrdiff_t width) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int x = 0; x < width; x += 2) {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 u = u_buf[x >> 1];
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 v = v_buf[x >> 1];
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 y0 = y_buf[x];
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8 a0 = a_buf[x];
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if ((x + 1) < width) {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      uint8 y1 = y_buf[x + 1];
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      uint8 a1 = a_buf[x + 1];
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4);
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rgba_buf += 8;  // Advance 2 pixels.
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 16.16 fixed point is used.  A shift by 16 isolates the integer.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A shift by 17 is used to further subsample the chrominence channels.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// & 0xffff isolates the fixed point fraction.  >> 2 to get the upper 2 bits,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for 1/65536 pixel accurate interpolation.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScaleYUVToRGB32Row_C(const uint8* y_buf,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const uint8* u_buf,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const uint8* v_buf,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          uint8* rgb_buf,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ptrdiff_t width,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ptrdiff_t source_dx) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x = 0;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < width; i += 2) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y = y_buf[x >> 16];
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u = u_buf[(x >> 17)];
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v = v_buf[(x >> 17)];
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertYUVToRGB32_C(y, u, v, rgb_buf);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += source_dx;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((i + 1) < width) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = y_buf[x >> 16];
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x += source_dx;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const uint8* u_buf,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const uint8* v_buf,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                uint8* rgb_buf,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                ptrdiff_t width,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                ptrdiff_t source_dx) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid point-sampling for down-scaling by > 2:1.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int source_x = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (source_dx >= 0x20000)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    source_x += 0x8000;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      source_x, source_dx);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const uint8* u_buf,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const uint8* v_buf,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         uint8* rgb_buf,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int dest_width,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int x,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int source_dx) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < dest_width; i += 2) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y0 = y_buf[x >> 16];
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y1 = y_buf[(x >> 16) + 1];
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u0 = u_buf[(x >> 17)];
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u1 = u_buf[(x >> 17) + 1];
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v0 = v_buf[(x >> 17)];
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v1 = v_buf[(x >> 17) + 1];
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y_frac = (x & 65535);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int uv_frac = ((x >> 1) & 65535);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertYUVToRGB32_C(y, u, v, rgb_buf);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += source_dx;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((i + 1) < dest_width) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y0 = y_buf[x >> 16];
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y1 = y_buf[(x >> 16) + 1];
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y_frac = (x & 65535);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x += source_dx;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rgb_buf += 8;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertYUVToRGB32_C(const uint8* yplane,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const uint8* uplane,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const uint8* vplane,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         uint8* rgbframe,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int width,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int height,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int ystride,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int uvstride,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int rgbstride,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         YUVType yuv_type) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int y_shift = yuv_type;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int y = 0; y < height; ++y) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* rgb_row = rgbframe + y * rgbstride;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* y_ptr = yplane + y * ystride;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertYUVToRGB32Row_C(y_ptr,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           u_ptr,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           v_ptr,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           rgb_row,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           width);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ConvertYUVAToARGB_C(const uint8* yplane,
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* uplane,
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* vplane,
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const uint8* aplane,
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         uint8* rgbaframe,
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int width,
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int height,
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int ystride,
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int uvstride,
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int astride,
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int rgbastride,
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         YUVType yuv_type) {
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned int y_shift = yuv_type;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int y = 0; y < height; y++) {
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint8* rgba_row = rgbaframe + y * rgbastride;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* y_ptr = yplane + y * ystride;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const uint8* a_ptr = aplane + y * astride;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ConvertYUVAToARGBRow_C(y_ptr,
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           u_ptr,
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           v_ptr,
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           a_ptr,
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           rgba_row,
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           width);
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
258