1 /*
2
3 # Spca561decoder (C) 2005 Andrzej Szombierski [qq@kuku.eu.org]
4
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as published by
7 # the Free Software Foundation; either version 2.1 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
18
19 # Note this code was originally licensed under the GNU GPL instead of the
20 # GNU LGPL, its license has been changed with permission, see the permission
21 # mail at the end of this file.
22
23 */
24
25 /*
26 * Decoder for compressed spca561 images
27 * It was developed for "Labtec WebCam Elch 2(SPCA561A)" (046d:0929)
28 * but it might work with other spca561 cameras
29 */
30 #include <string.h>
31 #include "libv4lconvert-priv.h"
32
33 /*fixme: not reentrant */
34 static unsigned int bit_bucket;
35 static const unsigned char *input_ptr;
36
refill(int * bitfill)37 static inline void refill(int *bitfill)
38 {
39 if (*bitfill < 8) {
40 bit_bucket = (bit_bucket << 8) | *(input_ptr++);
41 *bitfill += 8;
42 }
43 }
44
nbits(int * bitfill,int n)45 static inline int nbits(int *bitfill, int n)
46 {
47 bit_bucket = (bit_bucket << 8) | *(input_ptr++);
48 *bitfill -= n;
49 return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1);
50 }
51
_nbits(int * bitfill,int n)52 static inline int _nbits(int *bitfill, int n)
53 {
54 *bitfill -= n;
55 return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1);
56 }
57
fun_A(int * bitfill)58 static int fun_A(int *bitfill)
59 {
60 int ret;
61 static int tab[] = {
62 12, 13, 14, 15, 16, 17, 18, 19, -12, -13, -14, -15,
63 -16, -17, -18, -19, -19
64 };
65
66 ret = tab[nbits(bitfill, 4)];
67
68 refill(bitfill);
69 return ret;
70 }
71
fun_B(int * bitfill)72 static int fun_B(int *bitfill)
73 {
74 static int tab1[] = {
75 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31, 31,
76 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
77 16, 17,
78 18,
79 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
80 };
81 static int tab[] = {
82 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -5,
83 -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17,
84 -18, -19
85 };
86 unsigned int tmp;
87
88 tmp = nbits(bitfill, 7) - 68;
89 refill(bitfill);
90 if (tmp > 47)
91 return 0xff;
92 return tab[tab1[tmp]];
93 }
94
fun_C(int * bitfill,int gkw)95 static int fun_C(int *bitfill, int gkw)
96 {
97 static int tab1[] = {
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 23, 23, 23, 23, 23, 23,
99 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
100 12, 13,
101 14,
102 15, 16, 17, 18, 19, 20, 21, 22
103 };
104 static int tab[] = {
105 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -9, -10, -11,
106 -12, -13, -14, -15, -16, -17, -18, -19
107 };
108 unsigned int tmp;
109
110 if (gkw == 0xfe) {
111 if (nbits(bitfill, 1) == 0)
112 return 7;
113
114 return -8;
115 }
116
117 if (gkw != 0xff)
118 return 0xff;
119
120 tmp = nbits(bitfill, 7) - 72;
121 if (tmp > 43)
122 return 0xff;
123
124 refill(bitfill);
125 return tab[tab1[tmp]];
126 }
127
fun_D(int * bitfill,int gkw)128 static int fun_D(int *bitfill, int gkw)
129 {
130 if (gkw == 0xfd) {
131 if (nbits(bitfill, 1) == 0)
132 return 12;
133 return -13;
134 }
135
136 if (gkw == 0xfc) {
137 if (nbits(bitfill, 1) == 0)
138 return 13;
139 return -14;
140 }
141
142 if (gkw == 0xfe) {
143 switch (nbits(bitfill, 2)) {
144 case 0:
145 return 14;
146 case 1:
147 return -15;
148 case 2:
149 return 15;
150 case 3:
151 return -16;
152 }
153 }
154
155 if (gkw == 0xff) {
156 switch (nbits(bitfill, 3)) {
157 case 4:
158 return 16;
159 case 5:
160 return -17;
161 case 6:
162 return 17;
163 case 7:
164 return -18;
165 case 2:
166 return _nbits(bitfill, 1) ? 0xed : 0x12;
167 case 3:
168 (*bitfill)--;
169 return 18;
170 }
171 return 0xff;
172 }
173 return gkw;
174 }
175
fun_E(int cur_byte,int * bitfill)176 static int fun_E(int cur_byte, int *bitfill)
177 {
178 static int tab0[] = { 0, -1, 1, -2, 2, -3, 3, -4 };
179 static int tab1[] = { 4, -5, 5, -6, 6, -7, 7, -8 };
180 static int tab2[] = { 8, -9, 9, -10, 10, -11, 11, -12 };
181 static int tab3[] = { 12, -13, 13, -14, 14, -15, 15, -16 };
182 static int tab4[] = { 16, -17, 17, -18, 18, -19, 19, -19 };
183
184 if ((cur_byte & 0xf0) >= 0x80) {
185 *bitfill -= 4;
186 return tab0[(cur_byte >> 4) & 7];
187 }
188 if ((cur_byte & 0xc0) == 0x40) {
189 *bitfill -= 5;
190 return tab1[(cur_byte >> 3) & 7];
191
192 }
193 if ((cur_byte & 0xe0) == 0x20) {
194 *bitfill -= 6;
195 return tab2[(cur_byte >> 2) & 7];
196
197 }
198 if ((cur_byte & 0xf0) == 0x10) {
199 *bitfill -= 7;
200 return tab3[(cur_byte >> 1) & 7];
201
202 }
203 if ((cur_byte & 0xf8) == 8) {
204 *bitfill -= 8;
205 return tab4[cur_byte & 7];
206 }
207 return 0xff;
208 }
209
fun_F(int cur_byte,int * bitfill)210 static int fun_F(int cur_byte, int *bitfill)
211 {
212 *bitfill -= 5;
213 switch (cur_byte & 0xf8) {
214 case 0x80:
215 return 0;
216 case 0x88:
217 return -1;
218 case 0x90:
219 return 1;
220 case 0x98:
221 return -2;
222 case 0xa0:
223 return 2;
224 case 0xa8:
225 return -3;
226 case 0xb0:
227 return 3;
228 case 0xb8:
229 return -4;
230 case 0xc0:
231 return 4;
232 case 0xc8:
233 return -5;
234 case 0xd0:
235 return 5;
236 case 0xd8:
237 return -6;
238 case 0xe0:
239 return 6;
240 case 0xe8:
241 return -7;
242 case 0xf0:
243 return 7;
244 case 0xf8:
245 return -8;
246 }
247
248 *bitfill -= 1;
249 switch (cur_byte & 0xfc) {
250 case 0x40:
251 return 8;
252 case 0x44:
253 return -9;
254 case 0x48:
255 return 9;
256 case 0x4c:
257 return -10;
258 case 0x50:
259 return 10;
260 case 0x54:
261 return -11;
262 case 0x58:
263 return 11;
264 case 0x5c:
265 return -12;
266 case 0x60:
267 return 12;
268 case 0x64:
269 return -13;
270 case 0x68:
271 return 13;
272 case 0x6c:
273 return -14;
274 case 0x70:
275 return 14;
276 case 0x74:
277 return -15;
278 case 0x78:
279 return 15;
280 case 0x7c:
281 return -16;
282 }
283
284 *bitfill -= 1;
285 switch (cur_byte & 0xfe) {
286 case 0x20:
287 return 16;
288 case 0x22:
289 return -17;
290 case 0x24:
291 return 17;
292 case 0x26:
293 return -18;
294 case 0x28:
295 return 18;
296 case 0x2a:
297 return -19;
298 case 0x2c:
299 return 19;
300 }
301
302 *bitfill += 7;
303 return 0xff;
304 }
305
internal_spca561_decode(int width,int height,const unsigned char * inbuf,unsigned char * outbuf)306 static int internal_spca561_decode(int width, int height,
307 const unsigned char *inbuf,
308 unsigned char *outbuf)
309 {
310 /* buffers */
311 static int accum[8 * 8 * 8];
312 static int i_hits[8 * 8 * 8];
313
314 static const int nbits_A[] = {
315 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
316 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
317 1, 1,
318 1, 1, 1, 1, 1,
319 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
320 1, 1,
321 1, 1, 1, 1, 1,
322 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
323 1, 1,
324 1, 1, 1, 1, 1,
325 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326 1, 1,
327 1, 1, 1, 1, 1,
328 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7,
329 7, 7,
330 7, 7, 7, 7, 7,
331 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
332 3, 3,
333 3, 3, 3, 3, 3,
334 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
335 5, 5,
336 5, 5, 5, 5, 5,
337 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3,
338 3, 3,
339 3, 3, 3, 3, 3,
340 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
341 };
342 static const int tab_A[] = {
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 0, 0,
346 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 0,
349 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0,
352 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
354 0, 0,
355 0, 0, 0, 0,
356 0, 0, 0, 0, 11, -11, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
357 10, 10,
358 255, 254, -4,
359 -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, -10, -10, -1,
360 -1, -1,
361 -1, -1, -1,
362 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
363 -1, -1,
364 -1, -1,
365 -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
366 3, 3, 3,
367 3, 3, 3,
368 -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3,
369 -3, 1,
370 1, 1, 1, 1,
371 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
372 1, 1,
373 1, 1, 1, 1,
374 1
375 };
376
377 static const int nbits_B[] = {
378 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
379 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
380 3, 3,
381 3, 3, 3, 3, 3,
382 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2,
383 2, 2,
384 2, 2, 2, 2, 2,
385 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
386 2, 2,
387 2, 2, 2, 2, 2,
388 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
389 2, 2,
390 2, 2, 2, 2, 2,
391 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
392 1, 1,
393 1, 1, 1, 1, 1,
394 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
395 1, 1,
396 1, 1, 1, 1, 1,
397 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
398 1, 1,
399 1, 1, 1, 1, 1,
400 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
401 1, 1,
402 1, 1, 1, 1, 1,
403 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
404 };
405 static const int tab_B[] = {
406 0xff, -4, 3, 3, -3, -3, -3, -3, 2, 2, 2, 2, 2, 2, 2, 2, -2,
407 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
408 1, 1,
409 1, 1, 1, 1,
410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
411 1, 1,
412 1, 1, 1, 1,
413 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
414 -1, -1,
415 -1, -1,
416 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
417 -1, -1,
418 -1, -1,
419 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
420 -1, -1,
421 -1, -1,
422 -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
423 0, 0, 0,
424 0, 0, 0, 0,
425 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
426 0, 0,
427 0, 0, 0, 0,
428 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
429 0, 0,
430 0, 0, 0, 0,
431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
432 0, 0,
433 0, 0, 0, 0,
434 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
435 0, 0,
436 0, 0, 0, 0,
437 0, 0, 0, 0, 0, 0, 0,
438 };
439
440 static const int nbits_C[] = {
441 0, 0, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5,
442 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
443 4, 4,
444 4, 4, 4, 4, 4,
445 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3,
446 3, 3,
447 3, 3, 3, 3, 3,
448 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
449 3, 3,
450 3, 3, 3, 3, 3,
451 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
452 3, 3,
453 3, 3, 3, 3, 3,
454 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
455 2, 2,
456 2, 2, 2, 2, 2,
457 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
458 2, 2,
459 2, 2, 2, 2, 2,
460 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
461 2, 2,
462 2, 2, 2, 2, 2,
463 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
464 2, 2,
465 2, 2, 2, 2, 2,
466 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
467 };
468 static const int tab_C[] = {
469 0xff, 0xfe, 6, -7, 5, 5, -6, -6, 4, 4, 4, 4, -5, -5, -5, -5,
470 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, -4, 2,
471 2, 2, 2,
472 2, 2, 2,
473 2, 2, 2, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -3, -3,
474 -3, -3,
475 -3, -3, -3,
476 -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
477 1, 1,
478 1, 1, 1, 1,
479 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2,
480 -2, -2,
481 -2, -2, -2,
482 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
483 -2, -2,
484 -2, -2,
485 -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
486 0, 0, 0,
487 0, 0, 0, 0,
488 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
489 0, 0,
490 0, 0, 0, 0,
491 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1,
492 -1, -1,
493 -1, -1, -1,
494 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
495 -1, -1,
496 -1, -1,
497 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
498 -1, -1,
499 -1, -1,
500 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
501 -1,
502 };
503
504 static const int nbits_D[] = {
505 0, 0, 0, 0, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
506 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,
507 5, 5,
508 5, 5, 5, 5, 5,
509 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4,
510 4, 4,
511 4, 4, 4, 4, 4,
512 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
513 4, 4,
514 4, 4, 4, 4, 4,
515 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
516 4, 4,
517 4, 4, 4, 4, 4,
518 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
519 3, 3,
520 3, 3, 3, 3, 3,
521 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
522 3, 3,
523 3, 3, 3, 3, 3,
524 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
525 3, 3,
526 3, 3, 3, 3, 3,
527 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
528 3, 3,
529 3, 3, 3, 3, 3,
530 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
531 };
532 static const int tab_D[] = {
533 0xff, 0xfe, 0xfd, 0xfc, 10, -11, 11, -12, 8, 8, -9, -9, 9, 9,
534 -10, -10, 6, 6, 6, 6, -7, -7, -7, -7, 7, 7, 7, 7, -8, -8,
535 -8, -8,
536 4, 4, 4, 4,
537 4, 4, 4, 4, -5, -5, -5, -5, -5, -5, -5, -5, 5, 5, 5, 5, 5,
538 5, 5, 5,
539 -6, -6,
540 -6, -6, -6, -6, -6, -6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
541 2, 2,
542 2, 2, -3,
543 -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
544 3, 3,
545 3, 3, 3, 3,
546 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4,
547 -4, -4,
548 -4, -4, -4,
549 -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550 0, 0, 0,
551 0, 0, 0, 0,
552 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1,
553 -1, -1,
554 -1, -1, -1,
555 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
556 -1, -1,
557 -1, -1,
558 -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
559 1, 1, 1,
560 1, 1, 1,
561 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, -2,
562 -2, -2,
563 -2, -2, -2,
564 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
565 -2, -2,
566 -2, -2
567 };
568
569 /* a_curve[19 + i] = ... [-19..19] => [-160..160] */
570 static const int a_curve[] = {
571 -160, -144, -128, -112, -98, -88, -80, -72, -64, -56, -48,
572 -40, -32, -24, -18, -12, -8, -5, -2, 0, 2, 5, 8, 12, 18,
573 24, 32,
574 40, 48, 56, 64,
575 72, 80, 88, 98, 112, 128, 144, 160
576 };
577 /* clamp0_255[256 + i] = min(max(i,255),0) */
578 static const unsigned char clamp0_255[] = {
579 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
580 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
581 0, 0,
582 0, 0, 0, 0, 0, 0, 0, 0, 0,
583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
584 0, 0,
585 0, 0, 0, 0, 0, 0, 0, 0, 0,
586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0,
588 0, 0, 0, 0, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0,
591 0, 0, 0, 0, 0, 0, 0, 0, 0,
592 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
593 0, 0,
594 0, 0, 0, 0, 0, 0, 0, 0, 0,
595 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
596 0, 0,
597 0, 0, 0, 0, 0, 0, 0, 0, 0,
598 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
599 0, 0,
600 0, 0, 0, 0, 0, 0, 0, 0, 0,
601 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602 1, 2,
603 3, 4, 5, 6, 7, 8, 9, 10,
604 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
605 26, 27,
606 28, 29, 30, 31, 32, 33,
607 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
608 49, 50,
609 51, 52, 53, 54, 55, 56,
610 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
611 72, 73,
612 74, 75, 76, 77, 78, 79,
613 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
614 95, 96,
615 97, 98, 99, 100, 101,
616 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
617 114,
618 115, 116, 117, 118, 119,
619 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
620 132,
621 133, 134, 135, 136, 137,
622 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
623 150,
624 151, 152, 153, 154, 155,
625 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
626 168,
627 169, 170, 171, 172, 173,
628 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185,
629 186,
630 187, 188, 189, 190, 191,
631 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
632 204,
633 205, 206, 207, 208, 209,
634 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
635 222,
636 223, 224, 225, 226, 227,
637 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
638 240,
639 241, 242, 243, 244, 245,
640 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255,
641 255,
642 255, 255, 255, 255, 255,
643 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
644 255,
645 255, 255, 255, 255, 255,
646 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
647 255,
648 255, 255, 255, 255, 255,
649 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
650 255,
651 255, 255, 255, 255, 255,
652 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
653 255,
654 255, 255, 255, 255, 255,
655 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
656 255,
657 255, 255, 255, 255, 255,
658 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
659 255,
660 255, 255, 255, 255, 255,
661 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
662 255,
663 255, 255, 255, 255, 255,
664 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
665 255,
666 255, 255, 255, 255, 255,
667 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
668 255,
669 255, 255, 255, 255, 255,
670 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
671 255,
672 255, 255, 255, 255, 255,
673 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
674 255,
675 255, 255, 255, 255, 255,
676 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
677 255,
678 255, 255, 255, 255, 255,
679 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
680 255,
681 255, 255, 255, 255, 255,
682 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
683 255,
684 255
685 };
686 /* abs_clamp15[19 + i] = min(abs(i), 15) */
687 static const int abs_clamp15[] = {
688 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
689 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
690 15, 15,
691 15
692 };
693 /* diff_encoding[256 + i] = ... */
694 static const int diff_encoding[] = {
695 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
696 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
697 7, 7,
698 7, 7, 7, 7, 7, 7, 7,
699 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
700 7, 7,
701 7, 7, 7, 7, 7, 7, 7,
702 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
703 7, 7,
704 7, 7, 7, 7, 7, 7, 7,
705 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
706 7, 7,
707 7, 7, 7, 7, 7, 7, 7,
708 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
709 7, 7,
710 7, 7, 7, 7, 7, 7, 7,
711 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
712 7, 7,
713 7, 7, 7, 7, 7, 7, 7,
714 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
715 7, 7,
716 7, 7, 7, 7, 7, 7, 7,
717 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5,
718 5, 5,
719 5, 5, 5, 5, 5, 3, 3,
720 3, 3, 1, 1, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6,
721 6, 6,
722 6, 6, 6, 6, 6, 6, 6,
723 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
724 6, 6,
725 6, 6, 6, 6, 6, 6, 6,
726 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
727 6, 6,
728 6, 6, 6, 6, 6, 6, 6,
729 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
730 6, 6,
731 6, 6, 6, 6, 6, 6, 6,
732 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
733 6, 6,
734 6, 6, 6, 6, 6, 6, 6,
735 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
736 6, 6,
737 6, 6, 6, 6, 6, 6, 6,
738 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
739 6, 6,
740 6, 6, 6, 6, 6, 6, 6,
741 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
742 6, 6,
743 6, 6, 6, 6, 6, 6, 6,
744 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
745 6, 6,
746 6, 6, 6, 6, 6, 6
747 };
748
749 int block;
750 int bitfill = 0;
751 int xwidth = width + 6;
752 int off_up_right = 2 - 2 * xwidth;
753 int off_up_left = -2 - 2 * xwidth;
754 int pixel_U = 0, saved_pixel_UR = 0;
755 int pixel_x = 0, pixel_y = 2;
756 unsigned char *output_ptr = outbuf;
757
758 memset(i_hits, 0, sizeof(i_hits));
759 memset(accum, 0, sizeof(accum));
760
761 memcpy(outbuf + xwidth * 2 + 3, inbuf + 0x14, width);
762 memcpy(outbuf + xwidth * 3 + 3, inbuf + 0x14 + width, width);
763
764 input_ptr = inbuf + 0x14 + width * 2;
765 output_ptr = outbuf + (xwidth) * 4 + 3;
766
767 bit_bucket = 0;
768
769 for (block = 0; block < ((height - 2) * width) / 32; ++block) {
770 int b_it, var_7 = 0;
771 int cur_byte;
772
773 refill(&bitfill);
774
775 cur_byte = (bit_bucket >> (bitfill & 7)) & 0xff;
776
777 if ((cur_byte & 0x80) == 0) {
778 var_7 = 0;
779 bitfill--;
780 } else if ((cur_byte & 0xC0) == 0x80) {
781 var_7 = 1;
782 bitfill -= 2;
783 } else if ((cur_byte & 0xc0) == 0xc0) {
784 var_7 = 2;
785 bitfill -= 2;
786 }
787
788 for (b_it = 0; b_it < 32; b_it++) {
789 int index;
790 int pixel_L, pixel_UR, pixel_UL;
791 int multiplier;
792 int dL, dC, dR;
793 int gkw; /* God knows what */
794
795 refill(&bitfill);
796 cur_byte = bit_bucket >> (bitfill & 7) & 0xff;
797
798 pixel_L = output_ptr[-2];
799 pixel_UR = output_ptr[off_up_right];
800 pixel_UL = output_ptr[off_up_left];
801
802 dL = diff_encoding[0x100 + pixel_UL - pixel_L];
803 dC = diff_encoding[0x100 + pixel_U - pixel_UL];
804 dR = diff_encoding[0x100 + pixel_UR - pixel_U];
805
806 if (pixel_x < 2) {
807 pixel_L = pixel_UL = pixel_U =
808 output_ptr[-xwidth * 2];
809 pixel_UR = output_ptr[off_up_right];
810 dL = dC = 0;
811 dR = diff_encoding[0x100 + pixel_UR -
812 pixel_U];
813 } else if (pixel_x > width - 3)
814 dR = 0;
815
816 multiplier = 4;
817 index = dR + dC * 8 + dL * 64;
818
819 if (pixel_L + pixel_U * 2 <= 144
820 && (pixel_y & 1) == 0
821 && (b_it & 3) == 0 && (dR < 5) && (dC < 5)
822 && (dL < 5)) {
823 multiplier = 1;
824 } else if (pixel_L <= 48
825 && dL <= 4 && dC <= 4 && dL >= 1
826 && dC >= 1) {
827 multiplier = 2;
828 } else if (var_7 == 1) {
829 multiplier = 2;
830 } else if (dC + dL >= 11 || var_7 == 2) {
831 multiplier = 8;
832 }
833
834 if (i_hits[index] < 7) {
835 bitfill -= nbits_A[cur_byte];
836 gkw = tab_A[cur_byte];
837 if (gkw == 0xfe)
838 gkw = fun_A(&bitfill);
839 } else if (i_hits[index] >= accum[index]) {
840 bitfill -= nbits_B[cur_byte];
841 gkw = tab_B[cur_byte];
842 if (cur_byte == 0)
843 gkw = fun_B(&bitfill);
844 } else if (i_hits[index] * 2 >= accum[index]) {
845 bitfill -= nbits_C[cur_byte];
846 gkw = tab_C[cur_byte];
847 if (cur_byte < 2)
848 gkw = fun_C(&bitfill, gkw);
849 } else if (i_hits[index] * 4 >= accum[index]) {
850 bitfill -= nbits_D[cur_byte];
851 gkw = tab_D[cur_byte];
852 if (cur_byte < 4)
853 gkw = fun_D(&bitfill, gkw);
854 } else if (i_hits[index] * 8 >= accum[index]) {
855 gkw = fun_E(cur_byte, &bitfill);
856 } else {
857 gkw = fun_F(cur_byte, &bitfill);
858 }
859
860 if (gkw == 0xff)
861 return -3;
862
863 {
864 int tmp1, tmp2;
865
866 tmp1 =
867 (pixel_U + pixel_L) * 3 - pixel_UL * 2;
868 tmp1 += (tmp1 < 0) ? 3 : 0;
869 tmp2 = a_curve[19 + gkw] * multiplier;
870 tmp2 += (tmp2 < 0) ? 1 : 0;
871
872 *(output_ptr++) =
873 clamp0_255[0x100 + (tmp1 >> 2) -
874 (tmp2 >> 1)];
875 }
876 pixel_U = saved_pixel_UR;
877 saved_pixel_UR = pixel_UR;
878
879 if (++pixel_x == width) {
880 output_ptr += 6;
881 pixel_x = 0;
882 pixel_y++;
883 }
884
885 accum[index] += abs_clamp15[19 + gkw];
886
887 if (i_hits[index]++ == 15) {
888 i_hits[index] = 8;
889 accum[index] /= 2;
890 }
891 }
892 }
893 return 0;
894 }
895
896 /* FIXME, change internal_spca561_decode not to need the extra border
897 around its dest buffer */
v4lconvert_decode_spca561(const unsigned char * inbuf,unsigned char * outbuf,int width,int height)898 void v4lconvert_decode_spca561(const unsigned char *inbuf,
899 unsigned char *outbuf, int width, int height)
900 {
901 int i;
902 static unsigned char tmpbuf[650 * 490];
903
904 if (internal_spca561_decode(width, height, inbuf, tmpbuf) != 0)
905 return;
906 for (i = 0; i < height; i++)
907 memcpy(outbuf + i * width,
908 tmpbuf + (i + 2) * (width + 6) + 3, width);
909 }
910
911 /*************** License Change Permission Notice ***************
912
913 Return-Path: <qq@kuku.eu.org>
914 Received: from koko.hhs.nl ([145.52.2.16] verified)
915 by hhs.nl (CommuniGate Pro SMTP 4.3.6)
916 with ESMTP id 88574071 for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200
917 Received: from exim (helo=koko)
918 by koko.hhs.nl with local-smtp (Exim 4.62)
919 (envelope-from <qq@kuku.eu.org>)
920 id 1K8Fom-0002iJ-3K
921 for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200
922 Received: from [192.87.102.74] (port=41377 helo=filter6-ams.mf.surf.net)
923 by koko.hhs.nl with esmtp (Exim 4.62)
924 (envelope-from <qq@kuku.eu.org>)
925 id 1K8Fol-0002iC-Qo
926 for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:23 +0200
927 Received: from kuku.eu.org (pa90.wielkopole.sdi.tpnet.pl [217.99.123.90])
928 by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5GEa55r001787
929 for <j.w.r.degoede@hhs.nl>; Mon, 16 Jun 2008 16:36:06 +0200
930 Received: (qmail 2243 invoked by uid 500); 16 Jun 2008 14:29:37 -0000
931 Date: Mon, 16 Jun 2008 16:29:37 +0200 (CEST)
932 From: Andrzej Szombierski <qq@kuku.eu.org>
933 To: Hans de Goede <j.w.r.degoede@hhs.nl>
934 Subject: Re: spca561 decoder license question
935 In-Reply-To: <485673B6.4050003@hhs.nl>
936 Message-ID: <Pine.LNX.4.44L.0806161614560.7665-100000@kuku.eu.org>
937 References: <485673B6.4050003@hhs.nl>
938 MIME-Version: 1.0
939 Content-Type: TEXT/PLAIN; charset=iso-8859-2
940 Content-Transfer-Encoding: QUOTED-PRINTABLE
941 X-Canit-CHI2: 0.00
942 X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN)
943 X-Spam-Score: 2.00 (**) [Tag at 6.00] RBL(uceprotect-blacklist.surfnet.nl,2.0)
944 X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default)
945 X-Canit-Stats-ID: 85673281 - 37e52c8b07bc
946 X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74
947 X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 16062008 #776409, status: clean
948
949 On Mon, 16 Jun 2008, Hans de Goede wrote:
950
951 > Hi,
952 >=20
953 > I don't know if you're still subscribed to the spca devel mailing list, s=
954 o let=20
955 > me start with a short intro.
956 >
957 > I'm a Linux enthusiast / developer currently helping Jean-Fran=E7ois Moin=
958 e with=20
959 > porting gspca to video4linux2 and cleaning up the code to get it ready fo=
960 r=20
961 > mainline kernel inclusion.
962 >=20
963 > As part of this process the decompression code for all supported cams mus=
964 t be=20
965 > moved to userspace, as doing in kernel decompression is considered unwant=
966 ed by=20
967 > the mainline people (I agree) as it should be done in userspace.
968 >
969
970 Sounds reasonable.
971 =20
972 > As such I'm working on a library which does decompression of custom cam f=
973 ormats=20
974 > in userspace.
975 >
976
977 Nice. I hope that the library won't be limited to spca-supported webcams,=
978 =20
979 and as an application developer I would be able to just request RGB data=20
980 from any /dev/video*, right?
981
982 > I do not want to license this library as GPL (as the current spca code is=
983 ), as=20
984 > it should be usable by as much software as possible. Instead I want to li=
985 cense=20
986 > it under the LGPL version 2.1 or later.
987
988 Also sounds reasonable.
989
990 >=20
991 > So my question us my I have your permission to relicense your spca561=20
992 > decompression code under the LGPL?
993 >=20
994
995 Yes, of course.=20
996
997 > Thanks & Regards,
998 >=20
999 > Hans
1000 >=20
1001 >
1002
1003 --=20
1004 :: Andrzej Szombierski :: qq@kuku.eu.org :: http://kuku.eu.org ::
1005 :: anszom@bezkitu.com :: radio bez kitu :: http://bezkitu.com ::
1006
1007 */
1008