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