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