• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24 
25 #include <stdint.h>
26 #include <stdlib.h>
27 
28 #include "rgb2yuv.h"
29 
30 static int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256];
31 static int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256];
32 static int RGB2YUV_VG[256], RGB2YUV_VB[256];
33 
rgb2yuv_init(void)34 void rgb2yuv_init(void)
35 {
36 	int i;
37 
38 	for (i = 0; i < 256; i++)
39 		RGB2YUV_YR[i] = 65.481 * (i << 8);
40 
41 	for (i = 0; i < 256; i++)
42 		RGB2YUV_YG[i] = 128.553 * (i << 8);
43 
44 	for (i = 0; i < 256; i++)
45 		RGB2YUV_YB[i] = 24.966 * (i << 8);
46 
47 	for (i = 0; i < 256; i++)
48 		RGB2YUV_UR[i] = 37.797 * (i << 8);
49 
50 	for (i = 0; i < 256; i++)
51 		RGB2YUV_UG[i] = 74.203 * (i << 8);
52 
53 	for (i = 0; i < 256; i++)
54 		RGB2YUV_VG[i] = 93.786 * (i << 8);
55 
56 	for (i = 0; i < 256; i++)
57 		RGB2YUV_VB[i] = 18.214 * (i << 8);
58 
59 	for (i = 0; i < 256; i++)
60 		RGB2YUV_UBVR[i] = 112 * (i << 8);
61 }
62 
rgb2yuv(cairo_surface_t * surface,XvImage * image,uint8_t * yuv)63 int rgb2yuv(cairo_surface_t *surface, XvImage *image, uint8_t *yuv)
64 {
65 	uint8_t *data = cairo_image_surface_get_data(surface);
66 	int rgb_stride = cairo_image_surface_get_stride(surface);
67 	int width = cairo_image_surface_get_width(surface);
68 	int height = cairo_image_surface_get_height(surface);
69 	int y_stride = image->pitches[0];
70 	int uv_stride = image->pitches[1];
71 	uint8_t *tmp, *tl, *tr, *bl, *br;
72 	int i, j;
73 
74 	tmp = malloc(2*width*height);
75 	if (tmp == NULL)
76 		return 0;
77 
78 	tl = tmp;
79 	bl = tmp + width*height;
80 
81 	for (i = 0; i < height; i++) {
82 		uint16_t *rgb = (uint16_t *)(data + i * rgb_stride);
83 		for (j = 0; j < width; j++) {
84 			uint8_t r = (rgb[j] >> 11) & 0x1f;
85 			uint8_t g = (rgb[j] >>  5) & 0x3f;
86 			uint8_t b = (rgb[j] >>  0) & 0x1f;
87 
88 			r = r<<3 | r>>2;
89 			g = g<<2 | g>>4;
90 			b = b<<3 | b>>2;
91 
92 			yuv[j] = (RGB2YUV_YR[r] + RGB2YUV_YG[g] + RGB2YUV_YB[b] + 1048576) >> 16;
93 			*tl++ = (-RGB2YUV_UR[r] - RGB2YUV_UG[g] + RGB2YUV_UBVR[b] + 8388608) >> 16;
94 			*bl++ = (RGB2YUV_UBVR[r] - RGB2YUV_VG[g] - RGB2YUV_VB[b] + 8388608) >> 16;
95 		}
96 		yuv += y_stride;
97 	}
98 
99 	tl = tmp; tr = tl + 1;
100 	bl = tl + width; br = bl + 1;
101 	for (i = 0; i < height/2; i ++) {
102 		for (j = 0; j < width/2; j ++) {
103 			yuv[j] = ((int)*tl + *tr + *bl + *br) >> 2;
104 			tl += 2; tr += 2;
105 			bl += 2; br += 2;
106 		}
107 		yuv += uv_stride;
108 
109 		tl += width; tr += width;
110 		bl += width; br += width;
111 	}
112 
113 	tl = tmp + width*height; tr = tl + 1;
114 	bl = tl + width; br = bl + 1;
115 	for (i = 0; i < height/2; i++) {
116 		for (j = 0; j < width/2; j++) {
117 			yuv[j] = ((int)*tl + *tr + *bl + *br) >> 2;
118 			tl += 2; tr += 2;
119 			bl += 2; br += 2;
120 		}
121 		yuv += uv_stride;
122 
123 		tl += width; tr += width;
124 		bl += width; br += width;
125 	}
126 
127 	free(tmp);
128 	return 1;
129 }
130