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

source code of linux/drivers/media/usb/pwc/pwc-dec23.c