31 #include <linux/string.h>
32 #include <linux/slab.h>
39 #define USE_LOOKUP_TABLE_TO_CLAMP 1
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
55 static const unsigned int initial_values[12] = {
56 -0x526500, -0x221200, 0x221200, 0x526500,
58 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
62 static const unsigned int values_derivated[12] = {
63 0xa4ca, 0x4424, -0x4424, -0xa4ca,
65 0xdb69, 0x5aba, -0x5aba, -0xdb69,
68 unsigned int temp_values[12];
71 memcpy(temp_values, initial_values,
sizeof(initial_values));
72 for (i = 0; i < 256; i++) {
73 for (j = 0; j < 12; j++) {
75 temp_values[
j] += values_derivated[
j];
84 unsigned int bitpower = 1;
86 for (bit = 0; bit < 8; bit++) {
89 for (byte = 0; byte < 256; byte++) {
100 static void build_table_color(
const unsigned int romtable[16][8],
101 unsigned char p0004[16][1024],
102 unsigned char p8004[16][256])
104 int compression_mode,
j,
k,
bit,
pw;
105 unsigned char *
p0, *p8;
106 const unsigned int *
r;
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];
114 for (j = 0; j < 8; j++, r++, p0 += 128) {
116 for (k = 0; k < 16; k++) {
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;
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;
157 #define ONE_HALF (1UL << (SCALEBITS - 1))
162 for (i=0; i<256; i++) {
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
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}
287 #if USE_LOOKUP_TABLE_TO_CLAMP
288 #define MAX_OUTER_CROP_VALUE (512)
290 #define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
292 #define CLAMP(x) ((x)>255?255:((x)<0?0:x))
308 flags = cmd[2] & 0x18;
311 else if (flags == 0x10)
316 version = cmd[2] >> 5;
330 version = cmd[2] >> 3;
336 shift = 8 - pdec->
nbits;
340 fill_table_dc00_d800(pdec);
341 build_subblock_pattern(pdec);
342 build_bit_powermask_table(pdec);
344 #if USE_LOOKUP_TABLE_TO_CLAMP
347 pwc_crop_table[i] = 0;
348 for (i=0; i<256; i++)
349 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
351 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
361 static void copy_image_block_Y(
const int *
src,
unsigned char *
dst,
unsigned int bytes_per_line,
unsigned int scalebits)
363 #if UNROLL_LOOP_FOR_COPY
366 unsigned char *
d =
dst;
373 d = dst + bytes_per_line;
379 d = dst + bytes_per_line*2;
385 d = dst + bytes_per_line*3;
393 unsigned char *d =
dst;
394 for (i = 0; i < 4; i++, c++)
395 *d++ =
CLAMP((*c) >> scalebits);
397 d = dst + bytes_per_line;
398 for (i = 0; i < 4; i++, c++)
399 *d++ =
CLAMP((*c) >> scalebits);
401 d = dst + bytes_per_line*2;
402 for (i = 0; i < 4; i++, c++)
403 *d++ =
CLAMP((*c) >> scalebits);
405 d = dst + bytes_per_line*3;
406 for (i = 0; i < 4; i++, c++)
407 *d++ =
CLAMP((*c) >> scalebits);
415 static void copy_image_block_CrCb(
const int *src,
unsigned char *dst,
unsigned int bytes_per_line,
unsigned int scalebits)
417 #if UNROLL_LOOP_FOR_COPY
421 unsigned char *d =
dst;
432 d = dst + bytes_per_line;
444 const int *c2 = src + 4;
445 unsigned char *d =
dst;
447 for (i = 0; i < 4; i++, c1++, c2++) {
448 *d++ =
CLAMP((*c1) >> scalebits);
449 *d++ =
CLAMP((*c2) >> scalebits);
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);
469 #define fill_nbits(pdec, nbits_wanted) do { \
470 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
472 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
473 pdec->nbits_in_reservoir += 8; \
477 #define skip_nbits(pdec, nbits_to_skip) do { \
478 pdec->reservoir >>= (nbits_to_skip); \
479 pdec->nbits_in_reservoir -= (nbits_to_skip); \
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); \
488 #define __get_nbits(pdec, nbits_wanted, result) do { \
489 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
490 skip_nbits(pdec, nbits_wanted); \
493 #define look_nbits(pdec, nbits_wanted) \
494 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
500 const unsigned char *ptable0004,
501 const unsigned char *ptable8004)
503 unsigned int primary_color;
513 for (i = 0; i < 16; i++)
520 for (i = 0; i < 16; i++)
524 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
526 ptable0004 += (channel_v * 128);
527 ptable8004 += (channel_v * 32);
532 unsigned int htable_idx,
rows = 0;
533 const unsigned int *
block;
543 op = hash_table_ops[htable_idx * 4];
548 }
else if (op == 1) {
553 unsigned int mask, shift;
554 unsigned int nbits, col1;
562 nbits = ptable8004[offset1 * 2];
569 shift = ptable8004[offset1 * 2 + 1];
570 rows = ((mask << shift) + 0x80) & 0xFF;
573 for (i = 0; i < 16; i++)
582 offset1 += hash_table_ops [htable_idx * 4 + 2];
585 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
587 for (i = 0; i < 16; i++)
590 shift = hash_table_ops[htable_idx * 4 + 1];
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)
606 int compression_index, nblocks;
607 const unsigned char *ptable0004;
608 const unsigned char *ptable8004;
612 pdec->
stream = rawyuv + 1;
617 nblocks = compressed_image_width / 4;
624 decode_block(pdec, ptable0004, ptable8004);
631 nblocks = compressed_image_width / 8;
638 decode_block(pdec, ptable0004, ptable8004);
641 decode_block(pdec, ptable0004, ptable8004);
662 int bandlines_left, bytes_per_block;
666 unsigned char *pout_planar_y;
667 unsigned char *pout_planar_u;
668 unsigned char *pout_planar_v;
669 unsigned int plane_size;
673 bandlines_left = pdev->
height / 4;
674 bytes_per_block = pdev->
width * 4;
678 pout_planar_u = dst + plane_size;
679 pout_planar_v = dst + plane_size + plane_size / 4;
681 while (bandlines_left--) {
682 DecompressBand23(pdec, src,
683 pout_planar_y, pout_planar_u, pout_planar_v,
686 pout_planar_y += bytes_per_block;
687 pout_planar_u += pdev->
width;
688 pout_planar_v += pdev->
width;