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