• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
build_subblock_pattern(struct pwc_dec23_private * pdec)41 static 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 
build_bit_powermask_table(struct pwc_dec23_private * pdec)68 static 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 
build_table_color(const unsigned int romtable[16][8],unsigned char p0004[16][1024],unsigned char p8004[16][256])88 static 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  */
fill_table_dc00_d800(struct pwc_dec23_private * pdec)142 static 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  */
186 static 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  */
256 static 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)
277 static 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 */
pwc_dec23_init(struct pwc_device * pdev,const unsigned char * cmd)285 void 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(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
306 		build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, 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(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
320 		build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, 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  */
copy_image_block_Y(const int * src,unsigned char * dst,unsigned int bytes_per_line,unsigned int scalebits)349 static 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  */
copy_image_block_CrCb(const int * src,unsigned char * dst,unsigned int bytes_per_line,unsigned int scalebits)403 static 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  */
decode_block(struct pwc_dec23_private * pdec,const unsigned char * ptable0004,const unsigned char * ptable8004)487 static 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 
DecompressBand23(struct pwc_dec23_private * pdec,const unsigned char * rawyuv,unsigned char * planar_y,unsigned char * planar_u,unsigned char * planar_v,unsigned int compressed_image_width,unsigned int real_image_width)586 static 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(pdec->temp_colors, planar_y, real_image_width, 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(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
628 
629 		decode_block(pdec, ptable0004, ptable8004);
630 		copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
631 
632 		planar_v += 8;
633 		planar_u += 8;
634 		nblocks -= 2;
635 	}
636 
637 }
638 
639 /**
640  * Uncompress a pwc23 buffer.
641  * @pdev: pointer to pwc device's internal struct
642  * @src: raw data
643  * @dst: image output
644  */
pwc_dec23_decompress(struct pwc_device * pdev,const void * src,void * dst)645 void 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, src,
670 				 pout_planar_y, pout_planar_u, pout_planar_v,
671 				 pdev->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(&pdec->lock);
678 }
679