aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-dec23.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc/pwc-dec23.c')
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c941
1 files changed, 941 insertions, 0 deletions
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
new file mode 100644
index 000000000000..f9096c72cbb7
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -0,0 +1,941 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004-2006 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25*/
26
27#include "pwc-timon.h"
28#include "pwc-kiara.h"
29#include "pwc-dec23.h"
30#include <media/pwc-ioctl.h>
31
32#include <linux/string.h>
33
34/*
35 * USE_LOOKUP_TABLE_TO_CLAMP
36 * 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
37 * 1: use a faster lookup table for cpu with a big cache (intel)
38 */
39#define USE_LOOKUP_TABLE_TO_CLAMP 1
40/*
41 * UNROLL_LOOP_FOR_COPYING_BLOCK
42 * 0: use a loop for a smaller code (but little slower)
43 * 1: when unrolling the loop, gcc produces some faster code (perhaps only
44 * valid for intel processor class). Activating this option, automaticaly
45 * activate USE_LOOKUP_TABLE_TO_CLAMP
46 */
47#define UNROLL_LOOP_FOR_COPY 1
48#if UNROLL_LOOP_FOR_COPY
49# undef USE_LOOKUP_TABLE_TO_CLAMP
50# define USE_LOOKUP_TABLE_TO_CLAMP 1
51#endif
52
53/*
54 * ENABLE_BAYER_DECODER
55 * 0: bayer decoder is not build (save some space)
56 * 1: bayer decoder is build and can be used
57 */
58#define ENABLE_BAYER_DECODER 0
59
60static void build_subblock_pattern(struct pwc_dec23_private *pdec)
61{
62 static const unsigned int initial_values[12] = {
63 -0x526500, -0x221200, 0x221200, 0x526500,
64 -0x3de200, 0x3de200,
65 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
66 -0x12c200, 0x12c200
67
68 };
69 static const unsigned int values_derivated[12] = {
70 0xa4ca, 0x4424, -0x4424, -0xa4ca,
71 0x7bc4, -0x7bc4,
72 0xdb69, 0x5aba, -0x5aba, -0xdb69,
73 0x2584, -0x2584
74 };
75 unsigned int temp_values[12];
76 int i, j;
77
78 memcpy(temp_values, initial_values, sizeof(initial_values));
79 for (i = 0; i < 256; i++) {
80 for (j = 0; j < 12; j++) {
81 pdec->table_subblock[i][j] = temp_values[j];
82 temp_values[j] += values_derivated[j];
83 }
84 }
85}
86
87static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
88{
89 unsigned char *p;
90 unsigned int bit, byte, mask, val;
91 unsigned int bitpower = 1;
92
93 for (bit = 0; bit < 8; bit++) {
94 mask = bitpower - 1;
95 p = pdec->table_bitpowermask[bit];
96 for (byte = 0; byte < 256; byte++) {
97 val = (byte & mask);
98 if (byte & bitpower)
99 val = -val;
100 *p++ = val;
101 }
102 bitpower<<=1;
103 }
104}
105
106
107static void build_table_color(const unsigned int romtable[16][8],
108 unsigned char p0004[16][1024],
109 unsigned char p8004[16][256])
110{
111 int compression_mode, j, k, bit, pw;
112 unsigned char *p0, *p8;
113 const unsigned int *r;
114
115 /* We have 16 compressions tables */
116 for (compression_mode = 0; compression_mode < 16; compression_mode++) {
117 p0 = p0004[compression_mode];
118 p8 = p8004[compression_mode];
119 r = romtable[compression_mode];
120
121 for (j = 0; j < 8; j++, r++, p0 += 128) {
122
123 for (k = 0; k < 16; k++) {
124 if (k == 0)
125 bit = 1;
126 else if (k >= 1 && k < 3)
127 bit = (r[0] >> 15) & 7;
128 else if (k >= 3 && k < 6)
129 bit = (r[0] >> 12) & 7;
130 else if (k >= 6 && k < 10)
131 bit = (r[0] >> 9) & 7;
132 else if (k >= 10 && k < 13)
133 bit = (r[0] >> 6) & 7;
134 else if (k >= 13 && k < 15)
135 bit = (r[0] >> 3) & 7;
136 else
137 bit = (r[0]) & 7;
138 if (k == 0)
139 *p8++ = 8;
140 else
141 *p8++ = j - bit;
142 *p8++ = bit;
143
144 pw = 1 << bit;
145 p0[k + 0x00] = (1 * pw) + 0x80;
146 p0[k + 0x10] = (2 * pw) + 0x80;
147 p0[k + 0x20] = (3 * pw) + 0x80;
148 p0[k + 0x30] = (4 * pw) + 0x80;
149 p0[k + 0x40] = (-1 * pw) + 0x80;
150 p0[k + 0x50] = (-2 * pw) + 0x80;
151 p0[k + 0x60] = (-3 * pw) + 0x80;
152 p0[k + 0x70] = (-4 * pw) + 0x80;
153 } /* end of for (k=0; k<16; k++, p8++) */
154 } /* end of for (j=0; j<8; j++ , table++) */
155 } /* end of foreach compression_mode */
156}
157
158/*
159 *
160 */
161static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
162{
163#define SCALEBITS 15
164#define ONE_HALF (1UL << (SCALEBITS - 1))
165 int i;
166 unsigned int offset1 = ONE_HALF;
167 unsigned int offset2 = 0x0000;
168
169 for (i=0; i<256; i++) {
170 pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
171 pdec->table_d800[i] = offset2;
172
173 offset1 += 0x7bc4;
174 offset2 += 0x7bc4;
175 }
176}
177
178/*
179 * To decode the stream:
180 * if look_bits(2) == 0: # op == 2 in the lookup table
181 * skip_bits(2)
182 * end of the stream
183 * elif look_bits(3) == 7: # op == 1 in the lookup table
184 * skip_bits(3)
185 * yyyy = get_bits(4)
186 * xxxx = get_bits(8)
187 * else: # op == 0 in the lookup table
188 * skip_bits(x)
189 *
190 * For speedup processing, we build a lookup table and we takes the first 6 bits.
191 *
192 * struct {
193 * unsigned char op; // operation to execute
194 * unsigned char bits; // bits use to perform operation
195 * unsigned char offset1; // offset to add to access in the table_0004 % 16
196 * unsigned char offset2; // offset to add to access in the table_0004
197 * }
198 *
199 * How to build this table ?
200 * op == 2 when (i%4)==0
201 * op == 1 when (i%8)==7
202 * op == 0 otherwise
203 *
204 */
205static const unsigned char hash_table_ops[64*4] = {
206 0x02, 0x00, 0x00, 0x00,
207 0x00, 0x03, 0x01, 0x00,
208 0x00, 0x04, 0x01, 0x10,
209 0x00, 0x06, 0x01, 0x30,
210 0x02, 0x00, 0x00, 0x00,
211 0x00, 0x03, 0x01, 0x40,
212 0x00, 0x05, 0x01, 0x20,
213 0x01, 0x00, 0x00, 0x00,
214 0x02, 0x00, 0x00, 0x00,
215 0x00, 0x03, 0x01, 0x00,
216 0x00, 0x04, 0x01, 0x50,
217 0x00, 0x05, 0x02, 0x00,
218 0x02, 0x00, 0x00, 0x00,
219 0x00, 0x03, 0x01, 0x40,
220 0x00, 0x05, 0x03, 0x00,
221 0x01, 0x00, 0x00, 0x00,
222 0x02, 0x00, 0x00, 0x00,
223 0x00, 0x03, 0x01, 0x00,
224 0x00, 0x04, 0x01, 0x10,
225 0x00, 0x06, 0x02, 0x10,
226 0x02, 0x00, 0x00, 0x00,
227 0x00, 0x03, 0x01, 0x40,
228 0x00, 0x05, 0x01, 0x60,
229 0x01, 0x00, 0x00, 0x00,
230 0x02, 0x00, 0x00, 0x00,
231 0x00, 0x03, 0x01, 0x00,
232 0x00, 0x04, 0x01, 0x50,
233 0x00, 0x05, 0x02, 0x40,
234 0x02, 0x00, 0x00, 0x00,
235 0x00, 0x03, 0x01, 0x40,
236 0x00, 0x05, 0x03, 0x40,
237 0x01, 0x00, 0x00, 0x00,
238 0x02, 0x00, 0x00, 0x00,
239 0x00, 0x03, 0x01, 0x00,
240 0x00, 0x04, 0x01, 0x10,
241 0x00, 0x06, 0x01, 0x70,
242 0x02, 0x00, 0x00, 0x00,
243 0x00, 0x03, 0x01, 0x40,
244 0x00, 0x05, 0x01, 0x20,
245 0x01, 0x00, 0x00, 0x00,
246 0x02, 0x00, 0x00, 0x00,
247 0x00, 0x03, 0x01, 0x00,
248 0x00, 0x04, 0x01, 0x50,
249 0x00, 0x05, 0x02, 0x00,
250 0x02, 0x00, 0x00, 0x00,
251 0x00, 0x03, 0x01, 0x40,
252 0x00, 0x05, 0x03, 0x00,
253 0x01, 0x00, 0x00, 0x00,
254 0x02, 0x00, 0x00, 0x00,
255 0x00, 0x03, 0x01, 0x00,
256 0x00, 0x04, 0x01, 0x10,
257 0x00, 0x06, 0x02, 0x50,
258 0x02, 0x00, 0x00, 0x00,
259 0x00, 0x03, 0x01, 0x40,
260 0x00, 0x05, 0x01, 0x60,
261 0x01, 0x00, 0x00, 0x00,
262 0x02, 0x00, 0x00, 0x00,
263 0x00, 0x03, 0x01, 0x00,
264 0x00, 0x04, 0x01, 0x50,
265 0x00, 0x05, 0x02, 0x40,
266 0x02, 0x00, 0x00, 0x00,
267 0x00, 0x03, 0x01, 0x40,
268 0x00, 0x05, 0x03, 0x40,
269 0x01, 0x00, 0x00, 0x00
270};
271
272/*
273 *
274 */
275static const unsigned int MulIdx[16][16] = {
276 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
277 {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
278 {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
279 {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
280 {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
281 {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
282 {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
283 {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
284 {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
285 {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
286 {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
287 {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
288 {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
289 {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
290 {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
291 {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
292};
293
294#if USE_LOOKUP_TABLE_TO_CLAMP
295#define MAX_OUTER_CROP_VALUE (512)
296static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
297#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
298#else
299#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
300#endif
301
302
303/* If the type or the command change, we rebuild the lookup table */
304int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
305{
306 int flags, version, shift, i;
307 struct pwc_dec23_private *pdec;
308
309 if (pwc->decompress_data == NULL) {
310 pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
311 if (pdec == NULL)
312 return -ENOMEM;
313 pwc->decompress_data = pdec;
314 }
315 pdec = pwc->decompress_data;
316
317 if (DEVICE_USE_CODEC3(type)) {
318 flags = cmd[2] & 0x18;
319 if (flags == 8)
320 pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
321 else if (flags == 0x10)
322 pdec->nbits = 8;
323 else
324 pdec->nbits = 6;
325
326 version = cmd[2] >> 5;
327 build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
328 build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
329
330 } else {
331
332 flags = cmd[2] & 6;
333 if (flags == 2)
334 pdec->nbits = 7;
335 else if (flags == 4)
336 pdec->nbits = 8;
337 else
338 pdec->nbits = 6;
339
340 version = cmd[2] >> 3;
341 build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
342 build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
343 }
344
345 /* Informations can be coded on a variable number of bits but never less than 8 */
346 shift = 8 - pdec->nbits;
347 pdec->scalebits = SCALEBITS - shift;
348 pdec->nbitsmask = 0xFF >> shift;
349
350 fill_table_dc00_d800(pdec);
351 build_subblock_pattern(pdec);
352 build_bit_powermask_table(pdec);
353
354#if USE_LOOKUP_TABLE_TO_CLAMP
355 /* Build the static table to clamp value [0-255] */
356 for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
357 pwc_crop_table[i] = 0;
358 for (i=0; i<256; i++)
359 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
360 for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
361 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
362#endif
363
364 return 0;
365}
366
367/*
368 * Copy the 4x4 image block to Y plane buffer
369 */
370static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
371{
372#if UNROLL_LOOP_FOR_COPY
373 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
374 const int *c = src;
375 unsigned char *d = dst;
376
377 *d++ = cm[c[0] >> scalebits];
378 *d++ = cm[c[1] >> scalebits];
379 *d++ = cm[c[2] >> scalebits];
380 *d++ = cm[c[3] >> scalebits];
381
382 d = dst + bytes_per_line;
383 *d++ = cm[c[4] >> scalebits];
384 *d++ = cm[c[5] >> scalebits];
385 *d++ = cm[c[6] >> scalebits];
386 *d++ = cm[c[7] >> scalebits];
387
388 d = dst + bytes_per_line*2;
389 *d++ = cm[c[8] >> scalebits];
390 *d++ = cm[c[9] >> scalebits];
391 *d++ = cm[c[10] >> scalebits];
392 *d++ = cm[c[11] >> scalebits];
393
394 d = dst + bytes_per_line*3;
395 *d++ = cm[c[12] >> scalebits];
396 *d++ = cm[c[13] >> scalebits];
397 *d++ = cm[c[14] >> scalebits];
398 *d++ = cm[c[15] >> scalebits];
399#else
400 int i;
401 const int *c = src;
402 unsigned char *d = dst;
403 for (i = 0; i < 4; i++, c++)
404 *d++ = CLAMP((*c) >> scalebits);
405
406 d = dst + bytes_per_line;
407 for (i = 0; i < 4; i++, c++)
408 *d++ = CLAMP((*c) >> scalebits);
409
410 d = dst + bytes_per_line*2;
411 for (i = 0; i < 4; i++, c++)
412 *d++ = CLAMP((*c) >> scalebits);
413
414 d = dst + bytes_per_line*3;
415 for (i = 0; i < 4; i++, c++)
416 *d++ = CLAMP((*c) >> scalebits);
417#endif
418}
419
420/*
421 * Copy the 4x4 image block to a CrCb plane buffer
422 *
423 */
424static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
425{
426#if UNROLL_LOOP_FOR_COPY
427 /* Unroll all loops */
428 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
429 const int *c = src;
430 unsigned char *d = dst;
431
432 *d++ = cm[c[0] >> scalebits];
433 *d++ = cm[c[4] >> scalebits];
434 *d++ = cm[c[1] >> scalebits];
435 *d++ = cm[c[5] >> scalebits];
436 *d++ = cm[c[2] >> scalebits];
437 *d++ = cm[c[6] >> scalebits];
438 *d++ = cm[c[3] >> scalebits];
439 *d++ = cm[c[7] >> scalebits];
440
441 d = dst + bytes_per_line;
442 *d++ = cm[c[12] >> scalebits];
443 *d++ = cm[c[8] >> scalebits];
444 *d++ = cm[c[13] >> scalebits];
445 *d++ = cm[c[9] >> scalebits];
446 *d++ = cm[c[14] >> scalebits];
447 *d++ = cm[c[10] >> scalebits];
448 *d++ = cm[c[15] >> scalebits];
449 *d++ = cm[c[11] >> scalebits];
450#else
451 int i;
452 const int *c1 = src;
453 const int *c2 = src + 4;
454 unsigned char *d = dst;
455
456 for (i = 0; i < 4; i++, c1++, c2++) {
457 *d++ = CLAMP((*c1) >> scalebits);
458 *d++ = CLAMP((*c2) >> scalebits);
459 }
460 c1 = src + 12;
461 d = dst + bytes_per_line;
462 for (i = 0; i < 4; i++, c1++, c2++) {
463 *d++ = CLAMP((*c1) >> scalebits);
464 *d++ = CLAMP((*c2) >> scalebits);
465 }
466#endif
467}
468
469#if ENABLE_BAYER_DECODER
470/*
471 * Format: 8x2 pixels
472 * . G . G . G . G . G . G . G
473 * . . . . . . . . . . . . . .
474 * . G . G . G . G . G . G . G
475 * . . . . . . . . . . . . . .
476 * or
477 * . . . . . . . . . . . . . .
478 * G . G . G . G . G . G . G .
479 * . . . . . . . . . . . . . .
480 * G . G . G . G . G . G . G .
481*/
482static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
483{
484#if UNROLL_LOOP_FOR_COPY
485 /* Unroll all loops */
486 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
487 unsigned char *d = dst;
488 const int *c = src;
489
490 d[0] = cm[c[0] >> scalebits];
491 d[2] = cm[c[1] >> scalebits];
492 d[4] = cm[c[2] >> scalebits];
493 d[6] = cm[c[3] >> scalebits];
494 d[8] = cm[c[4] >> scalebits];
495 d[10] = cm[c[5] >> scalebits];
496 d[12] = cm[c[6] >> scalebits];
497 d[14] = cm[c[7] >> scalebits];
498
499 d = dst + bytes_per_line;
500 d[0] = cm[c[8] >> scalebits];
501 d[2] = cm[c[9] >> scalebits];
502 d[4] = cm[c[10] >> scalebits];
503 d[6] = cm[c[11] >> scalebits];
504 d[8] = cm[c[12] >> scalebits];
505 d[10] = cm[c[13] >> scalebits];
506 d[12] = cm[c[14] >> scalebits];
507 d[14] = cm[c[15] >> scalebits];
508#else
509 int i;
510 unsigned char *d;
511 const int *c = src;
512
513 d = dst;
514 for (i = 0; i < 8; i++, c++)
515 d[i*2] = CLAMP((*c) >> scalebits);
516
517 d = dst + bytes_per_line;
518 for (i = 0; i < 8; i++, c++)
519 d[i*2] = CLAMP((*c) >> scalebits);
520#endif
521}
522#endif
523
524#if ENABLE_BAYER_DECODER
525/*
526 * Format: 4x4 pixels
527 * R . R . R . R
528 * . B . B . B .
529 * R . R . R . R
530 * . B . B . B .
531 */
532static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
533{
534#if UNROLL_LOOP_FOR_COPY
535 /* Unroll all loops */
536 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
537 unsigned char *d = dst;
538 const int *c = src;
539
540 d[0] = cm[c[0] >> scalebits];
541 d[2] = cm[c[1] >> scalebits];
542 d[4] = cm[c[2] >> scalebits];
543 d[6] = cm[c[3] >> scalebits];
544
545 d = dst + bytes_per_line;
546 d[1] = cm[c[4] >> scalebits];
547 d[3] = cm[c[5] >> scalebits];
548 d[5] = cm[c[6] >> scalebits];
549 d[7] = cm[c[7] >> scalebits];
550
551 d = dst + bytes_per_line*2;
552 d[0] = cm[c[8] >> scalebits];
553 d[2] = cm[c[9] >> scalebits];
554 d[4] = cm[c[10] >> scalebits];
555 d[6] = cm[c[11] >> scalebits];
556
557 d = dst + bytes_per_line*3;
558 d[1] = cm[c[12] >> scalebits];
559 d[3] = cm[c[13] >> scalebits];
560 d[5] = cm[c[14] >> scalebits];
561 d[7] = cm[c[15] >> scalebits];
562#else
563 int i;
564 unsigned char *d;
565 const int *c = src;
566
567 d = dst;
568 for (i = 0; i < 4; i++, c++)
569 d[i*2] = CLAMP((*c) >> scalebits);
570
571 d = dst + bytes_per_line;
572 for (i = 0; i < 4; i++, c++)
573 d[i*2+1] = CLAMP((*c) >> scalebits);
574
575 d = dst + bytes_per_line*2;
576 for (i = 0; i < 4; i++, c++)
577 d[i*2] = CLAMP((*c) >> scalebits);
578
579 d = dst + bytes_per_line*3;
580 for (i = 0; i < 4; i++, c++)
581 d[i*2+1] = CLAMP((*c) >> scalebits);
582#endif
583}
584#endif
585
586/*
587 * To manage the stream, we keep bits in a 32 bits register.
588 * fill_nbits(n): fill the reservoir with at least n bits
589 * skip_bits(n): discard n bits from the reservoir
590 * get_bits(n): fill the reservoir, returns the first n bits and discard the
591 * bits from the reservoir.
592 * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
593 * contains at least n bits. bits returned is discarded.
594 */
595#define fill_nbits(pdec, nbits_wanted) do { \
596 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
597 { \
598 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
599 pdec->nbits_in_reservoir += 8; \
600 } \
601} while(0);
602
603#define skip_nbits(pdec, nbits_to_skip) do { \
604 pdec->reservoir >>= (nbits_to_skip); \
605 pdec->nbits_in_reservoir -= (nbits_to_skip); \
606} while(0);
607
608#define get_nbits(pdec, nbits_wanted, result) do { \
609 fill_nbits(pdec, nbits_wanted); \
610 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
611 skip_nbits(pdec, nbits_wanted); \
612} while(0);
613
614#define __get_nbits(pdec, nbits_wanted, result) do { \
615 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
616 skip_nbits(pdec, nbits_wanted); \
617} while(0);
618
619#define look_nbits(pdec, nbits_wanted) \
620 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
621
622/*
623 * Decode a 4x4 pixel block
624 */
625static void decode_block(struct pwc_dec23_private *pdec,
626 const unsigned char *ptable0004,
627 const unsigned char *ptable8004)
628{
629 unsigned int primary_color;
630 unsigned int channel_v, offset1, op;
631 int i;
632
633 fill_nbits(pdec, 16);
634 __get_nbits(pdec, pdec->nbits, primary_color);
635
636 if (look_nbits(pdec,2) == 0) {
637 skip_nbits(pdec, 2);
638 /* Very simple, the color is the same for all pixels of the square */
639 for (i = 0; i < 16; i++)
640 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
641
642 return;
643 }
644
645 /* This block is encoded with small pattern */
646 for (i = 0; i < 16; i++)
647 pdec->temp_colors[i] = pdec->table_d800[primary_color];
648
649 __get_nbits(pdec, 3, channel_v);
650 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
651
652 ptable0004 += (channel_v * 128);
653 ptable8004 += (channel_v * 32);
654
655 offset1 = 0;
656 do
657 {
658 unsigned int htable_idx, rows = 0;
659 const unsigned int *block;
660
661 /* [ zzzz y x x ]
662 * xx == 00 :=> end of the block def, remove the two bits from the stream
663 * yxx == 111
664 * yxx == any other value
665 *
666 */
667 fill_nbits(pdec, 16);
668 htable_idx = look_nbits(pdec, 6);
669 op = hash_table_ops[htable_idx * 4];
670
671 if (op == 2) {
672 skip_nbits(pdec, 2);
673
674 } else if (op == 1) {
675 /* 15bits [ xxxx xxxx yyyy 111 ]
676 * yyy => offset in the table8004
677 * xxx => offset in the tabled004 (tree)
678 */
679 unsigned int mask, shift;
680 unsigned int nbits, col1;
681 unsigned int yyyy;
682
683 skip_nbits(pdec, 3);
684 /* offset1 += yyyy */
685 __get_nbits(pdec, 4, yyyy);
686 offset1 += 1 + yyyy;
687 offset1 &= 0x0F;
688 nbits = ptable8004[offset1 * 2];
689
690 /* col1 = xxxx xxxx */
691 __get_nbits(pdec, nbits+1, col1);
692
693 /* Bit mask table */
694 mask = pdec->table_bitpowermask[nbits][col1];
695 shift = ptable8004[offset1 * 2 + 1];
696 rows = ((mask << shift) + 0x80) & 0xFF;
697
698 block = pdec->table_subblock[rows];
699 for (i = 0; i < 16; i++)
700 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
701
702 } else {
703 /* op == 0
704 * offset1 is coded on 3 bits
705 */
706 unsigned int shift;
707
708 offset1 += hash_table_ops [htable_idx * 4 + 2];
709 offset1 &= 0x0F;
710
711 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
712 block = pdec->table_subblock[rows];
713 for (i = 0; i < 16; i++)
714 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
715
716 shift = hash_table_ops[htable_idx * 4 + 1];
717 skip_nbits(pdec, shift);
718 }
719
720 } while (op != 2);
721
722}
723
724static void DecompressBand23(struct pwc_dec23_private *pdec,
725 const unsigned char *rawyuv,
726 unsigned char *planar_y,
727 unsigned char *planar_u,
728 unsigned char *planar_v,
729 unsigned int compressed_image_width,
730 unsigned int real_image_width)
731{
732 int compression_index, nblocks;
733 const unsigned char *ptable0004;
734 const unsigned char *ptable8004;
735
736 pdec->reservoir = 0;
737 pdec->nbits_in_reservoir = 0;
738 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
739
740 get_nbits(pdec, 4, compression_index);
741
742 /* pass 1: uncompress Y component */
743 nblocks = compressed_image_width / 4;
744
745 ptable0004 = pdec->table_0004_pass1[compression_index];
746 ptable8004 = pdec->table_8004_pass1[compression_index];
747
748 /* Each block decode a square of 4x4 */
749 while (nblocks) {
750 decode_block(pdec, ptable0004, ptable8004);
751 copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
752 planar_y += 4;
753 nblocks--;
754 }
755
756 /* pass 2: uncompress UV component */
757 nblocks = compressed_image_width / 8;
758
759 ptable0004 = pdec->table_0004_pass2[compression_index];
760 ptable8004 = pdec->table_8004_pass2[compression_index];
761
762 /* Each block decode a square of 4x4 */
763 while (nblocks) {
764 decode_block(pdec, ptable0004, ptable8004);
765 copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
766
767 decode_block(pdec, ptable0004, ptable8004);
768 copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
769
770 planar_v += 8;
771 planar_u += 8;
772 nblocks -= 2;
773 }
774
775}
776
777#if ENABLE_BAYER_DECODER
778/*
779 * Size need to be a multiple of 8 in width
780 *
781 * Return a block of four line encoded like this:
782 *
783 * G R G R G R G R G R G R G R G R
784 * B G B G B G B G B G B G B G B G
785 * G R G R G R G R G R G R G R G R
786 * B G B G B G B G B G B G B G B G
787 *
788 */
789static void DecompressBandBayer(struct pwc_dec23_private *pdec,
790 const unsigned char *rawyuv,
791 unsigned char *rgbbayer,
792 unsigned int compressed_image_width,
793 unsigned int real_image_width)
794{
795 int compression_index, nblocks;
796 const unsigned char *ptable0004;
797 const unsigned char *ptable8004;
798 unsigned char *dest;
799
800 pdec->reservoir = 0;
801 pdec->nbits_in_reservoir = 0;
802 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
803
804 get_nbits(pdec, 4, compression_index);
805
806 /* pass 1: uncompress RB component */
807 nblocks = compressed_image_width / 4;
808
809 ptable0004 = pdec->table_0004_pass1[compression_index];
810 ptable8004 = pdec->table_8004_pass1[compression_index];
811 dest = rgbbayer;
812
813 /* Each block decode a square of 4x4 */
814 while (nblocks) {
815 decode_block(pdec, ptable0004, ptable8004);
816 copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);
817 dest += 8;
818 nblocks--;
819 }
820
821 /* pass 2: uncompress G component */
822 nblocks = compressed_image_width / 8;
823
824 ptable0004 = pdec->table_0004_pass2[compression_index];
825 ptable8004 = pdec->table_8004_pass2[compression_index];
826
827 /* Each block decode a square of 4x4 */
828 while (nblocks) {
829 decode_block(pdec, ptable0004, ptable8004);
830 copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);
831
832 decode_block(pdec, ptable0004, ptable8004);
833 copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);
834
835 rgbbayer += 16;
836 nblocks -= 2;
837 }
838}
839#endif
840
841
842/**
843 *
844 * Uncompress a pwc23 buffer.
845 *
846 * pwc.view: size of the image wanted
847 * pwc.image: size of the image returned by the camera
848 * pwc.offset: (x,y) to displayer image in the view
849 *
850 * src: raw data
851 * dst: image output
852 * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER
853 */
854void pwc_dec23_decompress(const struct pwc_device *pwc,
855 const void *src,
856 void *dst,
857 int flags)
858{
859 int bandlines_left, stride, bytes_per_block;
860
861 bandlines_left = pwc->image.y / 4;
862 bytes_per_block = pwc->view.x * 4;
863
864 if (flags & PWCX_FLAG_BAYER) {
865#if ENABLE_BAYER_DECODER
866 /* RGB Bayer format */
867 unsigned char *rgbout;
868
869 stride = pwc->view.x * pwc->offset.y;
870 rgbout = dst + stride + pwc->offset.x;
871
872
873 while (bandlines_left--) {
874
875 DecompressBandBayer(pwc->decompress_data,
876 src,
877 rgbout,
878 pwc->image.x, pwc->view.x);
879
880 src += pwc->vbandlength;
881 rgbout += bytes_per_block;
882
883 }
884#else
885 memcpy(dst, 0, pwc->view.x * pwc->view.y);
886#endif
887
888 } else {
889 /* YUV420P image format */
890 unsigned char *pout_planar_y;
891 unsigned char *pout_planar_u;
892 unsigned char *pout_planar_v;
893 unsigned int plane_size;
894
895 plane_size = pwc->view.x * pwc->view.y;
896
897 /* offset in Y plane */
898 stride = pwc->view.x * pwc->offset.y;
899 pout_planar_y = dst + stride + pwc->offset.x;
900
901 /* offsets in U/V planes */
902 stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
903 pout_planar_u = dst + plane_size + stride;
904 pout_planar_v = dst + plane_size + plane_size / 4 + stride;
905
906 while (bandlines_left--) {
907
908 DecompressBand23(pwc->decompress_data,
909 src,
910 pout_planar_y, pout_planar_u, pout_planar_v,
911 pwc->image.x, pwc->view.x);
912 src += pwc->vbandlength;
913 pout_planar_y += bytes_per_block;
914 pout_planar_u += pwc->view.x;
915 pout_planar_v += pwc->view.x;
916
917 }
918
919 }
920
921}
922
923void pwc_dec23_exit(void)
924{
925 /* Do nothing */
926
927}
928
929/**
930 * Allocate a private structure used by lookup table.
931 * You must call kfree() to free the memory allocated.
932 */
933int pwc_dec23_alloc(struct pwc_device *pwc)
934{
935 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
936 if (pwc->decompress_data == NULL)
937 return -ENOMEM;
938 return 0;
939}
940
941/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */