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