1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
36
37
38
39#define USE_LOOKUP_TABLE_TO_CLAMP 1
40
41
42
43
44
45
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
53static 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
80static 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
100static 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
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 }
147 }
148 }
149}
150
151
152
153
154static 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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198static 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
268static 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)
289static 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
297void 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;
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
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
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
360
361static 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
413
414
415static 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
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
462
463
464
465
466
467
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
498
499static 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
513 for (i = 0; i < 16; i++)
514 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
515
516 return;
517 }
518
519
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
536
537
538
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
550
551
552
553 unsigned int mask, shift;
554 unsigned int nbits, col1;
555 unsigned int yyyy;
556
557 skip_nbits(pdec, 3);
558
559 __get_nbits(pdec, 4, yyyy);
560 offset1 += 1 + yyyy;
561 offset1 &= 0x0F;
562 nbits = ptable8004[offset1 * 2];
563
564
565 __get_nbits(pdec, nbits+1, col1);
566
567
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
578
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
598static 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;
613
614 get_nbits(pdec, 4, compression_index);
615
616
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
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
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
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
653
654
655
656
657
658void pwc_dec23_decompress(struct pwc_device *pdev,
659 const void *src,
660 void *dst)
661{
662 int bandlines_left, bytes_per_block;
663 struct pwc_dec23_private *pdec = &pdev->dec23;
664
665
666 unsigned char *pout_planar_y;
667 unsigned char *pout_planar_u;
668 unsigned char *pout_planar_v;
669 unsigned int plane_size;
670
671 mutex_lock(&pdec->lock);
672
673 bandlines_left = pdev->height / 4;
674 bytes_per_block = pdev->width * 4;
675 plane_size = pdev->height * pdev->width;
676
677 pout_planar_y = dst;
678 pout_planar_u = dst + plane_size;
679 pout_planar_v = dst + plane_size + plane_size / 4;
680
681 while (bandlines_left--) {
682 DecompressBand23(pdec, src,
683 pout_planar_y, pout_planar_u, pout_planar_v,
684 pdev->width, pdev->width);
685 src += pdev->vbandlength;
686 pout_planar_y += bytes_per_block;
687 pout_planar_u += pdev->width;
688 pout_planar_v += pdev->width;
689 }
690 mutex_unlock(&pdec->lock);
691}
692