linux/drivers/media/usb/pwc/pwc-dec23.c
<<
>>
Prefs
   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}
 679