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