1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/ycbcr/yuv_row_c.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,133 @@ 1.4 +// Copyright (c) 2010 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "yuv_row.h" 1.9 + 1.10 +#define DCHECK(a) 1.11 + 1.12 +extern "C" { 1.13 + 1.14 +// C reference code that mimic the YUV assembly. 1.15 +#define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) 1.16 +#define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ 1.17 + (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) 1.18 + 1.19 +static inline void YuvPixel(uint8 y, 1.20 + uint8 u, 1.21 + uint8 v, 1.22 + uint8* rgb_buf) { 1.23 + 1.24 + int b = kCoefficientsRgbY[256+u][0]; 1.25 + int g = kCoefficientsRgbY[256+u][1]; 1.26 + int r = kCoefficientsRgbY[256+u][2]; 1.27 + int a = kCoefficientsRgbY[256+u][3]; 1.28 + 1.29 + b = paddsw(b, kCoefficientsRgbY[512+v][0]); 1.30 + g = paddsw(g, kCoefficientsRgbY[512+v][1]); 1.31 + r = paddsw(r, kCoefficientsRgbY[512+v][2]); 1.32 + a = paddsw(a, kCoefficientsRgbY[512+v][3]); 1.33 + 1.34 + b = paddsw(b, kCoefficientsRgbY[y][0]); 1.35 + g = paddsw(g, kCoefficientsRgbY[y][1]); 1.36 + r = paddsw(r, kCoefficientsRgbY[y][2]); 1.37 + a = paddsw(a, kCoefficientsRgbY[y][3]); 1.38 + 1.39 + b >>= 6; 1.40 + g >>= 6; 1.41 + r >>= 6; 1.42 + a >>= 6; 1.43 + 1.44 + *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b)) | 1.45 + (packuswb(g) << 8) | 1.46 + (packuswb(r) << 16) | 1.47 + (packuswb(a) << 24); 1.48 +} 1.49 + 1.50 +void FastConvertYUVToRGB32Row_C(const uint8* y_buf, 1.51 + const uint8* u_buf, 1.52 + const uint8* v_buf, 1.53 + uint8* rgb_buf, 1.54 + int width, 1.55 + unsigned int x_shift) { 1.56 + for (int x = 0; x < width; x += 2) { 1.57 + uint8 u = u_buf[x >> x_shift]; 1.58 + uint8 v = v_buf[x >> x_shift]; 1.59 + uint8 y0 = y_buf[x]; 1.60 + YuvPixel(y0, u, v, rgb_buf); 1.61 + if ((x + 1) < width) { 1.62 + uint8 y1 = y_buf[x + 1]; 1.63 + if (x_shift == 0) { 1.64 + u = u_buf[x + 1]; 1.65 + v = v_buf[x + 1]; 1.66 + } 1.67 + YuvPixel(y1, u, v, rgb_buf + 4); 1.68 + } 1.69 + rgb_buf += 8; // Advance 2 pixels. 1.70 + } 1.71 +} 1.72 + 1.73 +// 16.16 fixed point is used. A shift by 16 isolates the integer. 1.74 +// A shift by 17 is used to further subsample the chrominence channels. 1.75 +// & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, 1.76 +// for 1/65536 pixel accurate interpolation. 1.77 +void ScaleYUVToRGB32Row_C(const uint8* y_buf, 1.78 + const uint8* u_buf, 1.79 + const uint8* v_buf, 1.80 + uint8* rgb_buf, 1.81 + int width, 1.82 + int source_dx) { 1.83 + int x = 0; 1.84 + for (int i = 0; i < width; i += 2) { 1.85 + int y = y_buf[x >> 16]; 1.86 + int u = u_buf[(x >> 17)]; 1.87 + int v = v_buf[(x >> 17)]; 1.88 + YuvPixel(y, u, v, rgb_buf); 1.89 + x += source_dx; 1.90 + if ((i + 1) < width) { 1.91 + y = y_buf[x >> 16]; 1.92 + YuvPixel(y, u, v, rgb_buf+4); 1.93 + x += source_dx; 1.94 + } 1.95 + rgb_buf += 8; 1.96 + } 1.97 +} 1.98 + 1.99 +void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, 1.100 + const uint8* u_buf, 1.101 + const uint8* v_buf, 1.102 + uint8* rgb_buf, 1.103 + int width, 1.104 + int source_dx) { 1.105 + int x = 0; 1.106 + if (source_dx >= 0x20000) { 1.107 + x = 32768; 1.108 + } 1.109 + for (int i = 0; i < width; i += 2) { 1.110 + int y0 = y_buf[x >> 16]; 1.111 + int y1 = y_buf[(x >> 16) + 1]; 1.112 + int u0 = u_buf[(x >> 17)]; 1.113 + int u1 = u_buf[(x >> 17) + 1]; 1.114 + int v0 = v_buf[(x >> 17)]; 1.115 + int v1 = v_buf[(x >> 17) + 1]; 1.116 + int y_frac = (x & 65535); 1.117 + int uv_frac = ((x >> 1) & 65535); 1.118 + int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 1.119 + int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16; 1.120 + int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16; 1.121 + YuvPixel(y, u, v, rgb_buf); 1.122 + x += source_dx; 1.123 + if ((i + 1) < width) { 1.124 + y0 = y_buf[x >> 16]; 1.125 + y1 = y_buf[(x >> 16) + 1]; 1.126 + y_frac = (x & 65535); 1.127 + y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 1.128 + YuvPixel(y, u, v, rgb_buf+4); 1.129 + x += source_dx; 1.130 + } 1.131 + rgb_buf += 8; 1.132 + } 1.133 +} 1.134 + 1.135 +} // extern "C" 1.136 +