1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ColorConvert.h"
18
19#ifndef max
20#define max(a,b) ((a) > (b) ? (a) : (b))
21#endif
22#ifndef min
23#define min(a,b) ((a) < (b) ? (a) : (b))
24#endif
25
26namespace android {
27
28void YUVToRGB(
29        int32_t y, int32_t u, int32_t v,
30        int32_t* r, int32_t* g, int32_t* b) {
31    y -= 16;
32    u -= 128;
33    v -= 128;
34
35    *b = 1192 * y + 2066 * u;
36    *g = 1192 * y - 833 * v - 400 * u;
37    *r = 1192 * y + 1634 * v;
38
39    *r = min(262143, max(0, *r));
40    *g = min(262143, max(0, *g));
41    *b = min(262143, max(0, *b));
42
43    *r >>= 10;
44    *g >>= 10;
45    *b >>= 10;
46}
47
48void convertYUV420spToARGB(
49        uint8_t *pY, uint8_t *pUV, int32_t width, int32_t height,
50        uint8_t *dest) {
51    const int32_t bytes_per_pixel = 2;
52
53    for (int32_t i = 0; i < height; i++) {
54        for (int32_t j = 0; j < width; j++) {
55            int32_t y = *(pY + i * width + j);
56            int32_t u = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
57            int32_t v = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
58
59            int32_t r, g, b;
60            YUVToRGB(y, u, v, &r, &g, &b);
61
62            *dest++ = 0xFF;
63            *dest++ = r;
64            *dest++ = g;
65            *dest++ = b;
66        }
67    }
68}
69
70void convertYUV420spToRGB888(
71        uint8_t *pY, uint8_t *pUV, int32_t width, int32_t height,
72        uint8_t *dest) {
73    const int32_t bytes_per_pixel = 2;
74
75    for (int32_t i = 0; i < height; i++) {
76        for (int32_t j = 0; j < width; j++) {
77            int32_t y = *(pY + i * width + j);
78            int32_t u = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
79            int32_t v = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
80
81            int32_t r, g, b;
82            YUVToRGB(y, u, v, &r, &g, &b);
83
84            *dest++ = r;
85            *dest++ = g;
86            *dest++ = b;
87        }
88    }
89}
90
91// HACK - not even slightly optimized
92// TODO: remove when RGBA support is added to SoftwareRenderer
93void convertRGBAToARGB(
94        uint8_t *src, int32_t width, int32_t height, uint32_t stride,
95        uint8_t *dest) {
96    for (int32_t i = 0; i < height; ++i) {
97        for (int32_t j = 0; j < width; ++j) {
98            uint8_t r = *src++;
99            uint8_t g = *src++;
100            uint8_t b = *src++;
101            uint8_t a = *src++;
102            *dest++ = a;
103            *dest++ = r;
104            *dest++ = g;
105            *dest++ = b;
106        }
107        src += (stride - width) * 4;
108    }
109}
110
111}   // namespace android
112