// SPDX-License-Identifier: GPL-2.0-or-later /* Linux driver for Philips webcam Decompression for chipset version 2 et 3 (C) 2004-2006 Luc Saillard ([email protected]) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. Please send bug reports and support requests to <[email protected]>. The decompression routines have been implemented by reverse-engineering the Nemosoft binary pwcx module. Caveat emptor. */ #include "pwc-timon.h" #include "pwc-kiara.h" #include "pwc-dec23.h" #include <linux/string.h> #include <linux/slab.h> /* * USE_LOOKUP_TABLE_TO_CLAMP * 0: use a C version of this tests: { a<0?0:(a>255?255:a) } * 1: use a faster lookup table for cpu with a big cache (intel) */ #define USE_LOOKUP_TABLE_TO_CLAMP … /* * UNROLL_LOOP_FOR_COPYING_BLOCK * 0: use a loop for a smaller code (but little slower) * 1: when unrolling the loop, gcc produces some faster code (perhaps only * valid for intel processor class). Activating this option, automatically * activate USE_LOOKUP_TABLE_TO_CLAMP */ #define UNROLL_LOOP_FOR_COPY … #if UNROLL_LOOP_FOR_COPY # undef USE_LOOKUP_TABLE_TO_CLAMP #define USE_LOOKUP_TABLE_TO_CLAMP … #endif static void build_subblock_pattern(struct pwc_dec23_private *pdec) { … } static void build_bit_powermask_table(struct pwc_dec23_private *pdec) { … } static void build_table_color(const unsigned int romtable[16][8], unsigned char p0004[16][1024], unsigned char p8004[16][256]) { … } /* * */ static void fill_table_dc00_d800(struct pwc_dec23_private *pdec) { … } /* * To decode the stream: * if look_bits(2) == 0: # op == 2 in the lookup table * skip_bits(2) * end of the stream * elif look_bits(3) == 7: # op == 1 in the lookup table * skip_bits(3) * yyyy = get_bits(4) * xxxx = get_bits(8) * else: # op == 0 in the lookup table * skip_bits(x) * * For speedup processing, we build a lookup table and we takes the first 6 bits. * * struct { * unsigned char op; // operation to execute * unsigned char bits; // bits use to perform operation * unsigned char offset1; // offset to add to access in the table_0004 % 16 * unsigned char offset2; // offset to add to access in the table_0004 * } * * How to build this table ? * op == 2 when (i%4)==0 * op == 1 when (i%8)==7 * op == 0 otherwise * */ static const unsigned char hash_table_ops[64*4] = …; /* * */ static const unsigned int MulIdx[16][16] = …; #if USE_LOOKUP_TABLE_TO_CLAMP #define MAX_OUTER_CROP_VALUE … static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; #define CLAMP(x) … #else #define CLAMP … #endif /* If the type or the command change, we rebuild the lookup table */ void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd) { … } /* * Copy the 4x4 image block to Y plane buffer */ static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) { … } /* * Copy the 4x4 image block to a CrCb plane buffer * */ static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) { … } /* * To manage the stream, we keep bits in a 32 bits register. * fill_nbits(n): fill the reservoir with at least n bits * skip_bits(n): discard n bits from the reservoir * get_bits(n): fill the reservoir, returns the first n bits and discard the * bits from the reservoir. * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir * contains at least n bits. bits returned is discarded. */ #define fill_nbits(pdec, nbits_wanted) … #define skip_nbits(pdec, nbits_to_skip) … #define get_nbits(pdec, nbits_wanted, result) … #define __get_nbits(pdec, nbits_wanted, result) … #define look_nbits(pdec, nbits_wanted) … /* * Decode a 4x4 pixel block */ static void decode_block(struct pwc_dec23_private *pdec, const unsigned char *ptable0004, const unsigned char *ptable8004) { … } static void DecompressBand23(struct pwc_dec23_private *pdec, const unsigned char *rawyuv, unsigned char *planar_y, unsigned char *planar_u, unsigned char *planar_v, unsigned int compressed_image_width, unsigned int real_image_width) { … } /** * pwc_dec23_decompress - Uncompress a pwc23 buffer. * @pdev: pointer to pwc device's internal struct * @src: raw data * @dst: image output */ void pwc_dec23_decompress(struct pwc_device *pdev, const void *src, void *dst) { … }