0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0024
0025
0026
0027 #define USE_LOOKUP_TABLE_TO_CLAMP 1
0028
0029
0030
0031
0032
0033
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
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 }
0135 }
0136 }
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
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
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
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;
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
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
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
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
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
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
0450
0451
0452
0453
0454
0455
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
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
0501 for (i = 0; i < 16; i++)
0502 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
0503
0504 return;
0505 }
0506
0507
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
0524
0525
0526
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
0538
0539
0540
0541 unsigned int mask, shift;
0542 unsigned int nbits, col1;
0543 unsigned int yyyy;
0544
0545 skip_nbits(pdec, 3);
0546
0547 __get_nbits(pdec, 4, yyyy);
0548 offset1 += 1 + yyyy;
0549 offset1 &= 0x0F;
0550 nbits = ptable8004[offset1 * 2];
0551
0552
0553 __get_nbits(pdec, nbits+1, col1);
0554
0555
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
0566
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;
0601
0602 get_nbits(pdec, 4, compression_index);
0603
0604
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
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
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
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
0641
0642
0643
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
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 }