1 /*
2 * Copyright (C) 2011 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 /*
18 * Contains implemenation of framebuffer conversion routines.
19 */
20
21 #define LOG_NDEBUG 0
22 #define LOG_TAG "EmulatedCamera_Converter"
23 #include <cutils/log.h>
24 #include "Converters.h"
25
26 namespace android {
27
_YUV420SToRGB565(const uint8_t * Y,const uint8_t * U,const uint8_t * V,int dUV,uint16_t * rgb,int width,int height)28 static void _YUV420SToRGB565(const uint8_t* Y,
29 const uint8_t* U,
30 const uint8_t* V,
31 int dUV,
32 uint16_t* rgb,
33 int width,
34 int height)
35 {
36 const uint8_t* U_pos = U;
37 const uint8_t* V_pos = V;
38
39 for (int y = 0; y < height; y++) {
40 for (int x = 0; x < width; x += 2, U += dUV, V += dUV) {
41 const uint8_t nU = *U;
42 const uint8_t nV = *V;
43 *rgb = YUVToRGB565(*Y, nU, nV);
44 Y++; rgb++;
45 *rgb = YUVToRGB565(*Y, nU, nV);
46 Y++; rgb++;
47 }
48 if (y & 0x1) {
49 U_pos = U;
50 V_pos = V;
51 } else {
52 U = U_pos;
53 V = V_pos;
54 }
55 }
56 }
57
_YUV420SToRGB32(const uint8_t * Y,const uint8_t * U,const uint8_t * V,int dUV,uint32_t * rgb,int width,int height)58 static void _YUV420SToRGB32(const uint8_t* Y,
59 const uint8_t* U,
60 const uint8_t* V,
61 int dUV,
62 uint32_t* rgb,
63 int width,
64 int height)
65 {
66 const uint8_t* U_pos = U;
67 const uint8_t* V_pos = V;
68
69 for (int y = 0; y < height; y++) {
70 for (int x = 0; x < width; x += 2, U += dUV, V += dUV) {
71 const uint8_t nU = *U;
72 const uint8_t nV = *V;
73 *rgb = YUVToRGB32(*Y, nU, nV);
74 Y++; rgb++;
75 *rgb = YUVToRGB32(*Y, nU, nV);
76 Y++; rgb++;
77 }
78 if (y & 0x1) {
79 U_pos = U;
80 V_pos = V;
81 } else {
82 U = U_pos;
83 V = V_pos;
84 }
85 }
86 }
87
YV12ToRGB565(const void * yv12,void * rgb,int width,int height)88 void YV12ToRGB565(const void* yv12, void* rgb, int width, int height)
89 {
90 const int pix_total = width * height;
91 const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12);
92 const uint8_t* U = Y + pix_total;
93 const uint8_t* V = U + pix_total / 4;
94 _YUV420SToRGB565(Y, U, V, 1, reinterpret_cast<uint16_t*>(rgb), width, height);
95 }
96
YV12ToRGB32(const void * yv12,void * rgb,int width,int height)97 void YV12ToRGB32(const void* yv12, void* rgb, int width, int height)
98 {
99 const int pix_total = width * height;
100 const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12);
101 const uint8_t* V = Y + pix_total;
102 const uint8_t* U = V + pix_total / 4;
103 _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height);
104 }
105
YU12ToRGB32(const void * yu12,void * rgb,int width,int height)106 void YU12ToRGB32(const void* yu12, void* rgb, int width, int height)
107 {
108 const int pix_total = width * height;
109 const uint8_t* Y = reinterpret_cast<const uint8_t*>(yu12);
110 const uint8_t* U = Y + pix_total;
111 const uint8_t* V = U + pix_total / 4;
112 _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height);
113 }
114
115 /* Common converter for YUV 4:2:0 interleaved to RGB565.
116 * y, u, and v point to Y,U, and V panes, where U and V values are interleaved.
117 */
_NVXXToRGB565(const uint8_t * Y,const uint8_t * U,const uint8_t * V,uint16_t * rgb,int width,int height)118 static void _NVXXToRGB565(const uint8_t* Y,
119 const uint8_t* U,
120 const uint8_t* V,
121 uint16_t* rgb,
122 int width,
123 int height)
124 {
125 _YUV420SToRGB565(Y, U, V, 2, rgb, width, height);
126 }
127
128 /* Common converter for YUV 4:2:0 interleaved to RGB32.
129 * y, u, and v point to Y,U, and V panes, where U and V values are interleaved.
130 */
_NVXXToRGB32(const uint8_t * Y,const uint8_t * U,const uint8_t * V,uint32_t * rgb,int width,int height)131 static void _NVXXToRGB32(const uint8_t* Y,
132 const uint8_t* U,
133 const uint8_t* V,
134 uint32_t* rgb,
135 int width,
136 int height)
137 {
138 _YUV420SToRGB32(Y, U, V, 2, rgb, width, height);
139 }
140
NV12ToRGB565(const void * nv12,void * rgb,int width,int height)141 void NV12ToRGB565(const void* nv12, void* rgb, int width, int height)
142 {
143 const int pix_total = width * height;
144 const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12);
145 _NVXXToRGB565(y, y + pix_total, y + pix_total + 1,
146 reinterpret_cast<uint16_t*>(rgb), width, height);
147 }
148
NV12ToRGB32(const void * nv12,void * rgb,int width,int height)149 void NV12ToRGB32(const void* nv12, void* rgb, int width, int height)
150 {
151 const int pix_total = width * height;
152 const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12);
153 _NVXXToRGB32(y, y + pix_total, y + pix_total + 1,
154 reinterpret_cast<uint32_t*>(rgb), width, height);
155 }
156
NV21ToRGB565(const void * nv21,void * rgb,int width,int height)157 void NV21ToRGB565(const void* nv21, void* rgb, int width, int height)
158 {
159 const int pix_total = width * height;
160 const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21);
161 _NVXXToRGB565(y, y + pix_total + 1, y + pix_total,
162 reinterpret_cast<uint16_t*>(rgb), width, height);
163 }
164
NV21ToRGB32(const void * nv21,void * rgb,int width,int height)165 void NV21ToRGB32(const void* nv21, void* rgb, int width, int height)
166 {
167 const int pix_total = width * height;
168 const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21);
169 _NVXXToRGB32(y, y + pix_total + 1, y + pix_total,
170 reinterpret_cast<uint32_t*>(rgb), width, height);
171 }
172
173 }; /* namespace android */
174