1744f5739019d1fd917f981e740b353c3d73fd1a8David Smith/*
2744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Copyright (C) 2014 The Android Open Source Project
3744f5739019d1fd917f981e740b353c3d73fd1a8David Smith *
4744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Licensed under the Apache License, Version 2.0 (the "License");
5744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * you may not use this file except in compliance with the License.
6744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * You may obtain a copy of the License at
7744f5739019d1fd917f981e740b353c3d73fd1a8David Smith *
8744f5739019d1fd917f981e740b353c3d73fd1a8David Smith *      http://www.apache.org/licenses/LICENSE-2.0
9744f5739019d1fd917f981e740b353c3d73fd1a8David Smith *
10744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Unless required by applicable law or agreed to in writing, software
11744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * distributed under the License is distributed on an "AS IS" BASIS,
12744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * See the License for the specific language governing permissions and
14744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * limitations under the License.
15744f5739019d1fd917f981e740b353c3d73fd1a8David Smith */
16744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
17744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include "ColorConvert.h"
18744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
19744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#ifndef max
20744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#define max(a,b) ((a) > (b) ? (a) : (b))
21744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#endif
22744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#ifndef min
23744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#define min(a,b) ((a) < (b) ? (a) : (b))
24744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#endif
25744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
26744f5739019d1fd917f981e740b353c3d73fd1a8David Smithnamespace android {
27744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
28744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid YUVToRGB(
29744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        int32_t y, int32_t u, int32_t v,
30744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        int32_t* r, int32_t* g, int32_t* b) {
31744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    y -= 16;
32744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    u -= 128;
33744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    v -= 128;
34744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
35744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *b = 1192 * y + 2066 * u;
36744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *g = 1192 * y - 833 * v - 400 * u;
37744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *r = 1192 * y + 1634 * v;
38744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
39744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *r = min(262143, max(0, *r));
40744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *g = min(262143, max(0, *g));
41744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *b = min(262143, max(0, *b));
42744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
43744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *r >>= 10;
44744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *g >>= 10;
45744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    *b >>= 10;
46744f5739019d1fd917f981e740b353c3d73fd1a8David Smith}
47744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
48744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid convertYUV420spToARGB(
49744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        uint8_t *pY, uint8_t *pUV, int32_t width, int32_t height,
50744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        uint8_t *dest) {
51744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    const int32_t bytes_per_pixel = 2;
52744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
53744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    for (int32_t i = 0; i < height; i++) {
54744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        for (int32_t j = 0; j < width; j++) {
55744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t y = *(pY + i * width + j);
56744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t u = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
57744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t v = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
58744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
59744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t r, g, b;
60744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            YUVToRGB(y, u, v, &r, &g, &b);
61744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
62744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = 0xFF;
63744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = r;
64744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = g;
65744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = b;
66744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        }
67744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
68744f5739019d1fd917f981e740b353c3d73fd1a8David Smith}
69744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
70744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid convertYUV420spToRGB888(
71744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        uint8_t *pY, uint8_t *pUV, int32_t width, int32_t height,
72744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        uint8_t *dest) {
73744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    const int32_t bytes_per_pixel = 2;
74744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
75744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    for (int32_t i = 0; i < height; i++) {
76744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        for (int32_t j = 0; j < width; j++) {
77744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t y = *(pY + i * width + j);
78744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t u = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
79744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t v = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
80744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
81744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            int32_t r, g, b;
82744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            YUVToRGB(y, u, v, &r, &g, &b);
83744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
84744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = r;
85744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = g;
86744f5739019d1fd917f981e740b353c3d73fd1a8David Smith            *dest++ = b;
87744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        }
88744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
89744f5739019d1fd917f981e740b353c3d73fd1a8David Smith}
90744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
91e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith// HACK - not even slightly optimized
92e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith// TODO: remove when RGBA support is added to SoftwareRenderer
93e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smithvoid convertRGBAToARGB(
94e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith        uint8_t *src, int32_t width, int32_t height, uint32_t stride,
95e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith        uint8_t *dest) {
96ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    for (int32_t i = 0; i < height; ++i) {
97ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        for (int32_t j = 0; j < width; ++j) {
98e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            uint8_t r = *src++;
99e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            uint8_t g = *src++;
100e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            uint8_t b = *src++;
101e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            uint8_t a = *src++;
102e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            *dest++ = a;
103e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            *dest++ = r;
104e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            *dest++ = g;
105e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith            *dest++ = b;
106e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith        }
107e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith        src += (stride - width) * 4;
108e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith    }
109e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith}
110e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith
111744f5739019d1fd917f981e740b353c3d73fd1a8David Smith}   // namespace android
112