📄 spcadecoder.c
字号:
val = 0; len = 0; if ((i & 0xC0) == 0) { /* code 00 */ val = 0; len = 2; } else if ((i & 0xC0) == 0x40) { /* code 01 */ val = -5; len = 2; } else if ((i & 0xC0) == 0x80) { /* code 10 */ val = +5; len = 2; } else if ((i & 0xF0) == 0xC0) { /* code 1100 */ val = -10; len = 4; } else if ((i & 0xF0) == 0xD0) { /* code 1101 */ val = +10; len = 4; } else if ((i & 0xF8) == 0xE0) { /* code 11100 */ val = -15; len = 5; } else if ((i & 0xF8) == 0xE8) { /* code 11101 */ val = +15; len = 5; } else if ((i & 0xFC) == 0xF0) { /* code 111100 */ val = -20; len = 6; } else if ((i & 0xFC) == 0xF4) { /* code 111101 */ val = +20; len = 6; } else if ((i & 0xF8) == 0xF8) { /* code 11111xxxxxx */ is_abs = 1; val = 0; len = 5; } table[i].is_abs = is_abs; table[i].val = val; table[i].len = len; }}static intpac_decompress_row(struct code_table_t *table, unsigned char *inp, unsigned char *outp, int width){ int col; int val; int bitpos; unsigned char code; /* first two pixels are stored as raw 8-bit */ *outp++ = inp[2]; *outp++ = inp[3]; bitpos = 32; /* main decoding loop */ for (col = 2; col < width; col++) { /* get bitcode */ code = getByte(inp, bitpos); bitpos += table[code].len; /* calculate pixel value */ if (table[code].is_abs) { /* absolute value: get 6 more bits */ code = getByte(inp, bitpos); bitpos += 6; *outp++ = code & 0xFC; } else { /* relative to left pixel */ val = outp[-2] + table[code].val; *outp++ = CLIP(val); } } /* return line length, rounded up to next 16-bit word */ return 2 * ((bitpos + 15) / 16);}#if 0static void tv8532_preprocess(struct spca50x_frame *myframe){/* we should received a whole frame with header and EOL markerin myframe->data and return a GBRG pattern in frame->tmpbuffer sequence 2bytes header the Alternate pixels bayer GB 4 bytes Alternate pixels bayer RG 4 bytes EOL */ int width = myframe->hdrwidth; int height = myframe->hdrheight; int src = 0; unsigned char *dst = myframe->tmpbuffer; unsigned char *data = myframe->data; int i; int seq1, seq2; /* precompute where is the good bayer line */ if ((((data[src + 3] + data[src + width + 7]) >> 1) + (data[src + 4] >> 2) + (data[src + width + 6] >> 1)) >= (((data[src + 2] + data[src + width + 6]) >> 1) + (data[src + 3] >> 2) + (data[src + width + 5] >> 1))) { seq1 = 3; seq2 = 4; } else { seq1 = 2; seq2 = 5; } for (i = 0; i < height / 2; i++) { src += seq1; memcpy(dst, &myframe->data[src], width); src += (width + 3); dst += width; memcpy(dst, &myframe->data[src], width); src += (width + seq2); dst += width; }}#endif static inline unsigned char cabs_diff(unsigned char a,unsigned char b){ return a>=b?a-b:b-a;};static void tv8532_preprocess(struct spca50x_frame *myframe){/* we should received a whole frame with header and EOL markerin myframe->data and return a GBRG pattern in frame->tmpbuffer sequence 2bytes header the Alternate pixels bayer GB 4 bytes Alternate pixels bayer RG 4 bytes EOL */ int width = myframe->hdrwidth; int height = myframe->hdrheight; int src = 0; unsigned char *dst = myframe->tmpbuffer; unsigned char *data = myframe->data; unsigned char * data_ptr; int seq1, seq2; int sum1=0,sum2=0; int height_inc=height/6-1; int width_inc=width/6-1; int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) { data_ptr=&data[(i*height_inc)*(width*2+10)+width_inc*j*2]; sum1+=cabs_diff(data_ptr[3],data_ptr[width + 7])+ cabs_diff(data_ptr[5],data_ptr[width + 7])+ cabs_diff(data_ptr[2*width+13],data_ptr[width + 7])+ cabs_diff(data_ptr[2*width+15],data_ptr[width + 7]); sum2+=cabs_diff(data_ptr[width + 6],data_ptr[4])+ cabs_diff(data_ptr[width + 6],data_ptr[2*width+14])+ cabs_diff(data_ptr[width + 8],data_ptr[4])+ cabs_diff(data_ptr[width + 8],data_ptr[2*width+14]); }; /* precompute where is the good bayer line */ if (sum1 <=sum2) { seq1 = 3; seq2 = 4; } else { seq1 = 2; seq2 = 5; }; for (i = 0; i < height / 2; i++) { src += seq1; memcpy(dst, &myframe->data[src], width); src += (width + 3); dst += width; memcpy(dst, &myframe->data[src], width); src += (width + seq2); dst += width; }}static inline unsigned short getShort(unsigned char *pt){ return ((pt[0] << 8) | pt[1]);}static int pixart_decompress(struct spca50x_frame *myframe){/* we should received a whole frame with header and EOL markerin myframe->data and return a GBRG pattern in frame->tmpbufferremove the header then copy line by line EOL is set with 0x0f 0xf0 markeror 0x1e 0xe1 for compressed line*/ int width = myframe->hdrwidth; int height = myframe->hdrheight; unsigned char *outp = myframe->tmpbuffer; unsigned char *inp = myframe->data; struct code_table_t *table = myframe->decoder->table; unsigned short word; int row; /* skip header */ inp += 16; /* and ask to go at pixel +1 ?? */ outp++; /* iterate over all rows */ for (row = 0; row < height; row++) { word = getShort(inp); switch (word) { case 0x0FF0: memcpy(outp, inp + 2, width); inp += (2 + width); break; case 0x1EE1: inp += pac_decompress_row(table, inp, outp, width); break; default: return -1; } outp += width; } return 0;}/*# Decoder for compressed spca561 images ## It was developed for "Labtec WebCam Elch 2(SPCA561A)" (046d:0929) ## but it might work with other spca561 cameras #*/static unsigned int bit_bucket;static unsigned char *input_ptr;static inline void refill(int *bitfill){ if (*bitfill < 8) { bit_bucket = (bit_bucket << 8) | *(input_ptr++); *bitfill += 8; }}static inline int nbits(int *bitfill, int n){ bit_bucket = (bit_bucket << 8) | *(input_ptr++); *bitfill -= n; return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1);}static inline int _nbits(int *bitfill, int n){ *bitfill -= n; return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1);}static int fun_A(int *bitfill){ int ret; static int tab[] = { 12, 13, 14, 15, 16, 17, 18, 19, -12, -13, -14, -15, -16, -17, -18, -19, -19 }; ret = tab[nbits(bitfill, 4)]; refill(bitfill); return ret;}static int fun_B(int *bitfill){ static int tab1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }; static int tab[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19 }; unsigned int tmp; tmp = nbits(bitfill, 7) - 68; refill(bitfill); if (tmp > 47) return 0xff; return tab[tab1[tmp]];}static int fun_C(int *bitfill, int gkw){ static int tab1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; static int tab[] = { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19 }; unsigned int tmp; if (gkw == 0xfe) { if (nbits(bitfill, 1) == 0) return 7; else return -8; } if (gkw != 0xff) return 0xff; tmp = nbits(bitfill, 7) - 72; if (tmp > 43) return 0xff; refill(bitfill); return tab[tab1[tmp]];}static int fun_D(int *bitfill, int gkw){ if (gkw == 0xfd) { if (nbits(bitfill, 1) == 0) return 12; else return -13; } if (gkw == 0xfc) { if (nbits(bitfill, 1) == 0) return 13; else return -14; } if (gkw == 0xfe) { switch (nbits(bitfill, 2)) { case 0: return 14; case 1: return -15; case 2: return 15; case 3: return -16; } } if (gkw == 0xff) { switch (nbits(bitfill, 3)) { case 4: return 16; case 5: return -17; case 6: return 17; case 7: return -18; case 2: return _nbits(bitfill, 1) ? 0xed : 0x12; case 3: *bitfill--; return 18; } return 0xff; } return gkw;}static int fun_E(int cur_byte, int *bitfill){ static int tab0[] = { 0, -1, 1, -2, 2, -3, 3, -4 }; static int tab1[] = { 4, -5, 5, -6, 6, -7, 7, -8 }; static int tab2[] = { 8, -9, 9, -10, 10, -11, 11, -12 }; static int tab3[] = { 12, -13, 13, -14, 14, -15, 15, -16 }; static int tab4[] = { 16, -17, 17, -18, 18, -19, 19, -19 }; if ((cur_byte & 0xf0) >= 0x80) { *bitfill -= 4; return tab0[(cur_byte >> 4) & 7]; } else if ((cur_byte & 0xc0) == 0x40) { *bitfill -= 5; return tab1[(cur_byte >> 3) & 7]; } else if ((cur_byte & 0xe0) == 0x20) { *bitfill -= 6; return tab2[(cur_byte >> 2) & 7]; } else if ((cur_byte & 0xf0) == 0x10) { *bitfill -= 7; return tab3[(cur_byte >> 1) & 7]; } else if ((cur_byte & 0xf8) == 8) { *bitfill -= 8; return tab4[cur_byte & 7]; } return 0xff;}static int fun_F(int cur_byte, int *bitfill){ *bitfill -= 5; switch (cur_byte & 0xf8) { case 0x80: return 0; case 0x88: return -1; case 0x90: return 1; case 0x98: return -2; case 0xa0: return 2; case 0xa8: return -3; case 0xb0: return 3; case 0xb8: return -4; case 0xc0: return 4; case 0xc8: return -5; case 0xd0: return 5; case 0xd8: return -6; case 0xe0: return 6; case 0xe8: return -7; case 0xf0: return 7; case 0xf8: return -8; } *bitfill -= 1; switch (cur_byte & 0xfc) { case 0x40: return 8; case 0x44: return -9; case 0x48:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -