1#include "gfx_conv_c.h"
2
3#include <strings.h>
4#include <stdio.h>
5
6
7void
8gfx_conv_null(AVFrame *in, AVFrame *out, int width, int height)
9{
10	memcpy(out->data[0], in->data[0], height * in->linesize[0]);
11}
12
13
14void
15gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
16{
17	int i;
18//	bool toggle=false;
19	unsigned long *po_eol;
20	register unsigned long *p;
21	register unsigned long y1;
22	register unsigned long y2;
23	register unsigned short u;
24	register unsigned short v;
25	register unsigned long a;
26	register unsigned long b;
27	register unsigned long c;
28	register unsigned long d;
29//	printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0],
30//		in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1],
31//		out->linesize[2]);
32//	memcpy(out->data[0], in->data[0], height * in->linesize[0]);
33	unsigned long *po = (unsigned long *)out->data[0];
34	unsigned long *pi = (unsigned long *)in->data[0];
35	unsigned short *pi2 = (unsigned short *)in->data[1];
36	unsigned short *pi3 = (unsigned short *)in->data[2];
37	for (i = 0; i < height; i++) {
38		for (p = po,
39			po_eol = (unsigned long *)(((char *)po) + out->linesize[0]);
40			p < po_eol;) {
41//			*(((long *)po) + j) = (long)(*(pi + j) + (*(pi2 + j) << 8)
42//				+ (*(pi + j + 3) << 16) + (*(pi3 + j) << 24));
43			y1 = *pi++;
44			y2 = *pi++;
45			u = *pi2;
46			v = *pi3;
47			a = (long)((y1 & 0x0FF) | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8)
48				| ((v & 0x0FF) << 24));
49			b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF) << 8)
50				| ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF) << 24));
51			c = (long)(y2 & 0x0FF | ((u& 0x0FF00)) | ((y2 & 0x0FF00) << 8)
52				| ((v & 0x0FF00) << 16));
53			d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF00))
54				| ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16));
55//			if (toggle) {
56				pi2++;
57//			} else {
58				pi3++;
59//			}
60//			toggle = !toggle;
61
62			*(p++) = a;
63			*(p++) = b;
64			*(p++) = c;
65			*(p++) = d;
66		}
67		po = (unsigned long *)((char *)po + out->linesize[0]);
68		pi = (unsigned long *)(in->data[0] + i * in->linesize[0]);
69		pi2 = (unsigned short *)(in->data[1] + ((i + 2) / 4)
70			* in->linesize[1]);
71		pi3 = (unsigned short *)(in->data[2] + ((i + 3) / 4)
72			* in->linesize[2]);
73	}
74}
75
76
77void
78gfx_conv_yuv411p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
79{
80	// this one is for cyuv
81	// TODO: (== yuv410p atm)
82	gfx_conv_yuv410p_ycbcr422_c(in, out, width, height);
83}
84
85
86void
87gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
88{
89	unsigned long *po_eol;
90	register unsigned long *p;
91	register unsigned long y1;
92	register unsigned long y2;
93	register unsigned long u;
94	register unsigned long v;
95	register unsigned long a;
96	register unsigned long b;
97	register unsigned long c;
98	register unsigned long d;
99//	printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0],
100//		in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1],
101//		out->linesize[2]);
102//	memcpy(out->data[0], in->data[0], height * in->linesize[0]);
103	unsigned long *po = (unsigned long *)out->data[0];
104	unsigned long *pi = (unsigned long *)in->data[0];
105	unsigned long *pi2 = (unsigned long *)in->data[1];
106	unsigned long *pi3 = (unsigned long *)in->data[2];
107	for (int i = 0; i < height; i++) {
108		for (p = po, po_eol = (unsigned long *)(((char *)po)+out->linesize[0]);
109			p < po_eol;) {
110//			*(((long *)po) + j) = (long)(*(pi + j) + (*(pi2 + j) << 8)
111//				+ (*(pi + j + 3) << 16) + (*(pi3 + j) << 24));
112			y1 = *pi++;
113			y2 = *pi++;
114			u = *pi2++;
115			v = *pi3++;
116			a = (long)(y1 & 0x0FF | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8)
117				| ((v & 0x0FF) << 24));
118			b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF00))
119				| ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16));
120			c = (long)(y2 & 0x0FF | ((u& 0x0FF0000) >> 8)
121				| ((y2 & 0x0FF00) << 8) | ((v & 0x0FF0000) << 8));
122			d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF000000) >> 16)
123				| ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF000000)));
124
125			*(p++) = a;
126			*(p++) = b;
127			*(p++) = c;
128			*(p++) = d;
129		}
130		po = (unsigned long *)((char *)po + out->linesize[0]);
131		pi = (unsigned long *)(in->data[0] + i * in->linesize[0]);
132		pi2 = (unsigned long *)(in->data[1] + ((i + 1) / 2) * in->linesize[1]);
133		pi3 = (unsigned long *)(in->data[2] + (i / 2) * in->linesize[2]);
134	}
135}
136
137void
138gfx_conv_yuv410p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
139{
140	gfx_conv_null(in, out, width, height);
141}
142
143
144void
145gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
146{
147	gfx_conv_null(in, out, width, height);
148}
149
150
151#define CLIP(a) if (0xffffff00 & (uint32)a) { if (a < 0) a = 0; else a = 255; }
152
153// http://en.wikipedia.org/wiki/YUV
154uint32
155YUV444TORGBA8888(uint8 y, uint8 u, uint8 v)
156{
157	int32 c = y - 16;
158	int32 d = u - 128;
159	int32 e = v - 128;
160
161	int32 r = (298 * c + 409 * e + 128) >> 8;
162	int32 g = (298 * c - 100 * d - 208 * e + 128) >> 8;
163	int32 b = (298 * c + 516 * d + 128) >> 8;
164
165	CLIP(r);
166	CLIP(g);
167	CLIP(b);
168
169	return (uint32)((r << 16) | (g << 8) | b);
170}
171
172
173void
174gfx_conv_YCbCr422_RGB32_c(AVFrame *in, AVFrame *out, int width, int height)
175{
176	uint8 *ybase = (uint8 *)in->data[0];
177	uint8 *ubase = (uint8 *)in->data[1];
178	uint8 *vbase = (uint8 *)in->data[2];
179
180	uint32 *rgbbase = (uint32 *)out->data[0];
181
182	int uv_index;
183
184	for (uint32 i = 0; i < height; i++) {
185
186		uv_index = 0;
187
188		for (uint32 j=0; j < width; j+=2) {
189			rgbbase[j] = YUV444TORGBA8888(ybase[j], ubase[uv_index],
190				vbase[uv_index]);
191			rgbbase[j + 1] = YUV444TORGBA8888(ybase[j + 1], ubase[uv_index],
192				vbase[uv_index]);
193
194    		uv_index++;
195		}
196
197		ybase += in->linesize[0];
198		ubase += in->linesize[1];
199		vbase += in->linesize[2];
200
201		rgbbase += out->linesize[0] / 4;
202	}
203
204	if (height & 1) {
205		// XXX special case for last line if height not multiple of 2 goes here
206		memset((height - 1) * out->linesize[0] + (uint8 *)out->data[0], 0,
207			width * 4);
208	}
209
210}
211