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}