summaryrefslogtreecommitdiff
path: root/utils/util.cpp (plain)
blob: ea28a337b3991013bae431e4feefbac6cc6dc302
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/ioctl.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include "util.h"
8
9#ifdef AMLOGIC_USB_CAMERA_SUPPORT
10#define swap_cbcr
11static void convert_rgb16_to_nv21(uint8_t *rgb, uint8_t *yuv, int width, int height)
12{
13 int iy =0, iuv = 0;
14 uint8_t* buf_y = yuv;
15 uint8_t* buf_uv = buf_y + width * height;
16 uint16_t* buf_rgb = (uint16_t *)rgb;
17 int h,w,val_rgb,val_r,val_g,val_b;
18 int y,u,v;
19 for (h = 0; h < height; h++) {
20 for (w = 0; w < width; w++) {
21 val_rgb = buf_rgb[h * width + w];
22 val_r = ((val_rgb & (0x1f << 11)) >> 11)<<3;
23 val_g = ((val_rgb & (0x3f << 5)) >> 5)<<2;
24 val_b = ((val_rgb & (0x1f << 0)) >> 0)<<3;
25 y = 0.30078 * val_r + 0.5859 * val_g + 0.11328 * val_b;
26 if (y > 255) {
27 y = 255;
28 } else if (y < 0) {
29 y = 0;
30 }
31 buf_y[iy++] = y;
32 if (0 == h % 2 && 0 == w % 2) {
33 u = -0.11328 * val_r - 0.33984 * val_g + 0.51179 * val_b + 128;
34 if (u > 255) {
35 u = 255;
36 } else if (u < 0) {
37 u = 0;
38 }
39 v = 0.51179 * val_r - 0.429688 * val_g - 0.08203 * val_b + 128;
40 if (v > 255) {
41 v = 255;
42 } else if (v < 0) {
43 v = 0;
44 }
45#ifdef swap_cbcr
46 buf_uv[iuv++] = v;
47 buf_uv[iuv++] = u;
48#else
49 buf_uv[iuv++] = u;
50 buf_uv[iuv++] = v;
51#endif
52 }
53 }
54}
55}
56
57static inline void yuv_to_rgb16(unsigned char y,unsigned char u,unsigned char v,unsigned char *rgb)
58{
59 register int r,g,b;
60 int rgb16;
61
62 r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10;
63 g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u -128) ) >> 10;
64 b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10;
65
66 r = r > 255 ? 255 : r < 0 ? 0 : r;
67 g = g > 255 ? 255 : g < 0 ? 0 : g;
68 b = b > 255 ? 255 : b < 0 ? 0 : b;
69
70 rgb16 = (int)(((r >> 3)<<11) | ((g >> 2) << 5)| ((b >> 3) << 0));
71
72 *rgb = (unsigned char)(rgb16 & 0xFF);
73 rgb++;
74 *rgb = (unsigned char)((rgb16 & 0xFF00) >> 8);
75
76}
77
78void yuyv422_to_rgb16(unsigned char *from, unsigned char *to, int size)
79{
80 int x,y,z=0;
81
82 for (y = 0; y < size; y+=4) {
83 unsigned char Y1, Y2, U, V;
84
85 Y1 = from[y + 0];
86 U = from[y + 1];
87 Y2 = from[y + 2];
88 V = from[y + 3];
89
90 yuv_to_rgb16(Y1, U, V, &to[y]);
91 yuv_to_rgb16(Y2, U, V, &to[y + 2]);
92 }
93}
94
95void yuyv422_to_rgb16(unsigned char *from, unsigned char *to, int width, int height)
96{
97 yuyv422_to_rgb16(from,to,(width * height) * 2);
98}
99
100void yuyv422_to_nv21(unsigned char *bufsrc, unsigned char *bufdest, int width, int height)
101{
102 unsigned char *ptrsrcy1, *ptrsrcy2;
103 unsigned char *ptrsrcy3, *ptrsrcy4;
104 unsigned char *ptrsrccb1, *ptrsrccb2;
105 unsigned char *ptrsrccb3, *ptrsrccb4;
106 unsigned char *ptrsrccr1, *ptrsrccr2;
107 unsigned char *ptrsrccr3, *ptrsrccr4;
108 int srcystride, srcccstride;
109
110 ptrsrcy1 = bufsrc ;
111 ptrsrcy2 = bufsrc + (width<<1) ;
112 ptrsrcy3 = bufsrc + (width<<1)*2 ;
113 ptrsrcy4 = bufsrc + (width<<1)*3 ;
114
115 ptrsrccb1 = bufsrc + 1;
116 ptrsrccb2 = bufsrc + (width<<1) + 1;
117 ptrsrccb3 = bufsrc + (width<<1)*2 + 1;
118 ptrsrccb4 = bufsrc + (width<<1)*3 + 1;
119
120 ptrsrccr1 = bufsrc + 3;
121 ptrsrccr2 = bufsrc + (width<<1) + 3;
122 ptrsrccr3 = bufsrc + (width<<1)*2 + 3;
123 ptrsrccr4 = bufsrc + (width<<1)*3 + 3;
124
125 srcystride = (width<<1)*3;
126 srcccstride = (width<<1)*3;
127
128 unsigned char *ptrdesty1, *ptrdesty2;
129 unsigned char *ptrdesty3, *ptrdesty4;
130 unsigned char *ptrdestcb1, *ptrdestcb2;
131 unsigned char *ptrdestcr1, *ptrdestcr2;
132 int destystride, destccstride;
133
134 ptrdesty1 = bufdest;
135 ptrdesty2 = bufdest + width;
136 ptrdesty3 = bufdest + width*2;
137 ptrdesty4 = bufdest + width*3;
138
139 ptrdestcb1 = bufdest + width*height;
140 ptrdestcb2 = bufdest + width*height + width;
141
142 ptrdestcr1 = bufdest + width*height + 1;
143 ptrdestcr2 = bufdest + width*height + width + 1;
144
145 destystride = (width)*3;
146 destccstride = width;
147
148 int i, j;
149
150 for(j=0; j<(height/4); j++)
151 {
152 for(i=0;i<(width/2);i++)
153 {
154 (*ptrdesty1++) = (*ptrsrcy1);
155 (*ptrdesty2++) = (*ptrsrcy2);
156 (*ptrdesty3++) = (*ptrsrcy3);
157 (*ptrdesty4++) = (*ptrsrcy4);
158
159 ptrsrcy1 += 2;
160 ptrsrcy2 += 2;
161 ptrsrcy3 += 2;
162 ptrsrcy4 += 2;
163
164 (*ptrdesty1++) = (*ptrsrcy1);
165 (*ptrdesty2++) = (*ptrsrcy2);
166 (*ptrdesty3++) = (*ptrsrcy3);
167 (*ptrdesty4++) = (*ptrsrcy4);
168
169 ptrsrcy1 += 2;
170 ptrsrcy2 += 2;
171 ptrsrcy3 += 2;
172 ptrsrcy4 += 2;
173
174#if 0
175 (*ptrdestcb1) = (*ptrsrccb1);
176 (*ptrdestcb2) = (*ptrsrccb3);
177#else
178 (*ptrdestcb1) = (*ptrsrccr1);
179 (*ptrdestcb2) = (*ptrsrccr3);
180#endif
181
182#if 0
183 (*ptrdestcr1) = (*ptrsrccr1);
184 (*ptrdestcr2) = (*ptrsrccr3);
185#else
186 (*ptrdestcr1) = (*ptrsrccb1);
187 (*ptrdestcr2) = (*ptrsrccb3);
188#endif
189
190 ptrdestcb1 += 2;
191 ptrdestcb2 += 2;
192 ptrdestcr1 += 2;
193 ptrdestcr2 += 2;
194
195 ptrsrccb1 += 4;
196 ptrsrccb3 += 4;
197 ptrsrccr1 += 4;
198 ptrsrccr3 += 4;
199
200 }
201
202
203 /* Update src pointers */
204 ptrsrcy1 += srcystride;
205 ptrsrcy2 += srcystride;
206 ptrsrcy3 += srcystride;
207 ptrsrcy4 += srcystride;
208
209 ptrsrccb1 += srcccstride;
210 ptrsrccb3 += srcccstride;
211
212 ptrsrccr1 += srcccstride;
213 ptrsrccr3 += srcccstride;
214
215
216 /* Update dest pointers */
217 ptrdesty1 += destystride;
218 ptrdesty2 += destystride;
219 ptrdesty3 += destystride;
220 ptrdesty4 += destystride;
221
222 ptrdestcb1 += destccstride;
223 ptrdestcb2 += destccstride;
224
225 ptrdestcr1 += destccstride;
226 ptrdestcr2 += destccstride;
227
228 }
229}
230
231static inline void yuv_to_rgb24(unsigned char y,unsigned char u,unsigned char v,unsigned char *rgb)
232{
233 register int r,g,b;
234 int rgb24;
235
236 r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10;
237 g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u -128) ) >> 10;
238 b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10;
239
240 r = r > 255 ? 255 : r < 0 ? 0 : r;
241 g = g > 255 ? 255 : g < 0 ? 0 : g;
242 b = b > 255 ? 255 : b < 0 ? 0 : b;
243
244 rgb24 = (int)((r <<16) | (g << 8)| b);
245
246 *rgb = (unsigned char)r;
247 rgb++;
248 *rgb = (unsigned char)g;
249 rgb++;
250 *rgb = (unsigned char)b;
251}
252
253void yuyv422_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height)
254{
255 int x,y,z=0;
256 int blocks;
257
258 blocks = (width * height) * 2;
259
260 for (y = 0,z=0; y < blocks; y+=4,z+=6) {
261 unsigned char Y1, Y2, U, V;
262
263 Y1 = buf[y + 0];
264 U = buf[y + 1];
265 Y2 = buf[y + 2];
266 V = buf[y + 3];
267
268 yuv_to_rgb24(Y1, U, V, &rgb[z]);
269 yuv_to_rgb24(Y2, U, V, &rgb[z + 3]);
270
271 }
272}
273
274void convert_rgb24_to_rgb16(uint8_t *src, uint8_t *dst, int width, int height)
275{
276 int src_len = width*height*3;
277 int i = 0;
278 int j = 0;
279
280 for (i = 0; i < src_len; i += 3)
281 {
282 dst[j] = (src[i]&0x1f) | (src[i+1]>>5);
283 dst[j+1] = ((src[i+1]>>2)<<5) | (src[i+2]>>3);
284 j += 2;
285 }
286}
287void yuyv_to_yv12(unsigned char *src, unsigned char *dst, int width, int height)
288{
289 //width should be an even number.
290 //uv ALIGN 32.
291 int i,j,stride,c_stride,c_size,y_size,cb_offset,cr_offset;
292 unsigned char *dst_copy,*src_copy;
293
294 dst_copy = dst;
295 src_copy = src;
296
297 y_size = width*height;
298 c_stride = ALIGN(width/2, 16);
299 c_size = c_stride * height/2;
300 cr_offset = y_size;
301 cb_offset = y_size+c_size;
302
303 for(i=0;i< y_size;i++){
304 *dst++ = *src;
305 src += 2;
306 }
307
308 dst = dst_copy;
309 src = src_copy;
310
311 for(i=0;i<height;i+=2){
312 for(j=1;j<width*2;j+=4){//one line has 2*width bytes for yuyv.
313 //ceil(u1+u2)/2
314 *(dst+cr_offset+j/4)= (*(src+j+2) + *(src+j+2+width*2) + 1)/2;
315 *(dst+cb_offset+j/4)= (*(src+j) + *(src+j+width*2) + 1)/2;
316 }
317 dst += c_stride;
318 src += width*4;
319 }
320}
321#endif
322void rgb24_memcpy(unsigned char *dst, unsigned char *src, int width, int height)
323{
324 int stride = (width + 31) & ( ~31);
325 int w, h;
326 for (h=0; h<height; h++)
327 {
328 memcpy( dst, src, width*3);
329 dst += width*3;
330 src += stride*3;
331 }
332}
333
334void nv21_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
335{
336 int stride = (width + 31) & ( ~31);
337 int w, h;
338 for (h=0; h<height*3/2; h++)
339 {
340 memcpy( dst, src, width);
341 dst += width;
342 src += stride;
343 }
344}
345
346void yv12_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
347{
348 int new_width = (width + 63) & ( ~63);
349 int stride;
350 int w, h;
351 for (h=0; h<height; h++)
352 {
353 memcpy( dst, src, width);
354 dst += width;
355 src += new_width;
356 }
357
358 stride = ALIGN(width/2, 16);
359 for (h=0; h<height; h++)
360 {
361 memcpy( dst, src, width/2);
362 dst += stride;
363 src += new_width/2;
364 }
365}
366
367void yv12_adjust_memcpy(unsigned char *dst, unsigned char *src, int width, int height)
368{
369 //width should be an even number.
370 int i,stride;
371 memcpy( dst, src, width*height);
372 src += width*height;
373 dst += width*height;
374
375 stride = ALIGN(width/2, 16);
376 for(i =0; i< height; i++)
377 {
378 memcpy(dst,src, stride);
379 src+=width/2;
380 dst+=stride;
381 }
382}
383
384void nv21_memcpy_canvas1080(unsigned char *dst, unsigned char *src, int width, int height)
385{
386 int h;
387 for (h=0; h<height; h++){
388 memcpy( dst, src, width);
389 dst += width;
390 src += width;
391 }
392 src+=width*8;
393 for (h=0; h<height/2; h++){
394 memcpy( dst, src, width);
395 dst += width;
396 src += width;
397 }
398}
399
400void yv12_memcpy_canvas1080(unsigned char *dst, unsigned char *src, int width, int height)
401{
402 int h;
403 for (h=0; h<height; h++){
404 memcpy( dst, src, width);
405 dst += width;
406 src += width;
407 }
408 src+=width*8;
409 for (h=0; h<height/2; h++){
410 memcpy( dst, src, width/2);
411 dst += width/2;
412 src += width/2;
413 }
414 src+=width*2;
415 for (h=0; h<height/2; h++){
416 memcpy( dst, src, width/2);
417 dst += width/2;
418 src += width/2;
419 }
420}
421