• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 #             (C) 2008 Hans de Goede <hdegoede@redhat.com>
3 
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU Lesser General Public License as published by
6 # the Free Software Foundation; either version 2.1 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335  USA
17  */
18 
19 #include <string.h>
20 #include "libv4lconvert-priv.h"
21 
22 /* YUYV per line */
v4lconvert_spca501_to_yuv420(const unsigned char * src,unsigned char * dst,int width,int height,int yvu)23 void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst,
24 		int width, int height, int yvu)
25 {
26 	int i, j;
27 	unsigned long *lsrc = (unsigned long *)src;
28 
29 	for (i = 0; i < height; i += 2) {
30 		/* -128 - 127 --> 0 - 255 and copy first line Y */
31 		unsigned long *ldst = (unsigned long *)(dst + i * width);
32 
33 		for (j = 0; j < width; j += sizeof(long)) {
34 			*ldst = *lsrc++;
35 			*ldst++ ^= 0x8080808080808080ULL;
36 		}
37 
38 		/* -128 - 127 --> 0 - 255 and copy 1 line U */
39 		if (yvu)
40 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
41 		else
42 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
43 		for (j = 0; j < width/2; j += sizeof(long)) {
44 			*ldst = *lsrc++;
45 			*ldst++ ^= 0x8080808080808080ULL;
46 		}
47 
48 		/* -128 - 127 --> 0 - 255 and copy second line Y */
49 		ldst = (unsigned long *)(dst + i * width + width);
50 		for (j = 0; j < width; j += sizeof(long)) {
51 			*ldst = *lsrc++;
52 			*ldst++ ^= 0x8080808080808080ULL;
53 		}
54 
55 		/* -128 - 127 --> 0 - 255 and copy 1 line V */
56 		if (yvu)
57 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
58 		else
59 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
60 		for (j = 0; j < width/2; j += sizeof(long)) {
61 			*ldst = *lsrc++;
62 			*ldst++ ^= 0x8080808080808080ULL;
63 		}
64 	}
65 }
66 
67 /* YYUV per line */
v4lconvert_spca505_to_yuv420(const unsigned char * src,unsigned char * dst,int width,int height,int yvu)68 void v4lconvert_spca505_to_yuv420(const unsigned char *src, unsigned char *dst,
69 		int width, int height, int yvu)
70 {
71 	int i, j;
72 	unsigned long *lsrc = (unsigned long *)src;
73 
74 	for (i = 0; i < height; i += 2) {
75 		/* -128 - 127 --> 0 - 255 and copy 2 lines of Y */
76 		unsigned long *ldst = (unsigned long *)(dst + i * width);
77 
78 		for (j = 0; j < width*2; j += sizeof(long)) {
79 			*ldst = *lsrc++;
80 			*ldst++ ^= 0x8080808080808080ULL;
81 		}
82 
83 		/* -128 - 127 --> 0 - 255 and copy 1 line U */
84 		if (yvu)
85 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
86 		else
87 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
88 		for (j = 0; j < width/2; j += sizeof(long)) {
89 			*ldst = *lsrc++;
90 			*ldst++ ^= 0x8080808080808080ULL;
91 		}
92 
93 		/* -128 - 127 --> 0 - 255 and copy 1 line V */
94 		if (yvu)
95 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
96 		else
97 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
98 		for (j = 0; j < width/2; j += sizeof(long)) {
99 			*ldst = *lsrc++;
100 			*ldst++ ^= 0x8080808080808080ULL;
101 		}
102 	}
103 }
104 
105 /* YUVY per line */
v4lconvert_spca508_to_yuv420(const unsigned char * src,unsigned char * dst,int width,int height,int yvu)106 void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char *dst,
107 		int width, int height, int yvu)
108 {
109 	int i, j;
110 	unsigned long *lsrc = (unsigned long *)src;
111 
112 	for (i = 0; i < height; i += 2) {
113 		/* -128 - 127 --> 0 - 255 and copy first line Y */
114 		unsigned long *ldst = (unsigned long *)(dst + i * width);
115 		for (j = 0; j < width; j += sizeof(long)) {
116 			*ldst = *lsrc++;
117 			*ldst++ ^= 0x8080808080808080ULL;
118 		}
119 
120 		/* -128 - 127 --> 0 - 255 and copy 1 line U */
121 		if (yvu)
122 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
123 		else
124 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
125 		for (j = 0; j < width/2; j += sizeof(long)) {
126 			*ldst = *lsrc++;
127 			*ldst++ ^= 0x8080808080808080ULL;
128 		}
129 
130 		/* -128 - 127 --> 0 - 255 and copy 1 line V */
131 		if (yvu)
132 			ldst = (unsigned long *)(dst + width * height + i * width / 4);
133 		else
134 			ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4);
135 		for (j = 0; j < width/2; j += sizeof(long)) {
136 			*ldst = *lsrc++;
137 			*ldst++ ^= 0x8080808080808080ULL;
138 		}
139 
140 		/* -128 - 127 --> 0 - 255 and copy second line Y */
141 		ldst = (unsigned long *)(dst + i * width + width);
142 		for (j = 0; j < width; j += sizeof(long)) {
143 			*ldst = *lsrc++;
144 			*ldst++ ^= 0x8080808080808080ULL;
145 		}
146 	}
147 }
148 
149 /* Note this is not a spca specific format, bit it fits in this file in that
150    it is another funny yuv format */
151 /* one line of Y then 1 line of VYUY */
v4lconvert_cit_yyvyuy_to_yuv420(const unsigned char * src,unsigned char * ydest,int width,int height,int yvu)152 void v4lconvert_cit_yyvyuy_to_yuv420(const unsigned char *src,
153 		unsigned char *ydest,
154 		int width, int height, int yvu)
155 {
156 	int x, y;
157 	unsigned char *udest, *vdest;
158 
159 	if (yvu) {
160 		vdest = ydest + width * height;
161 		udest = vdest + (width * height) / 4;
162 	} else {
163 		udest = ydest + width * height;
164 		vdest = udest + (width * height) / 4;
165 	}
166 
167 	for (y = 0; y < height; y += 2) {
168 		/* copy 1 line of Y */
169 		memcpy(ydest, src, width);
170 		src += width;
171 		ydest += width;
172 
173 		/* Split one line of VYUY */
174 		for (x = 0; x < width; x += 2) {
175 			*vdest++ = *src++;
176 			*ydest++ = *src++;
177 			*udest++ = *src++;
178 			*ydest++ = *src++;
179 		}
180 	}
181 }
182 
183 /* Note this is not a spca specific format, but it fits in this file in that
184    it is another funny yuv format */
185 /* The konica gspca subdriver using cams send data in blocks of 256 pixels
186    in YUV420 format. */
v4lconvert_konica_yuv420_to_yuv420(const unsigned char * src,unsigned char * ydest,int width,int height,int yvu)187 void v4lconvert_konica_yuv420_to_yuv420(const unsigned char *src,
188 		unsigned char *ydest,
189 		int width, int height, int yvu)
190 {
191 	int i, no_blocks;
192 	unsigned char *udest, *vdest;
193 
194 	if (yvu) {
195 		vdest = ydest + width * height;
196 		udest = vdest + (width * height) / 4;
197 	} else {
198 		udest = ydest + width * height;
199 		vdest = udest + (width * height) / 4;
200 	}
201 
202 	no_blocks = width * height / 256;
203 	for (i = 0; i < no_blocks; i++) {
204 		/* copy 256 Y pixels */
205 		memcpy(ydest, src, 256);
206 		src += 256;
207 		ydest += 256;
208 
209 		/* copy 64 U pixels */
210 		memcpy(udest, src, 64);
211 		src += 64;
212 		udest += 64;
213 
214 		/* copy 64 V pixels */
215 		memcpy(vdest, src, 64);
216 		src += 64;
217 		vdest += 64;
218 	}
219 }
220 
221 /* And another not a spca specific format, but fitting in this file in that
222    it is another funny yuv format */
223 /* Two lines of Y then 1 line of UV */
v4lconvert_m420_to_yuv420(const unsigned char * src,unsigned char * ydest,int width,int height,int yvu)224 void v4lconvert_m420_to_yuv420(const unsigned char *src,
225 		unsigned char *ydest,
226 		int width, int height, int yvu)
227 {
228 	int x, y;
229 	unsigned char *udest, *vdest;
230 
231 	if (yvu) {
232 		vdest = ydest + width * height;
233 		udest = vdest + (width * height) / 4;
234 	} else {
235 		udest = ydest + width * height;
236 		vdest = udest + (width * height) / 4;
237 	}
238 
239 	for (y = 0; y < height; y += 2) {
240 		/* copy 2 lines of Y */
241 		memcpy(ydest, src, 2 * width);
242 		src += 2 * width;
243 		ydest += 2 * width;
244 
245 		/* Split one line of UV */
246 		for (x = 0; x < width; x += 2) {
247 			*udest++ = *src++;
248 			*vdest++ = *src++;
249 		}
250 	}
251 }
252