12b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* Linux driver for Philips webcam 22b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard Decompression for chipset version 2 et 3 32b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard (C) 2004-2006 Luc Saillard (luc@saillard.org) 42b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 52b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 62b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard driver and thus may have bugs that are not present in the original version. 72b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard Please send bug reports and support requests to <luc@saillard.org>. 82b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard The decompression routines have been implemented by reverse-engineering the 92b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard Nemosoft binary pwcx module. Caveat emptor. 102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard This program is free software; you can redistribute it and/or modify 122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard it under the terms of the GNU General Public License as published by 132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard the Free Software Foundation; either version 2 of the License, or 142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard (at your option) any later version. 152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard This program is distributed in the hope that it will be useful, 172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard but WITHOUT ANY WARRANTY; without even the implied warranty of 182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard GNU General Public License for more details. 202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard You should have received a copy of the GNU General Public License 222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard along with this program; if not, write to the Free Software 232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard*/ 262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#include "pwc-timon.h" 282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#include "pwc-kiara.h" 292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#include "pwc-dec23.h" 302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#include <linux/string.h> 325a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * USE_LOOKUP_TABLE_TO_CLAMP 362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 0: use a C version of this tests: { a<0?0:(a>255?255:a) } 372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1: use a faster lookup table for cpu with a big cache (intel) 382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define USE_LOOKUP_TABLE_TO_CLAMP 1 402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * UNROLL_LOOP_FOR_COPYING_BLOCK 422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 0: use a loop for a smaller code (but little slower) 432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1: when unrolling the loop, gcc produces some faster code (perhaps only 442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * valid for intel processor class). Activating this option, automaticaly 452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * activate USE_LOOKUP_TABLE_TO_CLAMP 462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define UNROLL_LOOP_FOR_COPY 1 482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#if UNROLL_LOOP_FOR_COPY 492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard# undef USE_LOOKUP_TABLE_TO_CLAMP 502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard# define USE_LOOKUP_TABLE_TO_CLAMP 1 512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#endif 522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void build_subblock_pattern(struct pwc_dec23_private *pdec) 542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard static const unsigned int initial_values[12] = { 562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard -0x526500, -0x221200, 0x221200, 0x526500, 572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard -0x3de200, 0x3de200, 582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480, 592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard -0x12c200, 0x12c200 602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard }; 622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard static const unsigned int values_derivated[12] = { 632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0xa4ca, 0x4424, -0x4424, -0xa4ca, 642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x7bc4, -0x7bc4, 652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0xdb69, 0x5aba, -0x5aba, -0xdb69, 662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x2584, -0x2584 672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard }; 682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int temp_values[12]; 692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int i, j; 702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard memcpy(temp_values, initial_values, sizeof(initial_values)); 722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 256; i++) { 732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (j = 0; j < 12; j++) { 742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->table_subblock[i][j] = temp_values[j]; 752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard temp_values[j] += values_derivated[j]; 762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void build_bit_powermask_table(struct pwc_dec23_private *pdec) 812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *p; 832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int bit, byte, mask, val; 842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int bitpower = 1; 852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (bit = 0; bit < 8; bit++) { 872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard mask = bitpower - 1; 882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p = pdec->table_bitpowermask[bit]; 892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (byte = 0; byte < 256; byte++) { 902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard val = (byte & mask); 912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (byte & bitpower) 922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard val = -val; 932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *p++ = val; 942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bitpower<<=1; 962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 972b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1002b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void build_table_color(const unsigned int romtable[16][8], 101657de3cd32285831a56f9f96deb85c64205c42fcTrent Piepho unsigned char p0004[16][1024], 1022b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char p8004[16][256]) 1032b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 1042b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int compression_mode, j, k, bit, pw; 1052b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *p0, *p8; 1062b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned int *r; 1072b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* We have 16 compressions tables */ 1092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (compression_mode = 0; compression_mode < 16; compression_mode++) { 1102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0 = p0004[compression_mode]; 1112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p8 = p8004[compression_mode]; 1122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard r = romtable[compression_mode]; 1132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (j = 0; j < 8; j++, r++, p0 += 128) { 1152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (k = 0; k < 16; k++) { 1172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (k == 0) 1182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = 1; 1192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (k >= 1 && k < 3) 1202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0] >> 15) & 7; 1212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (k >= 3 && k < 6) 1222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0] >> 12) & 7; 1232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (k >= 6 && k < 10) 1242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0] >> 9) & 7; 1252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (k >= 10 && k < 13) 1262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0] >> 6) & 7; 1272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (k >= 13 && k < 15) 1282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0] >> 3) & 7; 1292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else 1302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard bit = (r[0]) & 7; 1312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (k == 0) 1322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *p8++ = 8; 1332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else 1342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *p8++ = j - bit; 1352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *p8++ = bit; 1362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pw = 1 << bit; 1382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x00] = (1 * pw) + 0x80; 1392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x10] = (2 * pw) + 0x80; 1402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x20] = (3 * pw) + 0x80; 1412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x30] = (4 * pw) + 0x80; 1422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x40] = (-1 * pw) + 0x80; 1432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x50] = (-2 * pw) + 0x80; 1442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x60] = (-3 * pw) + 0x80; 1452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard p0[k + 0x70] = (-4 * pw) + 0x80; 1462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } /* end of for (k=0; k<16; k++, p8++) */ 1472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } /* end of for (j=0; j<8; j++ , table++) */ 1482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } /* end of foreach compression_mode */ 1492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 1502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 1522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 1542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void fill_table_dc00_d800(struct pwc_dec23_private *pdec) 1552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 1562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define SCALEBITS 15 1572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define ONE_HALF (1UL << (SCALEBITS - 1)) 1582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int i; 1592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int offset1 = ONE_HALF; 1602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int offset2 = 0x0000; 1612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i=0; i<256; i++) { 1632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->table_dc00[i] = offset1 & ~(ONE_HALF); 1642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->table_d800[i] = offset2; 1652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 += 0x7bc4; 1672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset2 += 0x7bc4; 1682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 1692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 1702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 1712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 1722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * To decode the stream: 1732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * if look_bits(2) == 0: # op == 2 in the lookup table 1742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * skip_bits(2) 1752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * end of the stream 1762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * elif look_bits(3) == 7: # op == 1 in the lookup table 1772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * skip_bits(3) 1782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * yyyy = get_bits(4) 1792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * xxxx = get_bits(8) 1802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * else: # op == 0 in the lookup table 1812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * skip_bits(x) 1822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * For speedup processing, we build a lookup table and we takes the first 6 bits. 1842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * struct { 1862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * unsigned char op; // operation to execute 1872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * unsigned char bits; // bits use to perform operation 1882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * unsigned char offset1; // offset to add to access in the table_0004 % 16 1892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * unsigned char offset2; // offset to add to access in the table_0004 1902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * } 1912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * How to build this table ? 1932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * op == 2 when (i%4)==0 1942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * op == 1 when (i%8)==7 1952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * op == 0 otherwise 1962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 1972b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 1982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic const unsigned char hash_table_ops[64*4] = { 1992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2002b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2012b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x10, 2022b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x06, 0x01, 0x30, 2032b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2042b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2052b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x01, 0x20, 2062b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2072b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x50, 2102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x02, 0x00, 2112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x03, 0x00, 2142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x10, 2182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x06, 0x02, 0x10, 2192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x01, 0x60, 2222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x50, 2262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x02, 0x40, 2272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x03, 0x40, 2302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x10, 2342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x06, 0x01, 0x70, 2352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x01, 0x20, 2382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x50, 2422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x02, 0x00, 2432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x03, 0x00, 2462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x10, 2502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x06, 0x02, 0x50, 2512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x01, 0x60, 2542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00, 2552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x00, 2572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x04, 0x01, 0x50, 2582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x02, 0x40, 2592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x02, 0x00, 0x00, 0x00, 2602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x03, 0x01, 0x40, 2612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x00, 0x05, 0x03, 0x40, 2622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 0x01, 0x00, 0x00, 0x00 2632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard}; 2642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 2652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 2662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 2672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 2682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic const unsigned int MulIdx[16][16] = { 2692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 2702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,}, 2712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,}, 2722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,}, 2732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,}, 2742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,}, 2752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,}, 2762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,}, 2772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,}, 2782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,}, 2792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,}, 2802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,}, 2812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,}, 2822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,}, 2832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,}, 2842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10} 2852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard}; 2862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 2872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#if USE_LOOKUP_TABLE_TO_CLAMP 2882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define MAX_OUTER_CROP_VALUE (512) 2892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; 2902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)]) 2912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#else 2922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define CLAMP(x) ((x)>255?255:((x)<0?0:x)) 2932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#endif 2942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 2952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 2962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* If the type or the command change, we rebuild the lookup table */ 29724be689bfbbcd6c047d7918784ff810e97648006Hans de Goedevoid pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd) 2982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 2992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int flags, version, shift, i; 30056ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede struct pwc_dec23_private *pdec = &pdev->dec23; 3012b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 302c20d78cde37018caa0313469c9320424995cc489Hans de Goede mutex_init(&pdec->lock); 303c20d78cde37018caa0313469c9320424995cc489Hans de Goede 3041c852201a28601b1379857f615e99071211294c6Hans de Goede if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2]) 3051c852201a28601b1379857f615e99071211294c6Hans de Goede return; 3061c852201a28601b1379857f615e99071211294c6Hans de Goede 30756ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede if (DEVICE_USE_CODEC3(pdev->type)) { 3082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard flags = cmd[2] & 0x18; 3092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (flags == 8) 3102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ 3112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (flags == 0x10) 3122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 8; 3132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else 3142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 6; 3152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard version = cmd[2] >> 5; 3172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); 3182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); 3192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } else { 3212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard flags = cmd[2] & 6; 3232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (flags == 2) 3242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 7; 3252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else if (flags == 4) 3262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 8; 3272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard else 3282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits = 6; 3292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard version = cmd[2] >> 3; 3312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); 3322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); 3332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 3342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Informations can be coded on a variable number of bits but never less than 8 */ 3362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard shift = 8 - pdec->nbits; 3372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->scalebits = SCALEBITS - shift; 3382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbitsmask = 0xFF >> shift; 3392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard fill_table_dc00_d800(pdec); 3412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_subblock_pattern(pdec); 3422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard build_bit_powermask_table(pdec); 3432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#if USE_LOOKUP_TABLE_TO_CLAMP 3452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Build the static table to clamp value [0-255] */ 3462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i=0;i<MAX_OUTER_CROP_VALUE;i++) 3472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pwc_crop_table[i] = 0; 3482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i=0; i<256; i++) 3492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i; 3502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i=0; i<MAX_OUTER_CROP_VALUE; i++) 3512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; 3522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#endif 3531c852201a28601b1379857f615e99071211294c6Hans de Goede 3541c852201a28601b1379857f615e99071211294c6Hans de Goede pdec->last_cmd = cmd[2]; 3551c852201a28601b1379857f615e99071211294c6Hans de Goede pdec->last_cmd_valid = 1; 3562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 3572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 3592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * Copy the 4x4 image block to Y plane buffer 3602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 3612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) 3622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 3632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#if UNROLL_LOOP_FOR_COPY 3642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; 3652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const int *c = src; 3662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *d = dst; 3672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[0] >> scalebits]; 3692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[1] >> scalebits]; 3702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[2] >> scalebits]; 3712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[3] >> scalebits]; 3722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line; 3742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[4] >> scalebits]; 3752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[5] >> scalebits]; 3762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[6] >> scalebits]; 3772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[7] >> scalebits]; 3782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line*2; 3802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[8] >> scalebits]; 3812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[9] >> scalebits]; 3822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[10] >> scalebits]; 3832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[11] >> scalebits]; 3842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line*3; 3862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[12] >> scalebits]; 3872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[13] >> scalebits]; 3882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[14] >> scalebits]; 3892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[15] >> scalebits]; 3902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#else 3912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int i; 3922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const int *c = src; 3932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *d = dst; 3942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c++) 3952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c) >> scalebits); 3962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 3972b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line; 3982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c++) 3992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c) >> scalebits); 4002b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4012b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line*2; 4022b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c++) 4032b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c) >> scalebits); 4042b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4052b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line*3; 4062b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c++) 4072b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c) >> scalebits); 4082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#endif 4092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 4102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 4122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * Copy the 4x4 image block to a CrCb plane buffer 4132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 4142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 4152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) 4162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 4172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#if UNROLL_LOOP_FOR_COPY 4182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Unroll all loops */ 4192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; 4202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const int *c = src; 4212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *d = dst; 4222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[0] >> scalebits]; 4242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[4] >> scalebits]; 4252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[1] >> scalebits]; 4262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[5] >> scalebits]; 4272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[2] >> scalebits]; 4282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[6] >> scalebits]; 4292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[3] >> scalebits]; 4302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[7] >> scalebits]; 4312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line; 4332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[12] >> scalebits]; 4342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[8] >> scalebits]; 4352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[13] >> scalebits]; 4362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[9] >> scalebits]; 4372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[14] >> scalebits]; 4382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[10] >> scalebits]; 4392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[15] >> scalebits]; 4402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = cm[c[11] >> scalebits]; 4412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#else 4422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int i; 4432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const int *c1 = src; 4442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const int *c2 = src + 4; 4452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *d = dst; 4462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c1++, c2++) { 4482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c1) >> scalebits); 4492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c2) >> scalebits); 4502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 4512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard c1 = src + 12; 4522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard d = dst + bytes_per_line; 4532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 4; i++, c1++, c2++) { 4542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c1) >> scalebits); 4552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard *d++ = CLAMP((*c2) >> scalebits); 4562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 4572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#endif 4582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 4592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 4612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * To manage the stream, we keep bits in a 32 bits register. 4622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * fill_nbits(n): fill the reservoir with at least n bits 4632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * skip_bits(n): discard n bits from the reservoir 4642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * get_bits(n): fill the reservoir, returns the first n bits and discard the 4652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * bits from the reservoir. 4662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir 4672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * contains at least n bits. bits returned is discarded. 4682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 4692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define fill_nbits(pdec, nbits_wanted) do { \ 4702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard while (pdec->nbits_in_reservoir<(nbits_wanted)) \ 4712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard { \ 4722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \ 4732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits_in_reservoir += 8; \ 4742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } \ 4752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} while(0); 4762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define skip_nbits(pdec, nbits_to_skip) do { \ 4782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->reservoir >>= (nbits_to_skip); \ 4792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits_in_reservoir -= (nbits_to_skip); \ 4802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} while(0); 4812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define get_nbits(pdec, nbits_wanted, result) do { \ 4832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard fill_nbits(pdec, nbits_wanted); \ 4842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ 4852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, nbits_wanted); \ 4862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} while(0); 4872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define __get_nbits(pdec, nbits_wanted, result) do { \ 4892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ 4902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, nbits_wanted); \ 4912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} while(0); 4922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard#define look_nbits(pdec, nbits_wanted) \ 4942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ((pdec->reservoir) & ((1U<<(nbits_wanted))-1)) 4952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 4962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/* 4972b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * Decode a 4x4 pixel block 4982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 4992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void decode_block(struct pwc_dec23_private *pdec, 5002b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *ptable0004, 5012b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *ptable8004) 5022b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 5032b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int primary_color; 5042b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int channel_v, offset1, op; 5052b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int i; 5062b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5072b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard fill_nbits(pdec, 16); 5082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard __get_nbits(pdec, pdec->nbits, primary_color); 5092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (look_nbits(pdec,2) == 0) { 5112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, 2); 5122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Very simple, the color is the same for all pixels of the square */ 5132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 16; i++) 5142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->temp_colors[i] = pdec->table_dc00[primary_color]; 5152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard return; 5172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 5182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* This block is encoded with small pattern */ 5202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 16; i++) 5212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->temp_colors[i] = pdec->table_d800[primary_color]; 5222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard __get_nbits(pdec, 3, channel_v); 5242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2); 5252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable0004 += (channel_v * 128); 5272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable8004 += (channel_v * 32); 5282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 = 0; 5302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard do 5312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard { 5322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int htable_idx, rows = 0; 5332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned int *block; 5342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* [ zzzz y x x ] 5362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * xx == 00 :=> end of the block def, remove the two bits from the stream 5372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * yxx == 111 5382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * yxx == any other value 5392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 5402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 5412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard fill_nbits(pdec, 16); 5422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard htable_idx = look_nbits(pdec, 6); 5432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard op = hash_table_ops[htable_idx * 4]; 5442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard if (op == 2) { 5462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, 2); 5472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } else if (op == 1) { 5492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* 15bits [ xxxx xxxx yyyy 111 ] 5502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * yyy => offset in the table8004 5512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * xxx => offset in the tabled004 (tree) 5522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 5532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int mask, shift; 5542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int nbits, col1; 5552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int yyyy; 5562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, 3); 5582b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* offset1 += yyyy */ 5592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard __get_nbits(pdec, 4, yyyy); 5602b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 += 1 + yyyy; 5612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 &= 0x0F; 5622b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard nbits = ptable8004[offset1 * 2]; 5632b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5642b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* col1 = xxxx xxxx */ 5652b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard __get_nbits(pdec, nbits+1, col1); 5662b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5672b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Bit mask table */ 5682b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard mask = pdec->table_bitpowermask[nbits][col1]; 5692b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard shift = ptable8004[offset1 * 2 + 1]; 5702b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard rows = ((mask << shift) + 0x80) & 0xFF; 5712b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard block = pdec->table_subblock[rows]; 5732b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 16; i++) 5742b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->temp_colors[i] += block[MulIdx[offset1][i]]; 5752b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5762b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } else { 5772b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* op == 0 5782b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * offset1 is coded on 3 bits 5792b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 5802b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int shift; 5812b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5822b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 += hash_table_ops [htable_idx * 4 + 2]; 5832b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard offset1 &= 0x0F; 5842b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5852b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]]; 5862b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard block = pdec->table_subblock[rows]; 5872b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard for (i = 0; i < 16; i++) 5882b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->temp_colors[i] += block[MulIdx[offset1][i]]; 5892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5902b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard shift = hash_table_ops[htable_idx * 4 + 1]; 5912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard skip_nbits(pdec, shift); 5922b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 5932b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5942b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } while (op != 2); 5952b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5962b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 5972b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 5982b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillardstatic void DecompressBand23(struct pwc_dec23_private *pdec, 5992b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *rawyuv, 6002b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *planar_y, 6012b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *planar_u, 6022b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned char *planar_v, 6032b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int compressed_image_width, 6042b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard unsigned int real_image_width) 6052b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 6062b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard int compression_index, nblocks; 6072b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *ptable0004; 6082b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const unsigned char *ptable8004; 6092b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6102b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->reservoir = 0; 6112b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->nbits_in_reservoir = 0; 6122b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */ 6132b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6142b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard get_nbits(pdec, 4, compression_index); 6152b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6162b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* pass 1: uncompress Y component */ 6172b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard nblocks = compressed_image_width / 4; 6182b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6192b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable0004 = pdec->table_0004_pass1[compression_index]; 6202b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable8004 = pdec->table_8004_pass1[compression_index]; 6212b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6222b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Each block decode a square of 4x4 */ 6232b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard while (nblocks) { 6242b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard decode_block(pdec, ptable0004, ptable8004); 6252b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits); 6262b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard planar_y += 4; 6272b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard nblocks--; 6282b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 6292b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6302b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* pass 2: uncompress UV component */ 6312b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard nblocks = compressed_image_width / 8; 6322b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6332b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable0004 = pdec->table_0004_pass2[compression_index]; 6342b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard ptable8004 = pdec->table_8004_pass2[compression_index]; 6352b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6362b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard /* Each block decode a square of 4x4 */ 6372b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard while (nblocks) { 6382b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard decode_block(pdec, ptable0004, ptable8004); 6392b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits); 6402b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6412b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard decode_block(pdec, ptable0004, ptable8004); 6422b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits); 6432b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6442b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard planar_v += 8; 6452b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard planar_u += 8; 6462b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard nblocks -= 2; 6472b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 6482b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6492b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 6502b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 6512b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard/** 6522b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 6532b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * Uncompress a pwc23 buffer. 6542b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * 6552b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * src: raw data 6562b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard * dst: image output 6572b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard */ 65856ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goedevoid pwc_dec23_decompress(struct pwc_device *pdev, 6592b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard const void *src, 660dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede void *dst) 6612b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard{ 662795e6eb3262d3b7247ce450835eea6df6571d103Hans de Goede int bandlines_left, bytes_per_block; 66356ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede struct pwc_dec23_private *pdec = &pdev->dec23; 664c20d78cde37018caa0313469c9320424995cc489Hans de Goede 665dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede /* YUV420P image format */ 666dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede unsigned char *pout_planar_y; 667dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede unsigned char *pout_planar_u; 668dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede unsigned char *pout_planar_v; 669dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede unsigned int plane_size; 670dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede 671c20d78cde37018caa0313469c9320424995cc489Hans de Goede mutex_lock(&pdec->lock); 6722b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard 67356ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede bandlines_left = pdev->height / 4; 67456ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede bytes_per_block = pdev->width * 4; 67556ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede plane_size = pdev->height * pdev->width; 676dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede 677795e6eb3262d3b7247ce450835eea6df6571d103Hans de Goede pout_planar_y = dst; 678795e6eb3262d3b7247ce450835eea6df6571d103Hans de Goede pout_planar_u = dst + plane_size; 679795e6eb3262d3b7247ce450835eea6df6571d103Hans de Goede pout_planar_v = dst + plane_size + plane_size / 4; 680dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede 681dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede while (bandlines_left--) { 68256ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede DecompressBand23(pdec, src, 683dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede pout_planar_y, pout_planar_u, pout_planar_v, 68456ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede pdev->width, pdev->width); 68556ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede src += pdev->vbandlength; 686dc8a7e83aaf8bb1bcf7163bda8926a6dd29c409bHans de Goede pout_planar_y += bytes_per_block; 68756ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede pout_planar_u += pdev->width; 68856ae24aad8f9e25dfef995c3e898e5f394cf0bebHans de Goede pout_planar_v += pdev->width; 6892b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard } 690c20d78cde37018caa0313469c9320424995cc489Hans de Goede mutex_unlock(&pdec->lock); 6912b455db6d456ef2d44808a8377fd3bc832e08317Luc Saillard} 692