cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pwc-dec23.c (18481B)


      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(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 */
    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(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 * 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, 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}