Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Linux driver for Philips webcam
0003    Decompression for chipset version 2 et 3
0004    (C) 2004-2006  Luc Saillard (luc@saillard.org)
0005 
0006    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
0007    driver and thus may have bugs that are not present in the original version.
0008    Please send bug reports and support requests to <luc@saillard.org>.
0009    The decompression routines have been implemented by reverse-engineering the
0010    Nemosoft binary pwcx module. Caveat emptor.
0011 
0012 
0013 */
0014 
0015 #include "pwc-timon.h"
0016 #include "pwc-kiara.h"
0017 #include "pwc-dec23.h"
0018 
0019 #include <linux/string.h>
0020 #include <linux/slab.h>
0021 
0022 /*
0023  * USE_LOOKUP_TABLE_TO_CLAMP
0024  *   0: use a C version of this tests:  {  a<0?0:(a>255?255:a) }
0025  *   1: use a faster lookup table for cpu with a big cache (intel)
0026  */
0027 #define USE_LOOKUP_TABLE_TO_CLAMP   1
0028 /*
0029  * UNROLL_LOOP_FOR_COPYING_BLOCK
0030  *   0: use a loop for a smaller code (but little slower)
0031  *   1: when unrolling the loop, gcc produces some faster code (perhaps only
0032  *   valid for intel processor class). Activating this option, automatically
0033  *   activate USE_LOOKUP_TABLE_TO_CLAMP
0034  */
0035 #define UNROLL_LOOP_FOR_COPY        1
0036 #if UNROLL_LOOP_FOR_COPY
0037 # undef USE_LOOKUP_TABLE_TO_CLAMP
0038 # define USE_LOOKUP_TABLE_TO_CLAMP 1
0039 #endif
0040 
0041 static void build_subblock_pattern(struct pwc_dec23_private *pdec)
0042 {
0043     static const unsigned int initial_values[12] = {
0044         -0x526500, -0x221200, 0x221200, 0x526500,
0045                -0x3de200, 0x3de200,
0046         -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
0047                -0x12c200, 0x12c200
0048 
0049     };
0050     static const unsigned int values_derivated[12] = {
0051         0xa4ca, 0x4424, -0x4424, -0xa4ca,
0052             0x7bc4, -0x7bc4,
0053         0xdb69, 0x5aba, -0x5aba, -0xdb69,
0054             0x2584, -0x2584
0055     };
0056     unsigned int temp_values[12];
0057     int i, j;
0058 
0059     memcpy(temp_values, initial_values, sizeof(initial_values));
0060     for (i = 0; i < 256; i++) {
0061         for (j = 0; j < 12; j++) {
0062             pdec->table_subblock[i][j] = temp_values[j];
0063             temp_values[j] += values_derivated[j];
0064         }
0065     }
0066 }
0067 
0068 static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
0069 {
0070     unsigned char *p;
0071     unsigned int bit, byte, mask, val;
0072     unsigned int bitpower = 1;
0073 
0074     for (bit = 0; bit < 8; bit++) {
0075         mask = bitpower - 1;
0076         p = pdec->table_bitpowermask[bit];
0077         for (byte = 0; byte < 256; byte++) {
0078             val = (byte & mask);
0079             if (byte & bitpower)
0080                 val = -val;
0081             *p++ = val;
0082         }
0083         bitpower<<=1;
0084     }
0085 }
0086 
0087 
0088 static void build_table_color(const unsigned int romtable[16][8],
0089                   unsigned char p0004[16][1024],
0090                   unsigned char p8004[16][256])
0091 {
0092     int compression_mode, j, k, bit, pw;
0093     unsigned char *p0, *p8;
0094     const unsigned int *r;
0095 
0096     /* We have 16 compressions tables */
0097     for (compression_mode = 0; compression_mode < 16; compression_mode++) {
0098         p0 = p0004[compression_mode];
0099         p8 = p8004[compression_mode];
0100         r  = romtable[compression_mode];
0101 
0102         for (j = 0; j < 8; j++, r++, p0 += 128) {
0103 
0104             for (k = 0; k < 16; k++) {
0105                 if (k == 0)
0106                     bit = 1;
0107                 else if (k >= 1 && k < 3)
0108                     bit = (r[0] >> 15) & 7;
0109                 else if (k >= 3 && k < 6)
0110                     bit = (r[0] >> 12) & 7;
0111                 else if (k >= 6 && k < 10)
0112                     bit = (r[0] >> 9) & 7;
0113                 else if (k >= 10 && k < 13)
0114                     bit = (r[0] >> 6) & 7;
0115                 else if (k >= 13 && k < 15)
0116                     bit = (r[0] >> 3) & 7;
0117                 else
0118                     bit = (r[0]) & 7;
0119                 if (k == 0)
0120                     *p8++ = 8;
0121                 else
0122                     *p8++ = j - bit;
0123                 *p8++ = bit;
0124 
0125                 pw = 1 << bit;
0126                 p0[k + 0x00] = (1 * pw) + 0x80;
0127                 p0[k + 0x10] = (2 * pw) + 0x80;
0128                 p0[k + 0x20] = (3 * pw) + 0x80;
0129                 p0[k + 0x30] = (4 * pw) + 0x80;
0130                 p0[k + 0x40] = (-1 * pw) + 0x80;
0131                 p0[k + 0x50] = (-2 * pw) + 0x80;
0132                 p0[k + 0x60] = (-3 * pw) + 0x80;
0133                 p0[k + 0x70] = (-4 * pw) + 0x80;
0134             }   /* end of for (k=0; k<16; k++, p8++) */
0135         }   /* end of for (j=0; j<8; j++ , table++) */
0136     } /* end of foreach compression_mode */
0137 }
0138 
0139 /*
0140  *
0141  */
0142 static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
0143 {
0144 #define SCALEBITS 15
0145 #define ONE_HALF  (1UL << (SCALEBITS - 1))
0146     int i;
0147     unsigned int offset1 = ONE_HALF;
0148     unsigned int offset2 = 0x0000;
0149 
0150     for (i=0; i<256; i++) {
0151         pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
0152         pdec->table_d800[i] = offset2;
0153 
0154         offset1 += 0x7bc4;
0155         offset2 += 0x7bc4;
0156     }
0157 }
0158 
0159 /*
0160  * To decode the stream:
0161  *   if look_bits(2) == 0:  # op == 2 in the lookup table
0162  *      skip_bits(2)
0163  *      end of the stream
0164  *   elif look_bits(3) == 7:    # op == 1 in the lookup table
0165  *      skip_bits(3)
0166  *      yyyy = get_bits(4)
0167  *      xxxx = get_bits(8)
0168  *   else:          # op == 0 in the lookup table
0169  *      skip_bits(x)
0170  *
0171  * For speedup processing, we build a lookup table and we takes the first 6 bits.
0172  *
0173  * struct {
0174  *   unsigned char op;      // operation to execute
0175  *   unsigned char bits;    // bits use to perform operation
0176  *   unsigned char offset1; // offset to add to access in the table_0004 % 16
0177  *   unsigned char offset2; // offset to add to access in the table_0004
0178  * }
0179  *
0180  * How to build this table ?
0181  *   op == 2 when (i%4)==0
0182  *   op == 1 when (i%8)==7
0183  *   op == 0 otherwise
0184  *
0185  */
0186 static const unsigned char hash_table_ops[64*4] = {
0187     0x02, 0x00, 0x00, 0x00,
0188     0x00, 0x03, 0x01, 0x00,
0189     0x00, 0x04, 0x01, 0x10,
0190     0x00, 0x06, 0x01, 0x30,
0191     0x02, 0x00, 0x00, 0x00,
0192     0x00, 0x03, 0x01, 0x40,
0193     0x00, 0x05, 0x01, 0x20,
0194     0x01, 0x00, 0x00, 0x00,
0195     0x02, 0x00, 0x00, 0x00,
0196     0x00, 0x03, 0x01, 0x00,
0197     0x00, 0x04, 0x01, 0x50,
0198     0x00, 0x05, 0x02, 0x00,
0199     0x02, 0x00, 0x00, 0x00,
0200     0x00, 0x03, 0x01, 0x40,
0201     0x00, 0x05, 0x03, 0x00,
0202     0x01, 0x00, 0x00, 0x00,
0203     0x02, 0x00, 0x00, 0x00,
0204     0x00, 0x03, 0x01, 0x00,
0205     0x00, 0x04, 0x01, 0x10,
0206     0x00, 0x06, 0x02, 0x10,
0207     0x02, 0x00, 0x00, 0x00,
0208     0x00, 0x03, 0x01, 0x40,
0209     0x00, 0x05, 0x01, 0x60,
0210     0x01, 0x00, 0x00, 0x00,
0211     0x02, 0x00, 0x00, 0x00,
0212     0x00, 0x03, 0x01, 0x00,
0213     0x00, 0x04, 0x01, 0x50,
0214     0x00, 0x05, 0x02, 0x40,
0215     0x02, 0x00, 0x00, 0x00,
0216     0x00, 0x03, 0x01, 0x40,
0217     0x00, 0x05, 0x03, 0x40,
0218     0x01, 0x00, 0x00, 0x00,
0219     0x02, 0x00, 0x00, 0x00,
0220     0x00, 0x03, 0x01, 0x00,
0221     0x00, 0x04, 0x01, 0x10,
0222     0x00, 0x06, 0x01, 0x70,
0223     0x02, 0x00, 0x00, 0x00,
0224     0x00, 0x03, 0x01, 0x40,
0225     0x00, 0x05, 0x01, 0x20,
0226     0x01, 0x00, 0x00, 0x00,
0227     0x02, 0x00, 0x00, 0x00,
0228     0x00, 0x03, 0x01, 0x00,
0229     0x00, 0x04, 0x01, 0x50,
0230     0x00, 0x05, 0x02, 0x00,
0231     0x02, 0x00, 0x00, 0x00,
0232     0x00, 0x03, 0x01, 0x40,
0233     0x00, 0x05, 0x03, 0x00,
0234     0x01, 0x00, 0x00, 0x00,
0235     0x02, 0x00, 0x00, 0x00,
0236     0x00, 0x03, 0x01, 0x00,
0237     0x00, 0x04, 0x01, 0x10,
0238     0x00, 0x06, 0x02, 0x50,
0239     0x02, 0x00, 0x00, 0x00,
0240     0x00, 0x03, 0x01, 0x40,
0241     0x00, 0x05, 0x01, 0x60,
0242     0x01, 0x00, 0x00, 0x00,
0243     0x02, 0x00, 0x00, 0x00,
0244     0x00, 0x03, 0x01, 0x00,
0245     0x00, 0x04, 0x01, 0x50,
0246     0x00, 0x05, 0x02, 0x40,
0247     0x02, 0x00, 0x00, 0x00,
0248     0x00, 0x03, 0x01, 0x40,
0249     0x00, 0x05, 0x03, 0x40,
0250     0x01, 0x00, 0x00, 0x00
0251 };
0252 
0253 /*
0254  *
0255  */
0256 static const unsigned int MulIdx[16][16] = {
0257     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
0258     {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
0259     {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
0260     {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
0261     {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
0262     {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
0263     {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
0264     {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
0265     {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
0266     {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
0267     {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
0268     {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
0269     {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
0270     {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
0271     {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
0272     {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
0273 };
0274 
0275 #if USE_LOOKUP_TABLE_TO_CLAMP
0276 #define MAX_OUTER_CROP_VALUE    (512)
0277 static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
0278 #define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
0279 #else
0280 #define CLAMP(x) ((x)>255?255:((x)<0?0:x))
0281 #endif
0282 
0283 
0284 /* If the type or the command change, we rebuild the lookup table */
0285 void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd)
0286 {
0287     int flags, version, shift, i;
0288     struct pwc_dec23_private *pdec = &pdev->dec23;
0289 
0290     mutex_init(&pdec->lock);
0291 
0292     if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2])
0293         return;
0294 
0295     if (DEVICE_USE_CODEC3(pdev->type)) {
0296         flags = cmd[2] & 0x18;
0297         if (flags == 8)
0298             pdec->nbits = 7;    /* More bits, mean more bits to encode the stream, but better quality */
0299         else if (flags == 0x10)
0300             pdec->nbits = 8;
0301         else
0302             pdec->nbits = 6;
0303 
0304         version = cmd[2] >> 5;
0305         build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
0306         build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
0307 
0308     } else {
0309 
0310         flags = cmd[2] & 6;
0311         if (flags == 2)
0312             pdec->nbits = 7;
0313         else if (flags == 4)
0314             pdec->nbits = 8;
0315         else
0316             pdec->nbits = 6;
0317 
0318         version = cmd[2] >> 3;
0319         build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
0320         build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
0321     }
0322 
0323     /* Information can be coded on a variable number of bits but never less than 8 */
0324     shift = 8 - pdec->nbits;
0325     pdec->scalebits = SCALEBITS - shift;
0326     pdec->nbitsmask = 0xFF >> shift;
0327 
0328     fill_table_dc00_d800(pdec);
0329     build_subblock_pattern(pdec);
0330     build_bit_powermask_table(pdec);
0331 
0332 #if USE_LOOKUP_TABLE_TO_CLAMP
0333     /* Build the static table to clamp value [0-255] */
0334     for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
0335         pwc_crop_table[i] = 0;
0336     for (i=0; i<256; i++)
0337         pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
0338     for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
0339         pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
0340 #endif
0341 
0342     pdec->last_cmd = cmd[2];
0343     pdec->last_cmd_valid = 1;
0344 }
0345 
0346 /*
0347  * Copy the 4x4 image block to Y plane buffer
0348  */
0349 static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
0350 {
0351 #if UNROLL_LOOP_FOR_COPY
0352     const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
0353     const int *c = src;
0354     unsigned char *d = dst;
0355 
0356     *d++ = cm[c[0] >> scalebits];
0357     *d++ = cm[c[1] >> scalebits];
0358     *d++ = cm[c[2] >> scalebits];
0359     *d++ = cm[c[3] >> scalebits];
0360 
0361     d = dst + bytes_per_line;
0362     *d++ = cm[c[4] >> scalebits];
0363     *d++ = cm[c[5] >> scalebits];
0364     *d++ = cm[c[6] >> scalebits];
0365     *d++ = cm[c[7] >> scalebits];
0366 
0367     d = dst + bytes_per_line*2;
0368     *d++ = cm[c[8] >> scalebits];
0369     *d++ = cm[c[9] >> scalebits];
0370     *d++ = cm[c[10] >> scalebits];
0371     *d++ = cm[c[11] >> scalebits];
0372 
0373     d = dst + bytes_per_line*3;
0374     *d++ = cm[c[12] >> scalebits];
0375     *d++ = cm[c[13] >> scalebits];
0376     *d++ = cm[c[14] >> scalebits];
0377     *d++ = cm[c[15] >> scalebits];
0378 #else
0379     int i;
0380     const int *c = src;
0381     unsigned char *d = dst;
0382     for (i = 0; i < 4; i++, c++)
0383         *d++ = CLAMP((*c) >> scalebits);
0384 
0385     d = dst + bytes_per_line;
0386     for (i = 0; i < 4; i++, c++)
0387         *d++ = CLAMP((*c) >> scalebits);
0388 
0389     d = dst + bytes_per_line*2;
0390     for (i = 0; i < 4; i++, c++)
0391         *d++ = CLAMP((*c) >> scalebits);
0392 
0393     d = dst + bytes_per_line*3;
0394     for (i = 0; i < 4; i++, c++)
0395         *d++ = CLAMP((*c) >> scalebits);
0396 #endif
0397 }
0398 
0399 /*
0400  * Copy the 4x4 image block to a CrCb plane buffer
0401  *
0402  */
0403 static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
0404 {
0405 #if UNROLL_LOOP_FOR_COPY
0406     /* Unroll all loops */
0407     const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
0408     const int *c = src;
0409     unsigned char *d = dst;
0410 
0411     *d++ = cm[c[0] >> scalebits];
0412     *d++ = cm[c[4] >> scalebits];
0413     *d++ = cm[c[1] >> scalebits];
0414     *d++ = cm[c[5] >> scalebits];
0415     *d++ = cm[c[2] >> scalebits];
0416     *d++ = cm[c[6] >> scalebits];
0417     *d++ = cm[c[3] >> scalebits];
0418     *d++ = cm[c[7] >> scalebits];
0419 
0420     d = dst + bytes_per_line;
0421     *d++ = cm[c[12] >> scalebits];
0422     *d++ = cm[c[8] >> scalebits];
0423     *d++ = cm[c[13] >> scalebits];
0424     *d++ = cm[c[9] >> scalebits];
0425     *d++ = cm[c[14] >> scalebits];
0426     *d++ = cm[c[10] >> scalebits];
0427     *d++ = cm[c[15] >> scalebits];
0428     *d++ = cm[c[11] >> scalebits];
0429 #else
0430     int i;
0431     const int *c1 = src;
0432     const int *c2 = src + 4;
0433     unsigned char *d = dst;
0434 
0435     for (i = 0; i < 4; i++, c1++, c2++) {
0436         *d++ = CLAMP((*c1) >> scalebits);
0437         *d++ = CLAMP((*c2) >> scalebits);
0438     }
0439     c1 = src + 12;
0440     d = dst + bytes_per_line;
0441     for (i = 0; i < 4; i++, c1++, c2++) {
0442         *d++ = CLAMP((*c1) >> scalebits);
0443         *d++ = CLAMP((*c2) >> scalebits);
0444     }
0445 #endif
0446 }
0447 
0448 /*
0449  * To manage the stream, we keep bits in a 32 bits register.
0450  * fill_nbits(n): fill the reservoir with at least n bits
0451  * skip_bits(n): discard n bits from the reservoir
0452  * get_bits(n): fill the reservoir, returns the first n bits and discard the
0453  *              bits from the reservoir.
0454  * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
0455  *                 contains at least n bits. bits returned is discarded.
0456  */
0457 #define fill_nbits(pdec, nbits_wanted) do { \
0458    while (pdec->nbits_in_reservoir<(nbits_wanted)) \
0459     { \
0460       pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
0461       pdec->nbits_in_reservoir += 8; \
0462     } \
0463 }  while(0);
0464 
0465 #define skip_nbits(pdec, nbits_to_skip) do { \
0466    pdec->reservoir >>= (nbits_to_skip); \
0467    pdec->nbits_in_reservoir -= (nbits_to_skip); \
0468 }  while(0);
0469 
0470 #define get_nbits(pdec, nbits_wanted, result) do { \
0471    fill_nbits(pdec, nbits_wanted); \
0472    result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
0473    skip_nbits(pdec, nbits_wanted); \
0474 }  while(0);
0475 
0476 #define __get_nbits(pdec, nbits_wanted, result) do { \
0477    result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
0478    skip_nbits(pdec, nbits_wanted); \
0479 }  while(0);
0480 
0481 #define look_nbits(pdec, nbits_wanted) \
0482    ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
0483 
0484 /*
0485  * Decode a 4x4 pixel block
0486  */
0487 static void decode_block(struct pwc_dec23_private *pdec,
0488              const unsigned char *ptable0004,
0489              const unsigned char *ptable8004)
0490 {
0491     unsigned int primary_color;
0492     unsigned int channel_v, offset1, op;
0493     int i;
0494 
0495     fill_nbits(pdec, 16);
0496     __get_nbits(pdec, pdec->nbits, primary_color);
0497 
0498     if (look_nbits(pdec,2) == 0) {
0499         skip_nbits(pdec, 2);
0500         /* Very simple, the color is the same for all pixels of the square */
0501         for (i = 0; i < 16; i++)
0502             pdec->temp_colors[i] = pdec->table_dc00[primary_color];
0503 
0504         return;
0505     }
0506 
0507     /* This block is encoded with small pattern */
0508     for (i = 0; i < 16; i++)
0509         pdec->temp_colors[i] = pdec->table_d800[primary_color];
0510 
0511     __get_nbits(pdec, 3, channel_v);
0512     channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
0513 
0514     ptable0004 += (channel_v * 128);
0515     ptable8004 += (channel_v * 32);
0516 
0517     offset1 = 0;
0518     do
0519     {
0520         unsigned int htable_idx, rows = 0;
0521         const unsigned int *block;
0522 
0523         /* [  zzzz y x x ]
0524          *     xx == 00 :=> end of the block def, remove the two bits from the stream
0525          *    yxx == 111
0526          *    yxx == any other value
0527          *
0528          */
0529         fill_nbits(pdec, 16);
0530         htable_idx = look_nbits(pdec, 6);
0531         op = hash_table_ops[htable_idx * 4];
0532 
0533         if (op == 2) {
0534             skip_nbits(pdec, 2);
0535 
0536         } else if (op == 1) {
0537             /* 15bits [ xxxx xxxx yyyy 111 ]
0538              * yyy => offset in the table8004
0539              * xxx => offset in the tabled004 (tree)
0540              */
0541             unsigned int mask, shift;
0542             unsigned int nbits, col1;
0543             unsigned int yyyy;
0544 
0545             skip_nbits(pdec, 3);
0546             /* offset1 += yyyy */
0547             __get_nbits(pdec, 4, yyyy);
0548             offset1 += 1 + yyyy;
0549             offset1 &= 0x0F;
0550             nbits = ptable8004[offset1 * 2];
0551 
0552             /* col1 = xxxx xxxx */
0553             __get_nbits(pdec, nbits+1, col1);
0554 
0555             /* Bit mask table */
0556             mask = pdec->table_bitpowermask[nbits][col1];
0557             shift = ptable8004[offset1 * 2 + 1];
0558             rows = ((mask << shift) + 0x80) & 0xFF;
0559 
0560             block = pdec->table_subblock[rows];
0561             for (i = 0; i < 16; i++)
0562                 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
0563 
0564         } else {
0565             /* op == 0
0566              * offset1 is coded on 3 bits
0567              */
0568             unsigned int shift;
0569 
0570             offset1 += hash_table_ops [htable_idx * 4 + 2];
0571             offset1 &= 0x0F;
0572 
0573             rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
0574             block = pdec->table_subblock[rows];
0575             for (i = 0; i < 16; i++)
0576                 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
0577 
0578             shift = hash_table_ops[htable_idx * 4 + 1];
0579             skip_nbits(pdec, shift);
0580         }
0581 
0582     } while (op != 2);
0583 
0584 }
0585 
0586 static void DecompressBand23(struct pwc_dec23_private *pdec,
0587                  const unsigned char *rawyuv,
0588                  unsigned char *planar_y,
0589                  unsigned char *planar_u,
0590                  unsigned char *planar_v,
0591                  unsigned int   compressed_image_width,
0592                  unsigned int   real_image_width)
0593 {
0594     int compression_index, nblocks;
0595     const unsigned char *ptable0004;
0596     const unsigned char *ptable8004;
0597 
0598     pdec->reservoir = 0;
0599     pdec->nbits_in_reservoir = 0;
0600     pdec->stream = rawyuv + 1;  /* The first byte of the stream is skipped */
0601 
0602     get_nbits(pdec, 4, compression_index);
0603 
0604     /* pass 1: uncompress Y component */
0605     nblocks = compressed_image_width / 4;
0606 
0607     ptable0004 = pdec->table_0004_pass1[compression_index];
0608     ptable8004 = pdec->table_8004_pass1[compression_index];
0609 
0610     /* Each block decode a square of 4x4 */
0611     while (nblocks) {
0612         decode_block(pdec, ptable0004, ptable8004);
0613         copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
0614         planar_y += 4;
0615         nblocks--;
0616     }
0617 
0618     /* pass 2: uncompress UV component */
0619     nblocks = compressed_image_width / 8;
0620 
0621     ptable0004 = pdec->table_0004_pass2[compression_index];
0622     ptable8004 = pdec->table_8004_pass2[compression_index];
0623 
0624     /* Each block decode a square of 4x4 */
0625     while (nblocks) {
0626         decode_block(pdec, ptable0004, ptable8004);
0627         copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
0628 
0629         decode_block(pdec, ptable0004, ptable8004);
0630         copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
0631 
0632         planar_v += 8;
0633         planar_u += 8;
0634         nblocks -= 2;
0635     }
0636 
0637 }
0638 
0639 /**
0640  * pwc_dec23_decompress - Uncompress a pwc23 buffer.
0641  * @pdev: pointer to pwc device's internal struct
0642  * @src: raw data
0643  * @dst: image output
0644  */
0645 void pwc_dec23_decompress(struct pwc_device *pdev,
0646               const void *src,
0647               void *dst)
0648 {
0649     int bandlines_left, bytes_per_block;
0650     struct pwc_dec23_private *pdec = &pdev->dec23;
0651 
0652     /* YUV420P image format */
0653     unsigned char *pout_planar_y;
0654     unsigned char *pout_planar_u;
0655     unsigned char *pout_planar_v;
0656     unsigned int   plane_size;
0657 
0658     mutex_lock(&pdec->lock);
0659 
0660     bandlines_left = pdev->height / 4;
0661     bytes_per_block = pdev->width * 4;
0662     plane_size = pdev->height * pdev->width;
0663 
0664     pout_planar_y = dst;
0665     pout_planar_u = dst + plane_size;
0666     pout_planar_v = dst + plane_size + plane_size / 4;
0667 
0668     while (bandlines_left--) {
0669         DecompressBand23(pdec, src,
0670                  pout_planar_y, pout_planar_u, pout_planar_v,
0671                  pdev->width, pdev->width);
0672         src += pdev->vbandlength;
0673         pout_planar_y += bytes_per_block;
0674         pout_planar_u += pdev->width;
0675         pout_planar_v += pdev->width;
0676     }
0677     mutex_unlock(&pdec->lock);
0678 }