blob: bce3d9bfd035597dc05af52ae5f2734bb25a2100 [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
Luc Saillard2b455db2006-04-24 10:29:46 -030054static void build_subblock_pattern(struct pwc_dec23_private *pdec)
55{
56 static const unsigned int initial_values[12] = {
57 -0x526500, -0x221200, 0x221200, 0x526500,
58 -0x3de200, 0x3de200,
59 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
60 -0x12c200, 0x12c200
61
62 };
63 static const unsigned int values_derivated[12] = {
64 0xa4ca, 0x4424, -0x4424, -0xa4ca,
65 0x7bc4, -0x7bc4,
66 0xdb69, 0x5aba, -0x5aba, -0xdb69,
67 0x2584, -0x2584
68 };
69 unsigned int temp_values[12];
70 int i, j;
71
72 memcpy(temp_values, initial_values, sizeof(initial_values));
73 for (i = 0; i < 256; i++) {
74 for (j = 0; j < 12; j++) {
75 pdec->table_subblock[i][j] = temp_values[j];
76 temp_values[j] += values_derivated[j];
77 }
78 }
79}
80
81static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
82{
83 unsigned char *p;
84 unsigned int bit, byte, mask, val;
85 unsigned int bitpower = 1;
86
87 for (bit = 0; bit < 8; bit++) {
88 mask = bitpower - 1;
89 p = pdec->table_bitpowermask[bit];
90 for (byte = 0; byte < 256; byte++) {
91 val = (byte & mask);
92 if (byte & bitpower)
93 val = -val;
94 *p++ = val;
95 }
96 bitpower<<=1;
97 }
98}
99
100
101static void build_table_color(const unsigned int romtable[16][8],
Trent Piepho657de3c2006-06-20 00:30:57 -0300102 unsigned char p0004[16][1024],
Luc Saillard2b455db2006-04-24 10:29:46 -0300103 unsigned char p8004[16][256])
104{
105 int compression_mode, j, k, bit, pw;
106 unsigned char *p0, *p8;
107 const unsigned int *r;
108
109 /* We have 16 compressions tables */
110 for (compression_mode = 0; compression_mode < 16; compression_mode++) {
111 p0 = p0004[compression_mode];
112 p8 = p8004[compression_mode];
113 r = romtable[compression_mode];
114
115 for (j = 0; j < 8; j++, r++, p0 += 128) {
116
117 for (k = 0; k < 16; k++) {
118 if (k == 0)
119 bit = 1;
120 else if (k >= 1 && k < 3)
121 bit = (r[0] >> 15) & 7;
122 else if (k >= 3 && k < 6)
123 bit = (r[0] >> 12) & 7;
124 else if (k >= 6 && k < 10)
125 bit = (r[0] >> 9) & 7;
126 else if (k >= 10 && k < 13)
127 bit = (r[0] >> 6) & 7;
128 else if (k >= 13 && k < 15)
129 bit = (r[0] >> 3) & 7;
130 else
131 bit = (r[0]) & 7;
132 if (k == 0)
133 *p8++ = 8;
134 else
135 *p8++ = j - bit;
136 *p8++ = bit;
137
138 pw = 1 << bit;
139 p0[k + 0x00] = (1 * pw) + 0x80;
140 p0[k + 0x10] = (2 * pw) + 0x80;
141 p0[k + 0x20] = (3 * pw) + 0x80;
142 p0[k + 0x30] = (4 * pw) + 0x80;
143 p0[k + 0x40] = (-1 * pw) + 0x80;
144 p0[k + 0x50] = (-2 * pw) + 0x80;
145 p0[k + 0x60] = (-3 * pw) + 0x80;
146 p0[k + 0x70] = (-4 * pw) + 0x80;
147 } /* end of for (k=0; k<16; k++, p8++) */
148 } /* end of for (j=0; j<8; j++ , table++) */
149 } /* end of foreach compression_mode */
150}
151
152/*
153 *
154 */
155static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
156{
157#define SCALEBITS 15
158#define ONE_HALF (1UL << (SCALEBITS - 1))
159 int i;
160 unsigned int offset1 = ONE_HALF;
161 unsigned int offset2 = 0x0000;
162
163 for (i=0; i<256; i++) {
164 pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
165 pdec->table_d800[i] = offset2;
166
167 offset1 += 0x7bc4;
168 offset2 += 0x7bc4;
169 }
170}
171
172/*
173 * To decode the stream:
174 * if look_bits(2) == 0: # op == 2 in the lookup table
175 * skip_bits(2)
176 * end of the stream
177 * elif look_bits(3) == 7: # op == 1 in the lookup table
178 * skip_bits(3)
179 * yyyy = get_bits(4)
180 * xxxx = get_bits(8)
181 * else: # op == 0 in the lookup table
182 * skip_bits(x)
183 *
184 * For speedup processing, we build a lookup table and we takes the first 6 bits.
185 *
186 * struct {
187 * unsigned char op; // operation to execute
188 * unsigned char bits; // bits use to perform operation
189 * unsigned char offset1; // offset to add to access in the table_0004 % 16
190 * unsigned char offset2; // offset to add to access in the table_0004
191 * }
192 *
193 * How to build this table ?
194 * op == 2 when (i%4)==0
195 * op == 1 when (i%8)==7
196 * op == 0 otherwise
197 *
198 */
199static const unsigned char hash_table_ops[64*4] = {
200 0x02, 0x00, 0x00, 0x00,
201 0x00, 0x03, 0x01, 0x00,
202 0x00, 0x04, 0x01, 0x10,
203 0x00, 0x06, 0x01, 0x30,
204 0x02, 0x00, 0x00, 0x00,
205 0x00, 0x03, 0x01, 0x40,
206 0x00, 0x05, 0x01, 0x20,
207 0x01, 0x00, 0x00, 0x00,
208 0x02, 0x00, 0x00, 0x00,
209 0x00, 0x03, 0x01, 0x00,
210 0x00, 0x04, 0x01, 0x50,
211 0x00, 0x05, 0x02, 0x00,
212 0x02, 0x00, 0x00, 0x00,
213 0x00, 0x03, 0x01, 0x40,
214 0x00, 0x05, 0x03, 0x00,
215 0x01, 0x00, 0x00, 0x00,
216 0x02, 0x00, 0x00, 0x00,
217 0x00, 0x03, 0x01, 0x00,
218 0x00, 0x04, 0x01, 0x10,
219 0x00, 0x06, 0x02, 0x10,
220 0x02, 0x00, 0x00, 0x00,
221 0x00, 0x03, 0x01, 0x40,
222 0x00, 0x05, 0x01, 0x60,
223 0x01, 0x00, 0x00, 0x00,
224 0x02, 0x00, 0x00, 0x00,
225 0x00, 0x03, 0x01, 0x00,
226 0x00, 0x04, 0x01, 0x50,
227 0x00, 0x05, 0x02, 0x40,
228 0x02, 0x00, 0x00, 0x00,
229 0x00, 0x03, 0x01, 0x40,
230 0x00, 0x05, 0x03, 0x40,
231 0x01, 0x00, 0x00, 0x00,
232 0x02, 0x00, 0x00, 0x00,
233 0x00, 0x03, 0x01, 0x00,
234 0x00, 0x04, 0x01, 0x10,
235 0x00, 0x06, 0x01, 0x70,
236 0x02, 0x00, 0x00, 0x00,
237 0x00, 0x03, 0x01, 0x40,
238 0x00, 0x05, 0x01, 0x20,
239 0x01, 0x00, 0x00, 0x00,
240 0x02, 0x00, 0x00, 0x00,
241 0x00, 0x03, 0x01, 0x00,
242 0x00, 0x04, 0x01, 0x50,
243 0x00, 0x05, 0x02, 0x00,
244 0x02, 0x00, 0x00, 0x00,
245 0x00, 0x03, 0x01, 0x40,
246 0x00, 0x05, 0x03, 0x00,
247 0x01, 0x00, 0x00, 0x00,
248 0x02, 0x00, 0x00, 0x00,
249 0x00, 0x03, 0x01, 0x00,
250 0x00, 0x04, 0x01, 0x10,
251 0x00, 0x06, 0x02, 0x50,
252 0x02, 0x00, 0x00, 0x00,
253 0x00, 0x03, 0x01, 0x40,
254 0x00, 0x05, 0x01, 0x60,
255 0x01, 0x00, 0x00, 0x00,
256 0x02, 0x00, 0x00, 0x00,
257 0x00, 0x03, 0x01, 0x00,
258 0x00, 0x04, 0x01, 0x50,
259 0x00, 0x05, 0x02, 0x40,
260 0x02, 0x00, 0x00, 0x00,
261 0x00, 0x03, 0x01, 0x40,
262 0x00, 0x05, 0x03, 0x40,
263 0x01, 0x00, 0x00, 0x00
264};
265
266/*
267 *
268 */
269static const unsigned int MulIdx[16][16] = {
270 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
271 {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
272 {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
273 {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
274 {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
275 {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
276 {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
277 {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
278 {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
279 {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
280 {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
281 {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
282 {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
283 {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
284 {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
285 {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
286};
287
288#if USE_LOOKUP_TABLE_TO_CLAMP
289#define MAX_OUTER_CROP_VALUE (512)
290static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
291#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
292#else
293#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
294#endif
295
296
297/* If the type or the command change, we rebuild the lookup table */
298int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
299{
300 int flags, version, shift, i;
301 struct pwc_dec23_private *pdec;
302
303 if (pwc->decompress_data == NULL) {
304 pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
305 if (pdec == NULL)
306 return -ENOMEM;
307 pwc->decompress_data = pdec;
308 }
309 pdec = pwc->decompress_data;
310
Hans de Goedec20d78c2011-10-09 09:16:46 -0300311 mutex_init(&pdec->lock);
312
Luc Saillard2b455db2006-04-24 10:29:46 -0300313 if (DEVICE_USE_CODEC3(type)) {
314 flags = cmd[2] & 0x18;
315 if (flags == 8)
316 pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
317 else if (flags == 0x10)
318 pdec->nbits = 8;
319 else
320 pdec->nbits = 6;
321
322 version = cmd[2] >> 5;
323 build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
324 build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
325
326 } else {
327
328 flags = cmd[2] & 6;
329 if (flags == 2)
330 pdec->nbits = 7;
331 else if (flags == 4)
332 pdec->nbits = 8;
333 else
334 pdec->nbits = 6;
335
336 version = cmd[2] >> 3;
337 build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
338 build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
339 }
340
341 /* Informations can be coded on a variable number of bits but never less than 8 */
342 shift = 8 - pdec->nbits;
343 pdec->scalebits = SCALEBITS - shift;
344 pdec->nbitsmask = 0xFF >> shift;
345
346 fill_table_dc00_d800(pdec);
347 build_subblock_pattern(pdec);
348 build_bit_powermask_table(pdec);
349
350#if USE_LOOKUP_TABLE_TO_CLAMP
351 /* Build the static table to clamp value [0-255] */
352 for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
353 pwc_crop_table[i] = 0;
354 for (i=0; i<256; i++)
355 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
356 for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
357 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
358#endif
359
360 return 0;
361}
362
363/*
364 * Copy the 4x4 image block to Y plane buffer
365 */
366static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
367{
368#if UNROLL_LOOP_FOR_COPY
369 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
370 const int *c = src;
371 unsigned char *d = dst;
372
373 *d++ = cm[c[0] >> scalebits];
374 *d++ = cm[c[1] >> scalebits];
375 *d++ = cm[c[2] >> scalebits];
376 *d++ = cm[c[3] >> scalebits];
377
378 d = dst + bytes_per_line;
379 *d++ = cm[c[4] >> scalebits];
380 *d++ = cm[c[5] >> scalebits];
381 *d++ = cm[c[6] >> scalebits];
382 *d++ = cm[c[7] >> scalebits];
383
384 d = dst + bytes_per_line*2;
385 *d++ = cm[c[8] >> scalebits];
386 *d++ = cm[c[9] >> scalebits];
387 *d++ = cm[c[10] >> scalebits];
388 *d++ = cm[c[11] >> scalebits];
389
390 d = dst + bytes_per_line*3;
391 *d++ = cm[c[12] >> scalebits];
392 *d++ = cm[c[13] >> scalebits];
393 *d++ = cm[c[14] >> scalebits];
394 *d++ = cm[c[15] >> scalebits];
395#else
396 int i;
397 const int *c = src;
398 unsigned char *d = dst;
399 for (i = 0; i < 4; i++, c++)
400 *d++ = CLAMP((*c) >> scalebits);
401
402 d = dst + bytes_per_line;
403 for (i = 0; i < 4; i++, c++)
404 *d++ = CLAMP((*c) >> scalebits);
405
406 d = dst + bytes_per_line*2;
407 for (i = 0; i < 4; i++, c++)
408 *d++ = CLAMP((*c) >> scalebits);
409
410 d = dst + bytes_per_line*3;
411 for (i = 0; i < 4; i++, c++)
412 *d++ = CLAMP((*c) >> scalebits);
413#endif
414}
415
416/*
417 * Copy the 4x4 image block to a CrCb plane buffer
418 *
419 */
420static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
421{
422#if UNROLL_LOOP_FOR_COPY
423 /* Unroll all loops */
424 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
425 const int *c = src;
426 unsigned char *d = dst;
427
428 *d++ = cm[c[0] >> scalebits];
429 *d++ = cm[c[4] >> scalebits];
430 *d++ = cm[c[1] >> scalebits];
431 *d++ = cm[c[5] >> scalebits];
432 *d++ = cm[c[2] >> scalebits];
433 *d++ = cm[c[6] >> scalebits];
434 *d++ = cm[c[3] >> scalebits];
435 *d++ = cm[c[7] >> scalebits];
436
437 d = dst + bytes_per_line;
438 *d++ = cm[c[12] >> scalebits];
439 *d++ = cm[c[8] >> scalebits];
440 *d++ = cm[c[13] >> scalebits];
441 *d++ = cm[c[9] >> scalebits];
442 *d++ = cm[c[14] >> scalebits];
443 *d++ = cm[c[10] >> scalebits];
444 *d++ = cm[c[15] >> scalebits];
445 *d++ = cm[c[11] >> scalebits];
446#else
447 int i;
448 const int *c1 = src;
449 const int *c2 = src + 4;
450 unsigned char *d = dst;
451
452 for (i = 0; i < 4; i++, c1++, c2++) {
453 *d++ = CLAMP((*c1) >> scalebits);
454 *d++ = CLAMP((*c2) >> scalebits);
455 }
456 c1 = src + 12;
457 d = dst + bytes_per_line;
458 for (i = 0; i < 4; i++, c1++, c2++) {
459 *d++ = CLAMP((*c1) >> scalebits);
460 *d++ = CLAMP((*c2) >> scalebits);
461 }
462#endif
463}
464
Luc Saillard2b455db2006-04-24 10:29:46 -0300465/*
466 * To manage the stream, we keep bits in a 32 bits register.
467 * fill_nbits(n): fill the reservoir with at least n bits
468 * skip_bits(n): discard n bits from the reservoir
469 * get_bits(n): fill the reservoir, returns the first n bits and discard the
470 * bits from the reservoir.
471 * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
472 * contains at least n bits. bits returned is discarded.
473 */
474#define fill_nbits(pdec, nbits_wanted) do { \
475 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
476 { \
477 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
478 pdec->nbits_in_reservoir += 8; \
479 } \
480} while(0);
481
482#define skip_nbits(pdec, nbits_to_skip) do { \
483 pdec->reservoir >>= (nbits_to_skip); \
484 pdec->nbits_in_reservoir -= (nbits_to_skip); \
485} while(0);
486
487#define get_nbits(pdec, nbits_wanted, result) do { \
488 fill_nbits(pdec, nbits_wanted); \
489 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
490 skip_nbits(pdec, nbits_wanted); \
491} while(0);
492
493#define __get_nbits(pdec, nbits_wanted, result) do { \
494 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
495 skip_nbits(pdec, nbits_wanted); \
496} while(0);
497
498#define look_nbits(pdec, nbits_wanted) \
499 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
500
501/*
502 * Decode a 4x4 pixel block
503 */
504static void decode_block(struct pwc_dec23_private *pdec,
505 const unsigned char *ptable0004,
506 const unsigned char *ptable8004)
507{
508 unsigned int primary_color;
509 unsigned int channel_v, offset1, op;
510 int i;
511
512 fill_nbits(pdec, 16);
513 __get_nbits(pdec, pdec->nbits, primary_color);
514
515 if (look_nbits(pdec,2) == 0) {
516 skip_nbits(pdec, 2);
517 /* Very simple, the color is the same for all pixels of the square */
518 for (i = 0; i < 16; i++)
519 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
520
521 return;
522 }
523
524 /* This block is encoded with small pattern */
525 for (i = 0; i < 16; i++)
526 pdec->temp_colors[i] = pdec->table_d800[primary_color];
527
528 __get_nbits(pdec, 3, channel_v);
529 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
530
531 ptable0004 += (channel_v * 128);
532 ptable8004 += (channel_v * 32);
533
534 offset1 = 0;
535 do
536 {
537 unsigned int htable_idx, rows = 0;
538 const unsigned int *block;
539
540 /* [ zzzz y x x ]
541 * xx == 00 :=> end of the block def, remove the two bits from the stream
542 * yxx == 111
543 * yxx == any other value
544 *
545 */
546 fill_nbits(pdec, 16);
547 htable_idx = look_nbits(pdec, 6);
548 op = hash_table_ops[htable_idx * 4];
549
550 if (op == 2) {
551 skip_nbits(pdec, 2);
552
553 } else if (op == 1) {
554 /* 15bits [ xxxx xxxx yyyy 111 ]
555 * yyy => offset in the table8004
556 * xxx => offset in the tabled004 (tree)
557 */
558 unsigned int mask, shift;
559 unsigned int nbits, col1;
560 unsigned int yyyy;
561
562 skip_nbits(pdec, 3);
563 /* offset1 += yyyy */
564 __get_nbits(pdec, 4, yyyy);
565 offset1 += 1 + yyyy;
566 offset1 &= 0x0F;
567 nbits = ptable8004[offset1 * 2];
568
569 /* col1 = xxxx xxxx */
570 __get_nbits(pdec, nbits+1, col1);
571
572 /* Bit mask table */
573 mask = pdec->table_bitpowermask[nbits][col1];
574 shift = ptable8004[offset1 * 2 + 1];
575 rows = ((mask << shift) + 0x80) & 0xFF;
576
577 block = pdec->table_subblock[rows];
578 for (i = 0; i < 16; i++)
579 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
580
581 } else {
582 /* op == 0
583 * offset1 is coded on 3 bits
584 */
585 unsigned int shift;
586
587 offset1 += hash_table_ops [htable_idx * 4 + 2];
588 offset1 &= 0x0F;
589
590 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
591 block = pdec->table_subblock[rows];
592 for (i = 0; i < 16; i++)
593 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
594
595 shift = hash_table_ops[htable_idx * 4 + 1];
596 skip_nbits(pdec, shift);
597 }
598
599 } while (op != 2);
600
601}
602
603static void DecompressBand23(struct pwc_dec23_private *pdec,
604 const unsigned char *rawyuv,
605 unsigned char *planar_y,
606 unsigned char *planar_u,
607 unsigned char *planar_v,
608 unsigned int compressed_image_width,
609 unsigned int real_image_width)
610{
611 int compression_index, nblocks;
612 const unsigned char *ptable0004;
613 const unsigned char *ptable8004;
614
615 pdec->reservoir = 0;
616 pdec->nbits_in_reservoir = 0;
617 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
618
619 get_nbits(pdec, 4, compression_index);
620
621 /* pass 1: uncompress Y component */
622 nblocks = compressed_image_width / 4;
623
624 ptable0004 = pdec->table_0004_pass1[compression_index];
625 ptable8004 = pdec->table_8004_pass1[compression_index];
626
627 /* Each block decode a square of 4x4 */
628 while (nblocks) {
629 decode_block(pdec, ptable0004, ptable8004);
630 copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
631 planar_y += 4;
632 nblocks--;
633 }
634
635 /* pass 2: uncompress UV component */
636 nblocks = compressed_image_width / 8;
637
638 ptable0004 = pdec->table_0004_pass2[compression_index];
639 ptable8004 = pdec->table_8004_pass2[compression_index];
640
641 /* Each block decode a square of 4x4 */
642 while (nblocks) {
643 decode_block(pdec, ptable0004, ptable8004);
644 copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
645
646 decode_block(pdec, ptable0004, ptable8004);
647 copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
648
649 planar_v += 8;
650 planar_u += 8;
651 nblocks -= 2;
652 }
653
654}
655
Luc Saillard2b455db2006-04-24 10:29:46 -0300656/**
657 *
658 * Uncompress a pwc23 buffer.
659 *
660 * pwc.view: size of the image wanted
661 * pwc.image: size of the image returned by the camera
662 * pwc.offset: (x,y) to displayer image in the view
663 *
664 * src: raw data
665 * dst: image output
Luc Saillard2b455db2006-04-24 10:29:46 -0300666 */
667void pwc_dec23_decompress(const struct pwc_device *pwc,
668 const void *src,
Hans de Goededc8a7e82011-12-31 10:52:02 -0300669 void *dst)
Luc Saillard2b455db2006-04-24 10:29:46 -0300670{
671 int bandlines_left, stride, bytes_per_block;
Hans de Goedec20d78c2011-10-09 09:16:46 -0300672 struct pwc_dec23_private *pdec = pwc->decompress_data;
673
Hans de Goededc8a7e82011-12-31 10:52:02 -0300674 /* YUV420P image format */
675 unsigned char *pout_planar_y;
676 unsigned char *pout_planar_u;
677 unsigned char *pout_planar_v;
678 unsigned int plane_size;
679
Hans de Goedec20d78c2011-10-09 09:16:46 -0300680 mutex_lock(&pdec->lock);
Luc Saillard2b455db2006-04-24 10:29:46 -0300681
682 bandlines_left = pwc->image.y / 4;
683 bytes_per_block = pwc->view.x * 4;
Hans de Goededc8a7e82011-12-31 10:52:02 -0300684 plane_size = pwc->view.x * pwc->view.y;
Luc Saillard2b455db2006-04-24 10:29:46 -0300685
Hans de Goededc8a7e82011-12-31 10:52:02 -0300686 /* offset in Y plane */
687 stride = pwc->view.x * pwc->offset.y;
688 pout_planar_y = dst + stride + pwc->offset.x;
Luc Saillard2b455db2006-04-24 10:29:46 -0300689
Hans de Goededc8a7e82011-12-31 10:52:02 -0300690 /* offsets in U/V planes */
691 stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
692 pout_planar_u = dst + plane_size + stride;
693 pout_planar_v = dst + plane_size + plane_size / 4 + stride;
Luc Saillard2b455db2006-04-24 10:29:46 -0300694
Hans de Goededc8a7e82011-12-31 10:52:02 -0300695 while (bandlines_left--) {
696 DecompressBand23(pwc->decompress_data,
697 src,
698 pout_planar_y, pout_planar_u, pout_planar_v,
699 pwc->image.x, pwc->view.x);
700 src += pwc->vbandlength;
701 pout_planar_y += bytes_per_block;
702 pout_planar_u += pwc->view.x;
703 pout_planar_v += pwc->view.x;
Luc Saillard2b455db2006-04-24 10:29:46 -0300704 }
Hans de Goedec20d78c2011-10-09 09:16:46 -0300705 mutex_unlock(&pdec->lock);
Luc Saillard2b455db2006-04-24 10:29:46 -0300706}