1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/*
2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *
4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  in the file PATENTS. All contributing project authors may
8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */
10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h"
12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <string.h>  // For memcpy and memset.
14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/basic_types.h"
16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus
18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv {
19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" {
20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// llvm x86 is poor at ternary operator, so use branchless min/max.
23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define USE_BRANCHLESS 1
25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if USE_BRANCHLESS
26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int32 clamp0(int32 v) {
27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return ((-(v) >> 31) & (v));
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int32 clamp255(int32 v) {
31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (((255 - (v)) >> 31) | (v)) & 255;
32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline uint32 Clamp(int32 val) {
35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int v = clamp0(val);
36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (uint32)(clamp255(v));
37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline uint32 Abs(int32 v) {
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int m = v >> 31;
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (v + m) ^ m;
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else  // USE_BRANCHLESS
44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int32 clamp0(int32 v) {
45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (v < 0) ? 0 : v;
46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int32 clamp255(int32 v) {
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (v > 255) ? 255 : v;
50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline uint32 Clamp(int32 val) {
53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int v = clamp0(val);
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (uint32)(clamp255(v));
55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline uint32 Abs(int32 v) {
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (v < 0) ? -v : v;
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif  // USE_BRANCHLESS
61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef LIBYUV_LITTLE_ENDIAN
63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define WRITEWORD(p, v) *(uint32*)(p) = v
64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else
65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic inline void WRITEWORD(uint8* p, uint32 v) {
66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  p[0] = (uint8)(v & 255);
67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  p[1] = (uint8)((v >> 8) & 255);
68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  p[2] = (uint8)((v >> 16) & 255);
69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  p[3] = (uint8)((v >> 24) & 255);
70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width) {
74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_rgb24[0];
77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_rgb24[1];
78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_rgb24[2];
79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = b;
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = g;
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = r;
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb24 += 3;
85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width) {
89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_raw[0];
92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_raw[1];
93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_raw[2];
94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = b;
95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = g;
96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = r;
97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_raw += 3;
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1037bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid RAWToRGB24Row_C(const uint8* src_raw, uint8* dst_rgb24, int width) {
1047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int x;
1057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < width; ++x) {
1067bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 r = src_raw[0];
1077bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 g = src_raw[1];
1087bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 b = src_raw[2];
1097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_rgb24[0] = b;
1107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_rgb24[1] = g;
1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_rgb24[2] = r;
1127bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_rgb24 += 3;
1137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_raw += 3;
1147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1157bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
1167bc9febe8749e98a3812a0dc4380ceae75c29450Johann
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RGB565ToARGBRow_C(const uint8* src_rgb565, uint8* dst_argb, int width) {
118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_rgb565[0] & 0x1f;
121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_rgb565[1] >> 3;
123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (b << 3) | (b >> 2);
124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (g << 2) | (g >> 4);
125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (r << 3) | (r >> 2);
126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb565 += 2;
129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB1555ToARGBRow_C(const uint8* src_argb1555, uint8* dst_argb,
133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int width) {
134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb1555[0] & 0x1f;
137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (src_argb1555[1] & 0x7c) >> 2;
139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a = src_argb1555[1] >> 7;
140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (b << 3) | (b >> 2);
141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (g << 3) | (g >> 2);
142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (r << 3) | (r >> 2);
143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = -a;
144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1555 += 2;
146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB4444ToARGBRow_C(const uint8* src_argb4444, uint8* dst_argb,
150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int width) {
151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb4444[0] & 0x0f;
154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_argb4444[0] >> 4;
155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_argb4444[1] & 0x0f;
156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a = src_argb4444[1] >> 4;
157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (b << 4) | b;
158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (g << 4) | g;
159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (r << 4) | r;
160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (a << 4) | a;
161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb4444 += 2;
163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb[0];
170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_argb[1];
171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_argb[2];
172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[0] = b;
173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[1] = g;
174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[2] = r;
175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb += 3;
176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width) {
181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb[0];
184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_argb[1];
185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_argb[2];
186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[0] = r;
187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[1] = g;
188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb[2] = b;
189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb += 3;
190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 3;
198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 2;
199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 3;
200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_argb[4] >> 3;
201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = src_argb[5] >> 2;
202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = src_argb[6] >> 3;
203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) |
204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              (b1 << 16) | (g1 << 21) | (r1 << 27));
205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb += 4;
206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 3;
210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 2;
211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 3;
212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11);
213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
216da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// dither4 is a row of 4 values from 4x4 dither matrix.
217da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// The 4x4 matrix contains values to increase RGB.  When converting to
218da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// fewer bits (565) this provides an ordered dither.
219da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// The order in the 4x4 matrix in first byte is upper left.
220da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// The 4 values are passed as an int, then referenced as an array, so
221da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// endian will not affect order of the original matrix.  But the dither4
222da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// will containing the first pixel in the lower byte for little endian
223da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// or the upper byte for big endian.
224da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid ARGBToRGB565DitherRow_C(const uint8* src_argb, uint8* dst_rgb,
225da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             const uint32 dither4, int width) {
226da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  int x;
227da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
228da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int dither0 = ((const unsigned char*)(&dither4))[x & 3];
229da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int dither1 = ((const unsigned char*)(&dither4))[(x + 1) & 3];
230da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 b0 = clamp255(src_argb[0] + dither0) >> 3;
231da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 g0 = clamp255(src_argb[1] + dither0) >> 2;
232da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 r0 = clamp255(src_argb[2] + dither0) >> 3;
233da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 b1 = clamp255(src_argb[4] + dither1) >> 3;
234da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 g1 = clamp255(src_argb[5] + dither1) >> 2;
235da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 r1 = clamp255(src_argb[6] + dither1) >> 3;
236da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) |
237da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian              (b1 << 16) | (g1 << 21) | (r1 << 27));
238da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb += 4;
239da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_argb += 8;
240da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
241da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (width & 1) {
242da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int dither0 = ((const unsigned char*)(&dither4))[(width - 1) & 3];
243da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 b0 = clamp255(src_argb[0] + dither0) >> 3;
244da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 g0 = clamp255(src_argb[1] + dither0) >> 2;
245da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    uint8 r0 = clamp255(src_argb[2] + dither0) >> 3;
246da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11);
247da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
248da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
249da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 3;
254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 3;
255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 3;
256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = src_argb[3] >> 7;
257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_argb[4] >> 3;
258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = src_argb[5] >> 3;
259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = src_argb[6] >> 3;
260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a1 = src_argb[7] >> 7;
261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_rgb) =
262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) |
263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31);
264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb += 4;
265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 3;
269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 3;
270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 3;
271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = src_argb[3] >> 7;
272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_rgb) =
273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        b0 | (g0 << 5) | (r0 << 10) | (a0 << 15);
274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 4;
281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 4;
282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 4;
283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = src_argb[3] >> 4;
284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_argb[4] >> 4;
285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = src_argb[5] >> 4;
286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = src_argb[6] >> 4;
287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a1 = src_argb[7] >> 4;
288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_rgb) =
289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) |
290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 20) | (r1 << 24) | (a1 << 28);
291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb += 4;
292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb[0] >> 4;
296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb[1] >> 4;
297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb[2] >> 4;
298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = src_argb[3] >> 4;
299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_rgb) =
300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        b0 | (g0 << 4) | (r0 << 8) | (a0 << 12);
301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToY(uint8 r, uint8 g, uint8 b) {
305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (66 * r + 129 * g +  25 * b + 0x1080) >> 8;
306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToU(uint8 r, uint8 g, uint8 b) {
309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (112 * b - 74 * g - 38 * r + 0x8080) >> 8;
310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToV(uint8 r, uint8 g, uint8 b) {
312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (112 * r - 94 * g - 18 * b + 0x8080) >> 8;
313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define MAKEROWY(NAME, R, G, B, BPP) \
316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NAME ## ToYRow_C(const uint8* src_argb0, uint8* dst_y, int width) {       \
317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;                                                                       \
318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {                                                \
319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]);               \
320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += BPP;                                                          \
321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y += 1;                                                                \
322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}                                                                              \
324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NAME ## ToUVRow_C(const uint8* src_rgb0, int src_stride_rgb,              \
325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_u, uint8* dst_v, int width) {                \
326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* src_rgb1 = src_rgb0 + src_stride_rgb;                           \
327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;                                                                       \
328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {                                         \
329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = (src_rgb0[B] + src_rgb0[B + BPP] +                              \
330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian               src_rgb1[B] + src_rgb1[B + BPP]) >> 2;                          \
331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = (src_rgb0[G] + src_rgb0[G + BPP] +                              \
332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian               src_rgb1[G] + src_rgb1[G + BPP]) >> 2;                          \
333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = (src_rgb0[R] + src_rgb0[R + BPP] +                              \
334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian               src_rgb1[R] + src_rgb1[R + BPP]) >> 2;                          \
335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);                                             \
336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);                                             \
337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb0 += BPP * 2;                                                       \
338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb1 += BPP * 2;                                                       \
339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;                                                                \
340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;                                                                \
341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {                                                             \
343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = (src_rgb0[B] + src_rgb1[B]) >> 1;                               \
344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = (src_rgb0[G] + src_rgb1[G]) >> 1;                               \
345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = (src_rgb0[R] + src_rgb1[R]) >> 1;                               \
346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);                                             \
347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);                                             \
348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(ARGB, 2, 1, 0, 4)
352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(BGRA, 1, 2, 3, 4)
353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(ABGR, 0, 1, 2, 4)
354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(RGBA, 3, 2, 1, 4)
355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(RGB24, 2, 1, 0, 3)
356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWY(RAW, 0, 1, 2, 3)
357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef MAKEROWY
358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// JPeg uses a variation on BT.601-1 full range
360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// y =  0.29900 * r + 0.58700 * g + 0.11400 * b
361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// u = -0.16874 * r - 0.33126 * g + 0.50000 * b  + center
362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// v =  0.50000 * r - 0.41869 * g - 0.08131 * b  + center
363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// BT.601 Mpeg range uses:
364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b 0.1016 * 255 = 25.908 = 25
365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g 0.5078 * 255 = 129.489 = 129
366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r 0.2578 * 255 = 65.739 = 66
367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// JPeg 8 bit Y (not used):
368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b 0.11400 * 256 = 29.184 = 29
369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g 0.58700 * 256 = 150.272 = 150
370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r 0.29900 * 256 = 76.544 = 77
371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// JPeg 7 bit Y:
372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b 0.11400 * 128 = 14.592 = 15
373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g 0.58700 * 128 = 75.136 = 75
374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r 0.29900 * 128 = 38.272 = 38
375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// JPeg 8 bit U:
376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b  0.50000 * 255 = 127.5 = 127
377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g -0.33126 * 255 = -84.4713 = -84
378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r -0.16874 * 255 = -43.0287 = -43
379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// JPeg 8 bit V:
380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b -0.08131 * 255 = -20.73405 = -20
381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g -0.41869 * 255 = -106.76595 = -107
382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r  0.50000 * 255 = 127.5 = 127
383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToYJ(uint8 r, uint8 g, uint8 b) {
385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (38 * r + 75 * g +  15 * b + 64) >> 7;
386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToUJ(uint8 r, uint8 g, uint8 b) {
389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (127 * b - 84 * g - 43 * r + 0x8080) >> 8;
390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int RGBToVJ(uint8 r, uint8 g, uint8 b) {
392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (127 * r - 107 * g - 20 * b + 0x8080) >> 8;
393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define AVGB(a, b) (((a) + (b) + 1) >> 1)
396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define MAKEROWYJ(NAME, R, G, B, BPP) \
398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NAME ## ToYJRow_C(const uint8* src_argb0, uint8* dst_y, int width) {      \
399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;                                                                       \
400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {                                                \
401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]);              \
402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += BPP;                                                          \
403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y += 1;                                                                \
404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}                                                                              \
406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NAME ## ToUVJRow_C(const uint8* src_rgb0, int src_stride_rgb,             \
407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        uint8* dst_u, uint8* dst_v, int width) {               \
408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* src_rgb1 = src_rgb0 + src_stride_rgb;                           \
409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;                                                                       \
410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {                                         \
411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]),                            \
412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP]));               \
413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]),                            \
414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP]));               \
415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]),                            \
416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP]));               \
417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToUJ(ar, ag, ab);                                            \
418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToVJ(ar, ag, ab);                                            \
419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb0 += BPP * 2;                                                       \
420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb1 += BPP * 2;                                                       \
421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;                                                                \
422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;                                                                \
423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {                                                             \
425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = AVGB(src_rgb0[B], src_rgb1[B]);                                 \
426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = AVGB(src_rgb0[G], src_rgb1[G]);                                 \
427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = AVGB(src_rgb0[R], src_rgb1[R]);                                 \
428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToUJ(ar, ag, ab);                                            \
429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToVJ(ar, ag, ab);                                            \
430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }                                                                            \
431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMAKEROWYJ(ARGB, 2, 1, 0, 4)
434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef MAKEROWYJ
435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RGB565ToYRow_C(const uint8* src_rgb565, uint8* dst_y, int width) {
437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_rgb565[0] & 0x1f;
440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_rgb565[1] >> 3;
442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 3) | (b >> 2);
443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 2) | (g >> 4);
444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 3) | (r >> 2);
445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[0] = RGBToY(r, g, b);
446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb565 += 2;
447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y += 1;
448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB1555ToYRow_C(const uint8* src_argb1555, uint8* dst_y, int width) {
452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb1555[0] & 0x1f;
455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (src_argb1555[1] & 0x7c) >> 2;
457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 3) | (b >> 2);
458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 3) | (g >> 2);
459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 3) | (r >> 2);
460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[0] = RGBToY(r, g, b);
461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1555 += 2;
462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y += 1;
463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB4444ToYRow_C(const uint8* src_argb4444, uint8* dst_y, int width) {
467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb4444[0] & 0x0f;
470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_argb4444[0] >> 4;
471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_argb4444[1] & 0x0f;
472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 4) | b;
473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 4) | g;
474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 4) | r;
475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[0] = RGBToY(r, g, b);
476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb4444 += 2;
477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y += 1;
478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RGB565ToUVRow_C(const uint8* src_rgb565, int src_stride_rgb565,
482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst_u, uint8* dst_v, int width) {
483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* next_rgb565 = src_rgb565 + src_stride_rgb565;
484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_rgb565[0] & 0x1f;
487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_rgb565[1] >> 3;
489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_rgb565[2] & 0x1f;
490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = (src_rgb565[2] >> 5) | ((src_rgb565[3] & 0x07) << 3);
491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = src_rgb565[3] >> 3;
492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_rgb565[0] & 0x1f;
493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3);
494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = next_rgb565[1] >> 3;
495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b3 = next_rgb565[2] & 0x1f;
496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3);
497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r3 = next_rgb565[3] >> 3;
498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b1 + b2 + b3);  // 565 * 4 = 787.
499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g1 + g2 + g3);
500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r1 + r2 + r3);
501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 1) | (b >> 6);  // 787 -> 888.
502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 1) | (r >> 6);
503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_rgb565 += 4;
506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    next_rgb565 += 4;
507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_rgb565[0] & 0x1f;
512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3);
513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_rgb565[1] >> 3;
514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_rgb565[0] & 0x1f;
515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3);
516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = next_rgb565[1] >> 3;
517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b2);  // 565 * 2 = 676.
518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g2);
519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r2);
520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 2) | (b >> 4);  // 676 -> 888
521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 1) | (g >> 6);
522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 2) | (r >> 4);
523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB1555ToUVRow_C(const uint8* src_argb1555, int src_stride_argb1555,
529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_u, uint8* dst_v, int width) {
530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* next_argb1555 = src_argb1555 + src_stride_argb1555;
531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb1555[0] & 0x1f;
534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = (src_argb1555[1] & 0x7c) >> 2;
536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_argb1555[2] & 0x1f;
537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = (src_argb1555[2] >> 5) | ((src_argb1555[3] & 0x03) << 3);
538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = (src_argb1555[3] & 0x7c) >> 2;
539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_argb1555[0] & 0x1f;
540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3);
541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = (next_argb1555[1] & 0x7c) >> 2;
542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b3 = next_argb1555[2] & 0x1f;
543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3);
544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r3 = (next_argb1555[3] & 0x7c) >> 2;
545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b1 + b2 + b3);  // 555 * 4 = 777.
546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g1 + g2 + g3);
547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r1 + r2 + r3);
548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 1) | (b >> 6);  // 777 -> 888.
549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 1) | (g >> 6);
550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 1) | (r >> 6);
551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1555 += 4;
554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    next_argb1555 += 4;
555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb1555[0] & 0x1f;
560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3);
561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = (src_argb1555[1] & 0x7c) >> 2;
562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_argb1555[0] & 0x1f;
563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3);
564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = next_argb1555[1] >> 3;
565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b2);  // 555 * 2 = 666.
566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g2);
567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r2);
568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 2) | (b >> 4);  // 666 -> 888.
569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 2) | (g >> 4);
570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 2) | (r >> 4);
571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGB4444ToUVRow_C(const uint8* src_argb4444, int src_stride_argb4444,
577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_u, uint8* dst_v, int width) {
578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* next_argb4444 = src_argb4444 + src_stride_argb4444;
579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb4444[0] & 0x0f;
582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb4444[0] >> 4;
583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb4444[1] & 0x0f;
584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = src_argb4444[2] & 0x0f;
585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g1 = src_argb4444[2] >> 4;
586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r1 = src_argb4444[3] & 0x0f;
587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_argb4444[0] & 0x0f;
588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = next_argb4444[0] >> 4;
589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = next_argb4444[1] & 0x0f;
590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b3 = next_argb4444[2] & 0x0f;
591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g3 = next_argb4444[2] >> 4;
592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r3 = next_argb4444[3] & 0x0f;
593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b1 + b2 + b3);  // 444 * 4 = 666.
594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g1 + g2 + g3);
595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r1 + r2 + r3);
596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 2) | (b >> 4);  // 666 -> 888.
597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 2) | (g >> 4);
598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 2) | (r >> 4);
599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb4444 += 4;
602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    next_argb4444 += 4;
603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = src_argb4444[0] & 0x0f;
608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g0 = src_argb4444[0] >> 4;
609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r0 = src_argb4444[1] & 0x0f;
610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = next_argb4444[0] & 0x0f;
611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g2 = next_argb4444[0] >> 4;
612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r2 = next_argb4444[1] & 0x0f;
613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = (b0 + b2);  // 444 * 2 = 555.
614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = (g0 + g2);
615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = (r0 + r2);
616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b << 3) | (b >> 2);  // 555 -> 888.
617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g << 3) | (g >> 2);
618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r << 3) | (r >> 2);
619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(r, g, b);
620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(r, g, b);
621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToUV444Row_C(const uint8* src_argb,
625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst_u, uint8* dst_v, int width) {
626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = src_argb[0];
629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = src_argb[1];
630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = src_argb[2];
631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);
632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);
633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBToUV411Row_C(const uint8* src_argb,
640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst_u, uint8* dst_v, int width) {
641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 3; x += 4) {
643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8] + src_argb[12]) >> 2;
644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9] + src_argb[13]) >> 2;
645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10] + src_argb[14]) >> 2;
646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);
647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);
648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 16;
649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
6527bc9febe8749e98a3812a0dc4380ceae75c29450Johann  // Odd width handling mimics 'any' function which replicates last pixel.
653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if ((width & 3) == 3) {
6547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8] + src_argb[8]) >> 2;
6557bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9] + src_argb[9]) >> 2;
6567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10] + src_argb[10]) >> 2;
657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);
658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);
659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else if ((width & 3) == 2) {
660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = (src_argb[0] + src_argb[4]) >> 1;
661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = (src_argb[1] + src_argb[5]) >> 1;
662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = (src_argb[2] + src_argb[6]) >> 1;
663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);
664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);
665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else if ((width & 3) == 1) {
666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ab = src_argb[0];
667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ag = src_argb[1];
668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 ar = src_argb[2];
669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = RGBToU(ar, ag, ab);
670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = RGBToV(ar, ag, ab);
671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 y = RGBToYJ(src_argb[2], src_argb[1], src_argb[0]);
678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = src_argb[3];
680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert a row of image to Sepia tone.
686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBSepiaRow_C(uint8* dst_argb, int width) {
687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = dst_argb[0];
690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = dst_argb[1];
691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = dst_argb[2];
692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sb = (b * 17 + g * 68 + r * 35) >> 7;
693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sg = (b * 22 + g * 88 + r * 45) >> 7;
694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sr = (b * 24 + g * 98 + r * 50) >> 7;
695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // b does not over flow. a is preserved from original.
696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = sb;
697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = clamp255(sg);
698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = clamp255(sr);
699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply color matrix to a row of image. Matrix is signed.
704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// TODO(fbarchard): Consider adding rounding (+32).
705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBColorMatrixRow_C(const uint8* src_argb, uint8* dst_argb,
706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                          const int8* matrix_argb, int width) {
707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_argb[0];
710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = src_argb[1];
711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = src_argb[2];
712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_argb[3];
713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sb = (b * matrix_argb[0] + g * matrix_argb[1] +
714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              r * matrix_argb[2] + a * matrix_argb[3]) >> 6;
715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sg = (b * matrix_argb[4] + g * matrix_argb[5] +
716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              r * matrix_argb[6] + a * matrix_argb[7]) >> 6;
717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sr = (b * matrix_argb[8] + g * matrix_argb[9] +
718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              r * matrix_argb[10] + a * matrix_argb[11]) >> 6;
719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sa = (b * matrix_argb[12] + g * matrix_argb[13] +
720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              r * matrix_argb[14] + a * matrix_argb[15]) >> 6;
721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = Clamp(sb);
722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = Clamp(sg);
723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = Clamp(sr);
724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = Clamp(sa);
725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply color table to a row of image.
731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = dst_argb[0];
735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = dst_argb[1];
736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = dst_argb[2];
737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = dst_argb[3];
738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = table_argb[b * 4 + 0];
739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = table_argb[g * 4 + 1];
740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = table_argb[r * 4 + 2];
741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = table_argb[a * 4 + 3];
742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply color table to a row of image.
747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = dst_argb[0];
751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = dst_argb[1];
752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = dst_argb[2];
753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = table_argb[b * 4 + 0];
754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = table_argb[g * 4 + 1];
755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = table_argb[r * 4 + 2];
756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int interval_offset, int width) {
762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = dst_argb[0];
765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = dst_argb[1];
766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = dst_argb[2];
767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset;
768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (g * scale >> 16) * interval_size + interval_offset;
769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (r * scale >> 16) * interval_size + interval_offset;
770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define REPEAT8(v) (v) | ((v) << 8)
775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define SHADE(f, v) v * f >> 24
776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBShadeRow_C(const uint8* src_argb, uint8* dst_argb, int width,
778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    uint32 value) {
779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32 b_scale = REPEAT8(value & 0xff);
780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32 g_scale = REPEAT8((value >> 8) & 0xff);
781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32 r_scale = REPEAT8((value >> 16) & 0xff);
782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32 a_scale = REPEAT8(value >> 24);
783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 b = REPEAT8(src_argb[0]);
787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 g = REPEAT8(src_argb[1]);
788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 r = REPEAT8(src_argb[2]);
789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 a = REPEAT8(src_argb[3]);
790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = SHADE(b, b_scale);
791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = SHADE(g, g_scale);
792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = SHADE(r, r_scale);
793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = SHADE(a, a_scale);
794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef REPEAT8
799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef SHADE
800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define REPEAT8(v) (v) | ((v) << 8)
802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define SHADE(f, v) v * f >> 16
803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBMultiplyRow_C(const uint8* src_argb0, const uint8* src_argb1,
805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_argb, int width) {
806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 b = REPEAT8(src_argb0[0]);
809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 g = REPEAT8(src_argb0[1]);
810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 r = REPEAT8(src_argb0[2]);
811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 a = REPEAT8(src_argb0[3]);
812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 b_scale = src_argb1[0];
813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 g_scale = src_argb1[1];
814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 r_scale = src_argb1[2];
815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 a_scale = src_argb1[3];
816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = SHADE(b, b_scale);
817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = SHADE(g, g_scale);
818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = SHADE(r, r_scale);
819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = SHADE(a, a_scale);
820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += 4;
821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1 += 4;
822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef REPEAT8
826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef SHADE
827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define SHADE(f, v) clamp255(v + f)
829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBAddRow_C(const uint8* src_argb0, const uint8* src_argb1,
831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  uint8* dst_argb, int width) {
832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int b = src_argb0[0];
835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int g = src_argb0[1];
836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int r = src_argb0[2];
837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int a = src_argb0[3];
838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int b_add = src_argb1[0];
839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int g_add = src_argb1[1];
840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int r_add = src_argb1[2];
841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int a_add = src_argb1[3];
842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = SHADE(b, b_add);
843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = SHADE(g, g_add);
844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = SHADE(r, r_add);
845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = SHADE(a, a_add);
846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += 4;
847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1 += 4;
848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef SHADE
852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define SHADE(f, v) clamp0(f - v)
854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBSubtractRow_C(const uint8* src_argb0, const uint8* src_argb1,
856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_argb, int width) {
857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int b = src_argb0[0];
860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int g = src_argb0[1];
861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int r = src_argb0[2];
862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int a = src_argb0[3];
863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int b_sub = src_argb1[0];
864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int g_sub = src_argb1[1];
865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int r_sub = src_argb1[2];
866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const int a_sub = src_argb1[3];
867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = SHADE(b, b_sub);
868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = SHADE(g, g_sub);
869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = SHADE(r, r_sub);
870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = SHADE(a, a_sub);
871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += 4;
872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1 += 4;
873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef SHADE
877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Sobel functions which mimics SSSE3.
879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SobelXRow_C(const uint8* src_y0, const uint8* src_y1, const uint8* src_y2,
880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                 uint8* dst_sobelx, int width) {
881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_y0[i];
884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_y1[i];
885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c = src_y2[i];
886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a_sub = src_y0[i + 2];
887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b_sub = src_y1[i + 2];
888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c_sub = src_y2[i + 2];
889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a_diff = a - a_sub;
890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b_diff = b - b_sub;
891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c_diff = c - c_sub;
892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sobel = Abs(a_diff + b_diff * 2 + c_diff);
893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_sobelx[i] = (uint8)(clamp255(sobel));
894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SobelYRow_C(const uint8* src_y0, const uint8* src_y1,
898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                 uint8* dst_sobely, int width) {
899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_y0[i + 0];
902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_y0[i + 1];
903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c = src_y0[i + 2];
904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a_sub = src_y1[i + 0];
905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b_sub = src_y1[i + 1];
906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c_sub = src_y1[i + 2];
907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a_diff = a - a_sub;
908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b_diff = b - b_sub;
909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int c_diff = c - c_sub;
910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int sobel = Abs(a_diff + b_diff * 2 + c_diff);
911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_sobely[i] = (uint8)(clamp255(sobel));
912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SobelRow_C(const uint8* src_sobelx, const uint8* src_sobely,
916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                uint8* dst_argb, int width) {
917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = src_sobelx[i];
920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_sobely[i];
921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int s = clamp255(r + b);
922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (uint8)(s);
923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (uint8)(s);
924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (uint8)(s);
925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (uint8)(255u);
926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SobelToPlaneRow_C(const uint8* src_sobelx, const uint8* src_sobely,
931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_y, int width) {
932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = src_sobelx[i];
935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_sobely[i];
936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int s = clamp255(r + b);
937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[i] = (uint8)(s);
938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SobelXYRow_C(const uint8* src_sobelx, const uint8* src_sobely,
942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  uint8* dst_argb, int width) {
943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int r = src_sobelx[i];
946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_sobely[i];
947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int g = clamp255(r + b);
948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (uint8)(b);
949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (uint8)(g);
950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (uint8)(r);
951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (uint8)(255u);
952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
956da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Copy a Y to RGB.
958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 y = src_y[0];
961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    ++src_y;
965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
9687bc9febe8749e98a3812a0dc4380ceae75c29450Johann// TODO(fbarchard): Unify these structures to be platform independent.
9697bc9febe8749e98a3812a0dc4380ceae75c29450Johann// TODO(fbarchard): Generate SIMD structures from float matrix.
9707bc9febe8749e98a3812a0dc4380ceae75c29450Johann
971da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// BT.601 YUV to RGB reference
972da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian//  R = (Y - 16) * 1.164              - V * -1.596
973da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian//  G = (Y - 16) * 1.164 - U *  0.391 - V *  0.813
974da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian//  B = (Y - 16) * 1.164 - U * -2.018
975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
976da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// Y contribution to R,G,B.  Scale and bias.
977da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
978da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */
979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
980da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// U and V contributions to R,G,B.
981da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define UB -128 /* max(-128, round(-2.018 * 64)) */
982da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define UG 25 /* round(0.391 * 64) */
983da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define VG 52 /* round(0.813 * 64) */
984da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define VR -102 /* round(-1.596 * 64) */
985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
986da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// Bias values to subtract 16 from Y and 128 from U and V.
9877bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BB (UB * 128            + YGB)
988da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#define BG (UG * 128 + VG * 128 + YGB)
9897bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BR            (VR * 128 + YGB)
9907bc9febe8749e98a3812a0dc4380ceae75c29450Johann
9917bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(__aarch64__)  // 64 bit arm
9927bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
9937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
9947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
9957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
9967bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
9977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
9987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
9997bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10007bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
10017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
10027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
10037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
10047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
10057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
10067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
10077bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10087bc9febe8749e98a3812a0dc4380ceae75c29450Johann#elif defined(__arm__)  // 32 bit arm
10097bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
10107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
10117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
10127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
10137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
10147bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10157bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
10167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
10177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
10187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
10197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
10207bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10217bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
10227bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
10237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
10247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
10257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
10267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
10277bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
10287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
10297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
10307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
10317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
10327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
10337bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10347bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
10357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
10367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
10377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
10387bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
10397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
10407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB },
10417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
10427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
10437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
10447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
10457bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10467bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
1047da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
10487bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BB
10497bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BG
10507bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BR
1051da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#undef YGB
1052da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#undef UB
1053da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#undef UG
1054da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#undef VG
1055da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#undef VR
10567bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YG
1057da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1058da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// JPEG YUV to RGB reference
1059da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// *  R = Y                - V * -1.40200
1060da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// *  G = Y - U *  0.34414 - V *  0.71414
1061da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// *  B = Y - U * -1.77200
1062da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1063da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// Y contribution to R,G,B.  Scale and bias.
10647bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
10657bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YGB 32  /* 64 / 2 */
1066da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1067da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// U and V contributions to R,G,B.
10687bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define UB -113 /* round(-1.77200 * 64) */
10697bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define UG 22 /* round(0.34414 * 64) */
10707bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define VG 46 /* round(0.71414  * 64) */
10717bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define VR -90 /* round(-1.40200 * 64) */
1072da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
10737bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Bias values to round, and subtract 128 from U and V.
10747bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BB (UB * 128            + YGB)
10757bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BG (UG * 128 + VG * 128 + YGB)
10767bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BR            (VR * 128 + YGB)
10777bc9febe8749e98a3812a0dc4380ceae75c29450Johann
10787bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(__aarch64__)
10797bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
10807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
10817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
10827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
10837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
10847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
10857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
10867bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10877bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
10887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
10897bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
10907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
10917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
10927bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
10937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
10947bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
10957bc9febe8749e98a3812a0dc4380ceae75c29450Johann#elif defined(__arm__)
10967bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
10977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
10987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
10997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
11007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11017bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11027bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
11037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
11047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
11057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
11067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11077bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11087bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
11097bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
11107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
11117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
11127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
11137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
11147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
11157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
11167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
11177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
11187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
11197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
11207bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11217bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
11227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
11237bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
11247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
11257bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
11267bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
11277bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB },
11287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
11297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
11307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
11317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
11327bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11337bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
11347bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11357bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BB
11367bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BG
11377bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BR
11387bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YGB
11397bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef UB
11407bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef UG
11417bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef VG
11427bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef VR
11437bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YG
11447bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11457bc9febe8749e98a3812a0dc4380ceae75c29450Johann// BT.709 YUV to RGB reference
11467bc9febe8749e98a3812a0dc4380ceae75c29450Johann// *  R = Y                - V * -1.28033
11477bc9febe8749e98a3812a0dc4380ceae75c29450Johann// *  G = Y - U *  0.21482 - V *  0.38059
11487bc9febe8749e98a3812a0dc4380ceae75c29450Johann// *  B = Y - U * -2.12798
11497bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11507bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Y contribution to R,G,B.  Scale and bias.
11517bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
11527bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YGB 32  /* 64 / 2 */
11537bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11547bc9febe8749e98a3812a0dc4380ceae75c29450Johann// TODO(fbarchard): Find way to express 2.12 instead of 2.0.
11557bc9febe8749e98a3812a0dc4380ceae75c29450Johann// U and V contributions to R,G,B.
11567bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define UB -128 /* max(-128, round(-2.12798 * 64)) */
11577bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define UG 14 /* round(0.21482 * 64) */
11587bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define VG 24 /* round(0.38059  * 64) */
11597bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define VR -82 /* round(-1.28033 * 64) */
11607bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11617bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Bias values to round, and subtract 128 from U and V.
11627bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BB (UB * 128            + YGB)
11637bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BG (UG * 128 + VG * 128 + YGB)
11647bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BR            (VR * 128 + YGB)
11657bc9febe8749e98a3812a0dc4380ceae75c29450Johann
11667bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(__aarch64__)
11677bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
11687bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
11697bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
11707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
11717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG },
11727bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
11737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11747bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11757bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
11767bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
11777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
11787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
11797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG },
11807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
11817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11827bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11837bc9febe8749e98a3812a0dc4380ceae75c29450Johann#elif defined(__arm__)
11847bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
11857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
11867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
11877bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BG, BR, 0, 0, 0, 0, 0 },
11887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11897bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11907bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
11917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
11927bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
11937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BG, BB, 0, 0, 0, 0, 0 },
11947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0x0101 * YG, 0, 0, 0 }
11957bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
11967bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
11977bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
11987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
11997bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
12007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
12017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
12027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
12037bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
12047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
12057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
12067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
12077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
12087bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
12097bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
12107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
12117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
12127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
12137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
12147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
12157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB },
12167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
12177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
12187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
12197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
12207bc9febe8749e98a3812a0dc4380ceae75c29450Johann};
12217bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
12227bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12237bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BB
12247bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BG
12257bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef BR
12267bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YGB
12277bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef UB
12287bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef UG
12297bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef VG
12307bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef VR
12317bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YG
12327bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12337bc9febe8749e98a3812a0dc4380ceae75c29450Johann// C reference code that mimics the YUV assembly.
12347bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
12357bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              uint8* b, uint8* g, uint8* r,
12367bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              const struct YuvConstants* yuvconstants) {
12377bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(__aarch64__)
12387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ub = -yuvconstants->kUVToRB[0];
12397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ug = yuvconstants->kUVToG[0];
12407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vg = yuvconstants->kUVToG[1];
12417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vr = -yuvconstants->kUVToRB[1];
12427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bb = yuvconstants->kUVBiasBGR[0];
12437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bg = yuvconstants->kUVBiasBGR[1];
12447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int br = yuvconstants->kUVBiasBGR[2];
12457bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int yg = yuvconstants->kYToRgb[0] / 0x0101;
12467bc9febe8749e98a3812a0dc4380ceae75c29450Johann#elif defined(__arm__)
12477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ub = -yuvconstants->kUVToRB[0];
12487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ug = yuvconstants->kUVToG[0];
12497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vg = yuvconstants->kUVToG[4];
12507bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vr = -yuvconstants->kUVToRB[4];
12517bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bb = yuvconstants->kUVBiasBGR[0];
12527bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bg = yuvconstants->kUVBiasBGR[1];
12537bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int br = yuvconstants->kUVBiasBGR[2];
12547bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int yg = yuvconstants->kYToRgb[0] / 0x0101;
12557bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
12567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ub = yuvconstants->kUVToB[0];
12577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ug = yuvconstants->kUVToG[0];
12587bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vg = yuvconstants->kUVToG[1];
12597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int vr = yuvconstants->kUVToR[1];
12607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bb = yuvconstants->kUVBiasB[0];
12617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int bg = yuvconstants->kUVBiasG[0];
12627bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int br = yuvconstants->kUVBiasR[0];
12637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int yg = yuvconstants->kYToRgb[0];
12647bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
12657bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12667bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16;
12677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *b = Clamp((int32)(-(u * ub)          + y1 + bb) >> 6);
12687bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6);
12697bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *r = Clamp((int32)         (-(v * vr) + y1 + br) >> 6);
12707bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
12717bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12727bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Y contribution to R,G,B.  Scale and bias.
12737bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
12747bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */
1275da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1276da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// C reference code that mimics the YUV assembly.
12777bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) {
12787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16;
12797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *b = Clamp((int32)(y1 + YGB) >> 6);
12807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *g = Clamp((int32)(y1 + YGB) >> 6);
12817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *r = Clamp((int32)(y1 + YGB) >> 6);
12827bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
12837bc9febe8749e98a3812a0dc4380ceae75c29450Johann
12847bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YG
12857bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef YGB
1286da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(LIBYUV_DISABLE_NEON) && \
1288da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON))
1289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// C mimic assembly.
1290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// TODO(fbarchard): Remove subsampling from Neon.
1291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I444ToARGBRow_C(const uint8* src_y,
1292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
1293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
1294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
12957bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 u = (src_u[0] + src_u[1] + 1) >> 1;
1300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 v = (src_v[0] + src_v[1] + 1) >> 1;
13017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], u, v, rgb_buf + 0, rgb_buf + 1, rgb_buf + 2,
13027bc9febe8749e98a3812a0dc4380ceae75c29450Johann             yuvconstants);
1303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
13047bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], u, v, rgb_buf + 4, rgb_buf + 5, rgb_buf + 6,
13057bc9febe8749e98a3812a0dc4380ceae75c29450Johann             yuvconstants);
1306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 2;
1309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 2;
1310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
13147bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
13157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    rgb_buf[3] = 255;
1316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else
1319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I444ToARGBRow_C(const uint8* src_y,
1320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
1321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
1322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
13237bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
1327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
13287bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 1;
1331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 4;  // Advance 1 pixel.
1334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
1337da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Also used for 420
1339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToARGBRow_C(const uint8* src_y,
1340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
1341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
1342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
13437bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
13487bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_u[0], src_v[0],
13517bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
13607bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
13657bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid I422AlphaToARGBRow_C(const uint8* src_y,
13667bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const uint8* src_u,
13677bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const uint8* src_v,
13687bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const uint8* src_a,
13697bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          uint8* rgb_buf,
13707bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const struct YuvConstants* yuvconstants,
13717bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          int width) {
1372da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  int x;
1373da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
13747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0],
13757bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
13767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    rgb_buf[3] = src_a[0];
13777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], src_u[0], src_v[0],
13787bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
13797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    rgb_buf[7] = src_a[1];
1380da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += 2;
1381da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += 1;
1382da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += 1;
13837bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_a += 2;
1384da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1385da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
1386da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (width & 1) {
13877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0],
13887bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
13897bc9febe8749e98a3812a0dc4380ceae75c29450Johann    rgb_buf[3] = src_a[0];
1390da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
1391da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
1392da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
1393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToRGB24Row_C(const uint8* src_y,
1394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      const uint8* src_u,
1395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      const uint8* src_v,
1396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* rgb_buf,
13977bc9febe8749e98a3812a0dc4380ceae75c29450Johann                      const struct YuvConstants* yuvconstants,
1398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      int width) {
1399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
14027bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_u[0], src_v[0],
14047bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 3, rgb_buf + 4, rgb_buf + 5, yuvconstants);
1405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 6;  // Advance 2 pixels.
1409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
14127bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToARGB4444Row_C(const uint8* src_y,
1417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         const uint8* src_u,
1418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         const uint8* src_v,
1419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         uint8* dst_argb4444,
14207bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         const struct YuvConstants* yuvconstants,
1421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int width) {
1422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b0;
1423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g0;
1424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r0;
1425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b1;
1426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g1;
1427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r1;
1428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
14307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
14317bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants);
1432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 4;
1433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 4;
1434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 4;
1435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b1 = b1 >> 4;
1436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g1 = g1 >> 4;
1437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r1 = r1 >> 4;
1438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) |
1439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 20) | (r1 << 24) | 0xf000f000;
1440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb4444 += 4;  // Advance 2 pixels.
1444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
14467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
1447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 4;
1448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 4;
1449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 4;
1450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) |
1451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        0xf000;
1452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToARGB1555Row_C(const uint8* src_y,
1456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         const uint8* src_u,
1457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         const uint8* src_v,
1458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         uint8* dst_argb1555,
14597bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         const struct YuvConstants* yuvconstants,
1460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int width) {
1461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b0;
1462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g0;
1463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r0;
1464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b1;
1465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g1;
1466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r1;
1467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
14697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
14707bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants);
1471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 3;
1473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b1 = b1 >> 3;
1475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g1 = g1 >> 3;
1476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r1 = r1 >> 3;
1477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) |
1478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 21) | (r1 << 26) | 0x80008000;
1479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb1555 += 4;  // Advance 2 pixels.
1483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
14857bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
1486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 3;
1488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) |
1490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        0x8000;
1491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToRGB565Row_C(const uint8* src_y,
1495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       const uint8* src_u,
1496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       const uint8* src_v,
1497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_rgb565,
14987bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       const struct YuvConstants* yuvconstants,
1499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int width) {
1500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b0;
1501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g0;
1502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r0;
1503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b1;
1504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g1;
1505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r1;
1506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
15087bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
15097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants);
1510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 2;
1512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b1 = b1 >> 3;
1514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g1 = g1 >> 2;
1515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r1 = r1 >> 3;
1516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) |
1517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 21) | (r1 << 27);
1518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb565 += 4;  // Advance 2 pixels.
1522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
15247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants);
1525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 2;
1527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11);
1529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I411ToARGBRow_C(const uint8* src_y,
1533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
1534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
1535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
15367bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 3; x += 4) {
1540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
15417bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_u[0], src_v[0],
15447bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[2], src_u[0], src_v[0],
15477bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 8, rgb_buf + 9, rgb_buf + 10, yuvconstants);
1548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[11] = 255;
1549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[3], src_u[0], src_v[0],
15507bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 12, rgb_buf + 13, rgb_buf + 14, yuvconstants);
1551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[15] = 255;
1552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 4;
1553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 16;  // Advance 4 pixels.
1556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 2) {
1558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
15597bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_u[0], src_v[0],
15627bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
15697bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NV12ToARGBRow_C(const uint8* src_y,
1575da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                     const uint8* src_uv,
1576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
15777bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1581da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_uv[0], src_uv[1],
15827bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1584da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_uv[0], src_uv[1],
15857bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1588da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_uv += 2;
1589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1592da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_uv[0], src_uv[1],
15937bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NV21ToARGBRow_C(const uint8* src_y,
1599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_vu,
1600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
16017bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_vu[1], src_vu[0],
16067bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_vu[1], src_vu[0],
16097bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_vu += 2;
1613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_vu[1], src_vu[0],
16177bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid NV12ToRGB565Row_C(const uint8* src_y,
1623da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                       const uint8* src_uv,
1624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       uint8* dst_rgb565,
16257bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       const struct YuvConstants* yuvconstants,
1626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int width) {
1627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b0;
1628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g0;
1629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r0;
1630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 b1;
1631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 g1;
1632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8 r1;
1633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
16357bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0, yuvconstants);
16367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[1], src_uv[0], src_uv[1], &b1, &g1, &r1, yuvconstants);
1637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 2;
1639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b1 = b1 >> 3;
1641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g1 = g1 >> 2;
1642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r1 = r1 >> 3;
1643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) |
1644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (b1 << 16) | (g1 << 21) | (r1 << 27);
1645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1646da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_uv += 2;
1647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_rgb565 += 4;  // Advance 2 pixels.
1648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
16507bc9febe8749e98a3812a0dc4380ceae75c29450Johann    YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0, yuvconstants);
1651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b0 = b0 >> 3;
1652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g0 = g0 >> 2;
1653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r0 = r0 >> 3;
1654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11);
1655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid YUY2ToARGBRow_C(const uint8* src_yuy2,
1659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
16607bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3],
16657bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_yuy2[2], src_yuy2[1], src_yuy2[3],
16687bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_yuy2 += 4;
1671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3],
16757bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid UYVYToARGBRow_C(const uint8* src_uyvy,
1681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
16827bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2],
16877bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_uyvy[3], src_uyvy[0], src_uyvy[2],
16907bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants);
1691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uyvy += 4;
1693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2],
16977bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants);
1698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToRGBARow_C(const uint8* src_y,
1703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
1704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
1705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* rgb_buf,
17067bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const struct YuvConstants* yuvconstants,
1707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int width) {
1708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
17117bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 1, rgb_buf + 2, rgb_buf + 3, yuvconstants);
1712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[0] = 255;
1713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[1], src_u[0], src_v[0],
17147bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 5, rgb_buf + 6, rgb_buf + 7, yuvconstants);
1715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[4] = 255;
1716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
1718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
1719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    YuvPixel(src_y[0], src_u[0], src_v[0],
17237bc9febe8749e98a3812a0dc4380ceae75c29450Johann             rgb_buf + 1, rgb_buf + 2, rgb_buf + 3, yuvconstants);
1724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[0] = 255;
1725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1728da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid I400ToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) {
1729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1731da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
1732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1733da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6);
1734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[7] = 255;
1735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
1736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf += 8;  // Advance 2 pixels.
1737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1739da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
1740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rgb_buf[3] = 255;
1741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MirrorRow_C(const uint8* src, uint8* dst, int width) {
1745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  src += width - 1;
1747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[x] = src[0];
1749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[x + 1] = src[-1];
1750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src -= 2;
1751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[width - 1] = src[0];
1754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
1758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  src_uv += (width - 1) << 1;
1760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[x] = src_uv[0];
1762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[x + 1] = src_uv[-2];
1763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[x] = src_uv[1];
1764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[x + 1] = src_uv[-2 + 1];
1765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uv -= 4;
1766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[width - 1] = src_uv[0];
1769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[width - 1] = src_uv[1];
1770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBMirrorRow_C(const uint8* src, uint8* dst, int width) {
1774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src32 = (const uint32*)(src);
1776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst32 = (uint32*)(dst);
1777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  src32 += width - 1;
1778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst32[x] = src32[0];
1780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst32[x + 1] = src32[-1];
1781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src32 -= 2;
1782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst32[width - 1] = src32[0];
1785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
1789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[x] = src_uv[0];
1792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[x + 1] = src_uv[2];
1793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[x] = src_uv[1];
1794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[x + 1] = src_uv[3];
1795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uv += 4;
1796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[width - 1] = src_uv[0];
1799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[width - 1] = src_uv[1];
1800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MergeUVRow_C(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
1804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  int width) {
1805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[0] = src_u[x];
1808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[1] = src_v[x];
1809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[2] = src_u[x + 1];
1810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[3] = src_v[x + 1];
1811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv += 4;
1812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[0] = src_u[width - 1];
1815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[1] = src_v[width - 1];
1816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid CopyRow_C(const uint8* src, uint8* dst, int count) {
1820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  memcpy(dst, src, count);
1821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid CopyRow_16_C(const uint16* src, uint16* dst, int count) {
1824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  memcpy(dst, src, count * 2);
1825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1827da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid SetRow_C(uint8* dst, uint8 v8, int width) {
1828da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  memset(dst, v8, width);
1829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1831da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid ARGBSetRow_C(uint8* dst_argb, uint32 v32, int width) {
1832da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  uint32* d = (uint32*)(dst_argb);
1833da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  int x;
1834da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
1835da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    d[x] = v32;
1836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Filter 2 rows of YUY2 UV's (422) into U and V (420).
1840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid YUY2ToUVRow_C(const uint8* src_yuy2, int src_stride_yuy2,
1841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                   uint8* dst_u, uint8* dst_v, int width) {
1842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of UV values, filtering 2 rows of YUY2.
1843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; x += 2) {
1845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = (src_yuy2[1] + src_yuy2[src_stride_yuy2 + 1] + 1) >> 1;
1846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = (src_yuy2[3] + src_yuy2[src_stride_yuy2 + 3] + 1) >> 1;
1847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_yuy2 += 4;
1848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
1849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
1850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy row of YUY2 UV's (422) into U and V (422).
1854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid YUY2ToUV422Row_C(const uint8* src_yuy2,
1855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst_u, uint8* dst_v, int width) {
1856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of UV values.
1857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; x += 2) {
1859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = src_yuy2[1];
1860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = src_yuy2[3];
1861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_yuy2 += 4;
1862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
1863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
1864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy row of YUY2 Y's (422) into Y (420/422).
1868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width) {
1869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of Y values.
1870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[x] = src_yuy2[0];
1873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[x + 1] = src_yuy2[2];
1874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_yuy2 += 4;
1875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[width - 1] = src_yuy2[0];
1878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Filter 2 rows of UYVY UV's (422) into U and V (420).
1882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid UYVYToUVRow_C(const uint8* src_uyvy, int src_stride_uyvy,
1883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                   uint8* dst_u, uint8* dst_v, int width) {
1884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of UV values.
1885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; x += 2) {
1887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = (src_uyvy[0] + src_uyvy[src_stride_uyvy + 0] + 1) >> 1;
1888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = (src_uyvy[2] + src_uyvy[src_stride_uyvy + 2] + 1) >> 1;
1889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uyvy += 4;
1890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
1891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
1892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy row of UYVY UV's (422) into U and V (422).
1896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid UYVYToUV422Row_C(const uint8* src_uyvy,
1897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst_u, uint8* dst_v, int width) {
1898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of UV values.
1899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; x += 2) {
1901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u[0] = src_uyvy[0];
1902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v[0] = src_uyvy[2];
1903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uyvy += 4;
1904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_u += 1;
1905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_v += 1;
1906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy row of UYVY Y's (422) into Y (420/422).
1910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width) {
1911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Output a row of Y values.
1912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[x] = src_uyvy[1];
1915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[x + 1] = src_uyvy[3];
1916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_uyvy += 4;
1917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_y[width - 1] = src_uyvy[1];
1920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLEND(f, b, a) (((256 - a) * b) >> 8) + f
1924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Blend src_argb0 over src_argb1 and store to dst_argb.
1926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// dst_argb may be src_argb0 or src_argb1.
1927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This code mimics the SSSE3 version for better testability.
1928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBBlendRow_C(const uint8* src_argb0, const uint8* src_argb1,
1929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    uint8* dst_argb, int width) {
1930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
1931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
1932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fb = src_argb0[0];
1933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fg = src_argb0[1];
1934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fr = src_argb0[2];
1935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src_argb0[3];
1936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 bb = src_argb1[0];
1937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 bg = src_argb1[1];
1938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 br = src_argb1[2];
1939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = BLEND(fb, bb, a);
1940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = BLEND(fg, bg, a);
1941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = BLEND(fr, br, a);
1942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
1943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fb = src_argb0[4 + 0];
1945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fg = src_argb0[4 + 1];
1946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fr = src_argb0[4 + 2];
1947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_argb0[4 + 3];
1948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    bb = src_argb1[4 + 0];
1949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    bg = src_argb1[4 + 1];
1950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    br = src_argb1[4 + 2];
1951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[4 + 0] = BLEND(fb, bb, a);
1952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[4 + 1] = BLEND(fg, bg, a);
1953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[4 + 2] = BLEND(fr, br, a);
1954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[4 + 3] = 255u;
1955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb0 += 8;
1956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb1 += 8;
1957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 8;
1958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
1961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fb = src_argb0[0];
1962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fg = src_argb0[1];
1963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 fr = src_argb0[2];
1964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src_argb0[3];
1965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 bb = src_argb1[0];
1966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 bg = src_argb1[1];
1967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 br = src_argb1[2];
1968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = BLEND(fb, bb, a);
1969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = BLEND(fg, bg, a);
1970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = BLEND(fr, br, a);
1971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = 255u;
1972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLEND
19757bc9febe8749e98a3812a0dc4380ceae75c29450Johann
19767bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define UBLEND(f, b, a) (((a) * f) + ((255 - a) * b) + 255) >> 8
19777bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid BlendPlaneRow_C(const uint8* src0, const uint8* src1,
19787bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     const uint8* alpha, uint8* dst, int width) {
19797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int x;
19807bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < width - 1; x += 2) {
19817bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[0] = UBLEND(src0[0], src1[0], alpha[0]);
19827bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[1] = UBLEND(src0[1], src1[1], alpha[1]);
19837bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src0 += 2;
19847bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src1 += 2;
19857bc9febe8749e98a3812a0dc4380ceae75c29450Johann    alpha += 2;
19867bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst += 2;
19877bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
19887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (width & 1) {
19897bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[0] = UBLEND(src0[0], src1[0], alpha[0]);
19907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
19917bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
19927bc9febe8749e98a3812a0dc4380ceae75c29450Johann#undef UBLEND
19937bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24
1995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Multiply source RGB by alpha and store to destination.
1997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This code mimics the SSSE3 version for better testability.
1998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
1999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
2000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width - 1; i += 2) {
2001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src_argb[0];
2002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 g = src_argb[1];
2003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 r = src_argb[2];
2004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src_argb[3];
2005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = ATTENUATE(b, a);
2006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = ATTENUATE(g, a);
2007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = ATTENUATE(r, a);
2008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = a;
2009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src_argb[4];
2010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = src_argb[5];
2011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = src_argb[6];
2012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_argb[7];
2013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[4] = ATTENUATE(b, a);
2014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[5] = ATTENUATE(g, a);
2015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[6] = ATTENUATE(r, a);
2016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[7] = a;
2017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
2018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 8;
2019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
2022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 b = src_argb[0];
2023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 g = src_argb[1];
2024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 r = src_argb[2];
2025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 a = src_argb[3];
2026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = ATTENUATE(b, a);
2027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = ATTENUATE(g, a);
2028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = ATTENUATE(r, a);
2029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = a;
2030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef ATTENUATE
2033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Divide source RGB by alpha and store to destination.
2035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b = (b * 255 + (a / 2)) / a;
2036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// g = (g * 255 + (a / 2)) / a;
2037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// r = (r * 255 + (a / 2)) / a;
2038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Reciprocal method is off by 1 on some values. ie 125
2039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 8.8 fixed point inverse table with 1.0 in upper short and 1 / a in lower.
2040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define T(a) 0x01000000 + (0x10000 / a)
2041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst uint32 fixed_invtbl8[256] = {
2042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  0x01000000, 0x0100ffff, T(0x02), T(0x03), T(0x04), T(0x05), T(0x06), T(0x07),
2043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x08), T(0x09), T(0x0a), T(0x0b), T(0x0c), T(0x0d), T(0x0e), T(0x0f),
2044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x10), T(0x11), T(0x12), T(0x13), T(0x14), T(0x15), T(0x16), T(0x17),
2045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x18), T(0x19), T(0x1a), T(0x1b), T(0x1c), T(0x1d), T(0x1e), T(0x1f),
2046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x20), T(0x21), T(0x22), T(0x23), T(0x24), T(0x25), T(0x26), T(0x27),
2047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x28), T(0x29), T(0x2a), T(0x2b), T(0x2c), T(0x2d), T(0x2e), T(0x2f),
2048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x30), T(0x31), T(0x32), T(0x33), T(0x34), T(0x35), T(0x36), T(0x37),
2049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x38), T(0x39), T(0x3a), T(0x3b), T(0x3c), T(0x3d), T(0x3e), T(0x3f),
2050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x40), T(0x41), T(0x42), T(0x43), T(0x44), T(0x45), T(0x46), T(0x47),
2051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x48), T(0x49), T(0x4a), T(0x4b), T(0x4c), T(0x4d), T(0x4e), T(0x4f),
2052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x50), T(0x51), T(0x52), T(0x53), T(0x54), T(0x55), T(0x56), T(0x57),
2053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x58), T(0x59), T(0x5a), T(0x5b), T(0x5c), T(0x5d), T(0x5e), T(0x5f),
2054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x60), T(0x61), T(0x62), T(0x63), T(0x64), T(0x65), T(0x66), T(0x67),
2055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x68), T(0x69), T(0x6a), T(0x6b), T(0x6c), T(0x6d), T(0x6e), T(0x6f),
2056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x70), T(0x71), T(0x72), T(0x73), T(0x74), T(0x75), T(0x76), T(0x77),
2057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x78), T(0x79), T(0x7a), T(0x7b), T(0x7c), T(0x7d), T(0x7e), T(0x7f),
2058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x80), T(0x81), T(0x82), T(0x83), T(0x84), T(0x85), T(0x86), T(0x87),
2059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x88), T(0x89), T(0x8a), T(0x8b), T(0x8c), T(0x8d), T(0x8e), T(0x8f),
2060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x90), T(0x91), T(0x92), T(0x93), T(0x94), T(0x95), T(0x96), T(0x97),
2061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0x98), T(0x99), T(0x9a), T(0x9b), T(0x9c), T(0x9d), T(0x9e), T(0x9f),
2062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xa0), T(0xa1), T(0xa2), T(0xa3), T(0xa4), T(0xa5), T(0xa6), T(0xa7),
2063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xa8), T(0xa9), T(0xaa), T(0xab), T(0xac), T(0xad), T(0xae), T(0xaf),
2064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xb0), T(0xb1), T(0xb2), T(0xb3), T(0xb4), T(0xb5), T(0xb6), T(0xb7),
2065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xb8), T(0xb9), T(0xba), T(0xbb), T(0xbc), T(0xbd), T(0xbe), T(0xbf),
2066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xc0), T(0xc1), T(0xc2), T(0xc3), T(0xc4), T(0xc5), T(0xc6), T(0xc7),
2067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xc8), T(0xc9), T(0xca), T(0xcb), T(0xcc), T(0xcd), T(0xce), T(0xcf),
2068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xd0), T(0xd1), T(0xd2), T(0xd3), T(0xd4), T(0xd5), T(0xd6), T(0xd7),
2069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xd8), T(0xd9), T(0xda), T(0xdb), T(0xdc), T(0xdd), T(0xde), T(0xdf),
2070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xe0), T(0xe1), T(0xe2), T(0xe3), T(0xe4), T(0xe5), T(0xe6), T(0xe7),
2071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xe8), T(0xe9), T(0xea), T(0xeb), T(0xec), T(0xed), T(0xee), T(0xef),
2072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xf0), T(0xf1), T(0xf2), T(0xf3), T(0xf4), T(0xf5), T(0xf6), T(0xf7),
2073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  T(0xf8), T(0xf9), T(0xfa), T(0xfb), T(0xfc), T(0xfd), T(0xfe), 0x01000100 };
2074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef T
2075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
2077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
2078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
2079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src_argb[0];
2080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 g = src_argb[1];
2081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 r = src_argb[2];
2082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 a = src_argb[3];
2083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const uint32 ia = fixed_invtbl8[a] & 0xffff;  // 8.8 fixed point
2084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = (b * ia) >> 8;
2085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    g = (g * ia) >> 8;
2086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    r = (r * ia) >> 8;
2087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Clamping should not be necessary but is free in assembly.
2088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = clamp255(b);
2089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = clamp255(g);
2090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = clamp255(r);
2091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = a;
2092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
2093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
2094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ComputeCumulativeSumRow_C(const uint8* row, int32* cumsum,
2098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               const int32* previous_cumsum, int width) {
2099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int32 row_sum[4] = {0, 0, 0, 0};
2100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
2101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width; ++x) {
2102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    row_sum[0] += row[x * 4 + 0];
2103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    row_sum[1] += row[x * 4 + 1];
2104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    row_sum[2] += row[x * 4 + 2];
2105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    row_sum[3] += row[x * 4 + 3];
2106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    cumsum[x * 4 + 0] = row_sum[0]  + previous_cumsum[x * 4 + 0];
2107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    cumsum[x * 4 + 1] = row_sum[1]  + previous_cumsum[x * 4 + 1];
2108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    cumsum[x * 4 + 2] = row_sum[2]  + previous_cumsum[x * 4 + 2];
2109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    cumsum[x * 4 + 3] = row_sum[3]  + previous_cumsum[x * 4 + 3];
2110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid CumulativeSumToAverageRow_C(const int32* tl, const int32* bl,
2114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                int w, int area, uint8* dst, int count) {
2115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  float ooa = 1.0f / area;
2116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
2117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < count; ++i) {
2118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (uint8)((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa);
2119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (uint8)((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa);
2120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[2] = (uint8)((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa);
2121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[3] = (uint8)((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa);
2122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 4;
2123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    tl += 4;
2124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    bl += 4;
2125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy pixels from rotated source to destination row with a slope.
2129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API
2130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBAffineRow_C(const uint8* src_argb, int src_argb_stride,
2131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst_argb, const float* uv_dudv, int width) {
2132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
2133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Render a row of pixels from source into a buffer.
2134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  float uv[2];
2135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uv[0] = uv_dudv[0];
2136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uv[1] = uv_dudv[1];
2137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < width; ++i) {
2138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int x = (int)(uv[0]);
2139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int y = (int)(uv[1]);
2140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *(uint32*)(dst_argb) =
2141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        *(const uint32*)(src_argb + y * src_argb_stride +
2142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                         x * 4);
2143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
2144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uv[0] += uv_dudv[2];
2145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uv[1] += uv_dudv[3];
2146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2149da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// Blend 2 rows into 1.
21507bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void HalfRow_C(const uint8* src_uv, ptrdiff_t src_uv_stride,
21517bc9febe8749e98a3812a0dc4380ceae75c29450Johann                      uint8* dst_uv, int width) {
2152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
21537bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < width; ++x) {
2154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[x] = (src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1;
2155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
21587bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void HalfRow_16_C(const uint16* src_uv, ptrdiff_t src_uv_stride,
21597bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         uint16* dst_uv, int width) {
2160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
21617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < width; ++x) {
2162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_uv[x] = (src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1;
2163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// C version 2x2 -> 2x1.
2167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
2168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      ptrdiff_t src_stride,
2169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      int width, int source_y_fraction) {
2170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int y1_fraction = source_y_fraction;
2171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int y0_fraction = 256 - y1_fraction;
2172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* src_ptr1 = src_ptr + src_stride;
2173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
21747bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (y1_fraction == 0) {
2175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    memcpy(dst_ptr, src_ptr, width);
2176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return;
2177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
21787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (y1_fraction == 128) {
21797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    HalfRow_C(src_ptr, src_stride, dst_ptr, width);
2180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return;
2181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
21837bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_ptr[0] =
21847bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction + 128) >> 8;
21857bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_ptr[1] =
21867bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction + 128) >> 8;
2187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 2;
2188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr1 += 2;
2189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
2190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
21927bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_ptr[0] =
21937bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction + 128) >> 8;
2194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid InterpolateRow_16_C(uint16* dst_ptr, const uint16* src_ptr,
2198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         ptrdiff_t src_stride,
2199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int width, int source_y_fraction) {
2200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int y1_fraction = source_y_fraction;
2201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int y0_fraction = 256 - y1_fraction;
2202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* src_ptr1 = src_ptr + src_stride;
2203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
2204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (source_y_fraction == 0) {
2205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    memcpy(dst_ptr, src_ptr, width * 2);
2206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return;
2207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (source_y_fraction == 128) {
22097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    HalfRow_16_C(src_ptr, src_stride, dst_ptr, width);
2210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return;
2211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
2213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8;
2214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8;
2215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 2;
2216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr1 += 2;
2217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
2218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
2220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8;
2221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Use first 4 shuffler values to reorder ARGB channels.
2225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ARGBShuffleRow_C(const uint8* src_argb, uint8* dst_argb,
22267bc9febe8749e98a3812a0dc4380ceae75c29450Johann                      const uint8* shuffler, int width) {
2227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int index0 = shuffler[0];
2228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int index1 = shuffler[1];
2229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int index2 = shuffler[2];
2230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int index3 = shuffler[3];
2231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Shuffle a row of ARGB.
2232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
22337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < width; ++x) {
2234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // To support in-place conversion.
2235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b = src_argb[index0];
2236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 g = src_argb[index1];
2237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 r = src_argb[index2];
2238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a = src_argb[index3];
2239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = b;
2240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = g;
2241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = r;
2242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = a;
2243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 4;
2244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
2245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToYUY2Row_C(const uint8* src_y,
2249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
2250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
2251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst_frame, int width) {
2252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
2253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
2254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[0] = src_y[0];
2255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[1] = src_u[0];
2256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[2] = src_y[1];
2257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[3] = src_v[0];
2258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame += 4;
2259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
2260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
2261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
2262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
2264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[0] = src_y[0];
2265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[1] = src_u[0];
2266da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_frame[2] = 0;
2267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[3] = src_v[0];
2268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToUYVYRow_C(const uint8* src_y,
2272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_u,
2273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     const uint8* src_v,
2274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst_frame, int width) {
2275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
2276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < width - 1; x += 2) {
2277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[0] = src_u[0];
2278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[1] = src_y[0];
2279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[2] = src_v[0];
2280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[3] = src_y[1];
2281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame += 4;
2282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_y += 2;
2283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_u += 1;
2284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_v += 1;
2285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (width & 1) {
2287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[0] = src_u[0];
2288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[1] = src_y[0];
2289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_frame[2] = src_v[0];
2290da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_frame[3] = 0;
2291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
2292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2294da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
22957bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ARGBPolynomialRow_C(const uint8* src_argb,
22967bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         uint8* dst_argb,
22977bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         const float* poly,
22987bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         int width) {
22997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
23007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < width; ++i) {
23017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float b = (float)(src_argb[0]);
23027bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float g = (float)(src_argb[1]);
23037bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float r = (float)(src_argb[2]);
23047bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float a = (float)(src_argb[3]);
23057bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float b2 = b * b;
23067bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float g2 = g * g;
23077bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float r2 = r * r;
23087bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float a2 = a * a;
23097bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float db = poly[0] + poly[4] * b;
23107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float dg = poly[1] + poly[5] * g;
23117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float dr = poly[2] + poly[6] * r;
23127bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float da = poly[3] + poly[7] * a;
23137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float b3 = b2 * b;
23147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float g3 = g2 * g;
23157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float r3 = r2 * r;
23167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    float a3 = a2 * a;
23177bc9febe8749e98a3812a0dc4380ceae75c29450Johann    db += poly[8] * b2;
23187bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dg += poly[9] * g2;
23197bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dr += poly[10] * r2;
23207bc9febe8749e98a3812a0dc4380ceae75c29450Johann    da += poly[11] * a2;
23217bc9febe8749e98a3812a0dc4380ceae75c29450Johann    db += poly[12] * b3;
23227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dg += poly[13] * g3;
23237bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dr += poly[14] * r3;
23247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    da += poly[15] * a3;
23257bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[0] = Clamp((int32)(db));
23277bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[1] = Clamp((int32)(dg));
23287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[2] = Clamp((int32)(dr));
23297bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[3] = Clamp((int32)(da));
23307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_argb += 4;
23317bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb += 4;
23327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23337bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
23347bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23357bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ARGBLumaColorTableRow_C(const uint8* src_argb, uint8* dst_argb, int width,
23367bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             const uint8* luma, uint32 lumacoeff) {
23377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint32 bc = lumacoeff & 0xff;
23387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint32 gc = (lumacoeff >> 8) & 0xff;
23397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint32 rc = (lumacoeff >> 16) & 0xff;
23407bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
23427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < width - 1; i += 2) {
23437bc9febe8749e98a3812a0dc4380ceae75c29450Johann    // Luminance in rows, color values in columns.
23447bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const uint8* luma0 = ((src_argb[0] * bc + src_argb[1] * gc +
23457bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           src_argb[2] * rc) & 0x7F00u) + luma;
23467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const uint8* luma1;
23477bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[0] = luma0[src_argb[0]];
23487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[1] = luma0[src_argb[1]];
23497bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[2] = luma0[src_argb[2]];
23507bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[3] = src_argb[3];
23517bc9febe8749e98a3812a0dc4380ceae75c29450Johann    luma1 = ((src_argb[4] * bc + src_argb[5] * gc +
23527bc9febe8749e98a3812a0dc4380ceae75c29450Johann              src_argb[6] * rc) & 0x7F00u) + luma;
23537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[4] = luma1[src_argb[4]];
23547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[5] = luma1[src_argb[5]];
23557bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[6] = luma1[src_argb[6]];
23567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[7] = src_argb[7];
23577bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_argb += 8;
23587bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb += 8;
23597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (width & 1) {
23617bc9febe8749e98a3812a0dc4380ceae75c29450Johann    // Luminance in rows, color values in columns.
23627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    const uint8* luma0 = ((src_argb[0] * bc + src_argb[1] * gc +
23637bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           src_argb[2] * rc) & 0x7F00u) + luma;
23647bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[0] = luma0[src_argb[0]];
23657bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[1] = luma0[src_argb[1]];
23667bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[2] = luma0[src_argb[2]];
23677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_argb[3] = src_argb[3];
23687bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23697bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
23707bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23717bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ARGBCopyAlphaRow_C(const uint8* src, uint8* dst, int width) {
23727bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
23737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < width - 1; i += 2) {
23747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[3] = src[3];
23757bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[7] = src[7];
23767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst += 8;
23777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src += 8;
23787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (width & 1) {
23807bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[3] = src[3];
23817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23827bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
23837bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23847bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width) {
23857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
23867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < width - 1; i += 2) {
23877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_a[0] = src_argb[3];
23887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_a[1] = src_argb[7];
23897bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_a += 2;
23907bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_argb += 8;
23917bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23927bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (width & 1) {
23937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst_a[0] = src_argb[3];
23947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
23957bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
23967bc9febe8749e98a3812a0dc4380ceae75c29450Johann
23977bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) {
23987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
23997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < width - 1; i += 2) {
24007bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[3] = src[0];
24017bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[7] = src[1];
24027bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst += 8;
24037bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src += 2;
24047bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
24057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (width & 1) {
24067bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[3] = src[0];
24077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
24087bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
24097bc9febe8749e98a3812a0dc4380ceae75c29450Johann
24107bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Maximum temporary width for wrappers to process at a time, in pixels.
24117bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define MAXTWIDTH 2048
24127bc9febe8749e98a3812a0dc4380ceae75c29450Johann
24137bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if !(defined(_MSC_VER) && defined(_M_IX86)) && \
24147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    defined(HAS_I422TORGB565ROW_SSSE3)
24157bc9febe8749e98a3812a0dc4380ceae75c29450Johann// row_win.cc has asm version, but GCC uses 2 step wrapper.
24167bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid I422ToRGB565Row_SSSE3(const uint8* src_y,
24177bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           const uint8* src_u,
24187bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           const uint8* src_v,
24197bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           uint8* dst_rgb565,
24207bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           const struct YuvConstants* yuvconstants,
24217bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           int width) {
24227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
24237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  while (width > 0) {
24247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
24257bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth);
24267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
24277bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_y += twidth;
24287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_u += twidth / 2;
2429da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2430da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb565 += twidth * 2;
2431da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2432da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2434da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2436da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOARGB1555ROW_SSSE3)
2437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToARGB1555Row_SSSE3(const uint8* src_y,
2438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             const uint8* src_u,
2439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             const uint8* src_v,
2440da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             uint8* dst_argb1555,
24417bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             const struct YuvConstants* yuvconstants,
2442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             int width) {
2443da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
2444da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2445da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2446da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
24477bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth);
2448da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToARGB1555Row_SSE2(row, dst_argb1555, twidth);
2449da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2450da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2451da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2452da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_argb1555 += twidth * 2;
2453da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2454da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2456da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2458da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOARGB4444ROW_SSSE3)
2459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid I422ToARGB4444Row_SSSE3(const uint8* src_y,
2460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             const uint8* src_u,
2461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             const uint8* src_v,
2462da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             uint8* dst_argb4444,
24637bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             const struct YuvConstants* yuvconstants,
2464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             int width) {
2465da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
2466da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2467da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2468da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
24697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth);
2470da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToARGB4444Row_SSE2(row, dst_argb4444, twidth);
2471da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2472da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2473da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2474da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_argb4444 += twidth * 2;
2475da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2476da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2478da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2480da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV12TORGB565ROW_SSSE3)
24817bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid NV12ToRGB565Row_SSSE3(const uint8* src_y,
24827bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           const uint8* src_uv,
24837bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           uint8* dst_rgb565,
24847bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           const struct YuvConstants* yuvconstants,
24857bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           int width) {
2486da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
2487da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2488da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2489da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
24907bc9febe8749e98a3812a0dc4380ceae75c29450Johann    NV12ToARGBRow_SSSE3(src_y, src_uv, row, yuvconstants, twidth);
2491da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
2492da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2493da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_uv += twidth;
2494da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb565 += twidth * 2;
2495da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2496da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
2498da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
2500da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TORGB565ROW_AVX2)
2501da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid I422ToRGB565Row_AVX2(const uint8* src_y,
2502da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                          const uint8* src_u,
2503da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                          const uint8* src_v,
2504da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                          uint8* dst_rgb565,
25057bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const struct YuvConstants* yuvconstants,
2506da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                          int width) {
25077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2508da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2509da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
25107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
25117bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_ARGBTORGB565ROW_AVX2)
2512da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth);
25137bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
25147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
25157bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
2516da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2517da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2518da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2519da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb565 += twidth * 2;
2520da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2521da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2522da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
2523da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2524da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
2525da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOARGB1555ROW_AVX2)
2526da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid I422ToARGB1555Row_AVX2(const uint8* src_y,
2527da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_u,
2528da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_v,
2529da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            uint8* dst_argb1555,
25307bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            const struct YuvConstants* yuvconstants,
2531da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            int width) {
2532da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
25337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2534da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2535da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
25367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
25377bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_ARGBTOARGB1555ROW_AVX2)
2538da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToARGB1555Row_AVX2(row, dst_argb1555, twidth);
25397bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
25407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARGBToARGB1555Row_SSE2(row, dst_argb1555, twidth);
25417bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
2542da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2543da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2544da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2545da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_argb1555 += twidth * 2;
2546da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2547da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2548da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
2549da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2550da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
2551da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOARGB4444ROW_AVX2)
2552da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid I422ToARGB4444Row_AVX2(const uint8* src_y,
2553da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_u,
2554da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_v,
2555da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            uint8* dst_argb4444,
25567bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            const struct YuvConstants* yuvconstants,
2557da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            int width) {
2558da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
25597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2560da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2561da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
25627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
25637bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_ARGBTOARGB4444ROW_AVX2)
2564da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToARGB4444Row_AVX2(row, dst_argb4444, twidth);
25657bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
25667bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARGBToARGB4444Row_SSE2(row, dst_argb4444, twidth);
25677bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
2568da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2569da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2570da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2571da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_argb4444 += twidth * 2;
2572da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2573da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2574da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
2575da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2576da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
2577da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TORGB24ROW_AVX2)
2578da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid I422ToRGB24Row_AVX2(const uint8* src_y,
2579da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_u,
2580da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            const uint8* src_v,
2581da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            uint8* dst_rgb24,
25827bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            const struct YuvConstants* yuvconstants,
2583da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                            int width) {
2584da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
25857bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2586da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2587da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
25887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
2589da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    // TODO(fbarchard): ARGBToRGB24Row_AVX2
2590da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth);
2591da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
2592da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_u += twidth / 2;
2593da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_v += twidth / 2;
2594da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb24 += twidth * 3;
2595da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2596da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2597da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
2598da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2599da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
2600da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV12TORGB565ROW_AVX2)
26017bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid NV12ToRGB565Row_AVX2(const uint8* src_y,
26027bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const uint8* src_uv,
26037bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          uint8* dst_rgb565,
26047bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          const struct YuvConstants* yuvconstants,
26057bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          int width) {
2606da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // Row buffer for intermediate ARGB pixels.
26077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
2608da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  while (width > 0) {
2609da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
26107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth);
26117bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_ARGBTORGB565ROW_AVX2)
2612da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth);
26137bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
26147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth);
2615da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2616da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_y += twidth;
26177bc9febe8749e98a3812a0dc4380ceae75c29450Johann    src_uv += twidth;
2618da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_rgb565 += twidth * 2;
2619da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    width -= twidth;
2620da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
2621da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
2622da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
2623da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
2624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus
2625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // extern "C"
2626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // namespace libyuv
2627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
2628