📄 zc030x_jpeg.c
字号:
/* Include declaration */#include "zc030x_kerneldef.h"#include "zc030x_jpeg.h"#include "zc030x_v4l.h"/* Decoder specific structure, shouldn't be exported */typedef struct{ int Index; // Index of this minimum code entry long CodeValue; // And its code value} MinimumCodeEntry;typedef struct { MinimumCodeEntry * pMinCodeTable; // Minimum code table (given the huffman tree) and a length, as index long * pMaxCodeTable; // Maximum code table (given the huffman tree) and a length, as index unsigned char * pCodeCatTable; // The code category (bit length) table unsigned short * pCodeTable; // The code itself table} HuffmanTable;typedef unsigned char byte;typedef unsigned short word;// Define functions// Construct the huffman tablesvoid ConstructHuffmanTables(void);// Get n bit from the huffman streamint GetNBits(int NumberOfBits, byte **); // Get code from this stream given the huffman tableint GetCode(HuffmanTable * pTable, byte ** Buf); // Decode a codeint DecodeCode(int Code, int NumberOfBits); // Invert DCT//TBRM: static void IDCT (short Data[]);// InverDCT caller plus dequantifierint InvertDCT(short vector[], byte quant[]);/* Define DCT block size and constants */#define DCTSIZE 8 #define DCTSIZE2 64 /* Should remove the L prefix on x64 architecture */#define ONE 0x00000001 /* Define architecture independant right shifting operator */#ifdef RIGHT_SHIFT_IS_UNSIGNED#define LG2_DCT_SCALE 15#define RIGHT_SHIFT(_x,_shft) ((((_x) + (ONE << 30)) >> (_shft)) - (ONE << (30 - (_shft))))#else#define LG2_DCT_SCALE 16#define RIGHT_SHIFT(_x,_shft) ((_x) >> (_shft))#endif/* Define DCT scales */#define DCT_SCALE (ONE << LG2_DCT_SCALE)/* Define iDCT scale constants */#define LG2_OVERSCALE 2#define OVERSCALE (ONE << LG2_OVERSCALE)/* Define iDCT macros */#define FIX(x) ((int) ((x) * DCT_SCALE + 0.5))#define FIXO(x) ((int) ((x) * DCT_SCALE / OVERSCALE + 0.5))#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)), LG2_DCT_SCALE-LG2_OVERSCALE)#define OVERSH(x) ((x) << LG2_OVERSCALE)/* Define iDCT constants */#define SIN_1_4 FIX(0.7071067811856476)#define COS_1_4 SIN_1_4/* Define iDCT constants */#define SIN_1_8 FIX(0.3826834323650898)#define COS_1_8 FIX(0.9238795325112870)#define SIN_3_8 COS_1_8#define COS_3_8 SIN_1_8/* Define iDCT constants */#define SIN_1_16 FIX(0.1950903220161282)#define COS_1_16 FIX(0.9807852804032300)#define SIN_7_16 COS_1_16#define COS_7_16 SIN_1_16/* Define iDCT constants */#define SIN_3_16 FIX(0.5555702330196022)#define COS_3_16 FIX(0.8314696123025450)#define SIN_5_16 COS_3_16#define COS_5_16 SIN_3_16/* Define iDCT constants */#define OSIN_1_4 FIXO(0.707106781185647)#define OCOS_1_4 OSIN_1_4/* Define iDCT constants */#define OSIN_1_8 FIXO(0.3826834323650898)#define OCOS_1_8 FIXO(0.9238795325112870)#define OSIN_3_8 OCOS_1_8#define OCOS_3_8 OSIN_1_8/* Define iDCT constants */#define OSIN_1_16 FIXO(0.1950903220161282)#define OCOS_1_16 FIXO(0.9807852804032300)#define OSIN_7_16 OCOS_1_16#define OCOS_7_16 OSIN_1_16/* Define iDCT constants */#define OSIN_3_16 FIXO(0.5555702330196022)#define OCOS_3_16 FIXO(0.8314696123025450)#define OSIN_5_16 OCOS_3_16#define OCOS_5_16 OSIN_3_16/* Define fixed point values */#define FIX_1_082392200 277 /* FIX(1.082392200) */#define FIX_1_414213562 362 /* FIX(1.414213562) */#define FIX_1_847759065 473 /* FIX(1.847759065) */#define FIX_2_613125930 669 /* FIX(2.613125930) *//* For outputting to file */#define BGR(B,G,R) B, G, R#define JPGToBGR(Y,U,V, B, G, R) _JPGToBGR(Y,U,V,B,G,R)//this will store _ONE_ pixel in one of the specified RGB formats in the vram buffer////Thommy: Replaced global variable Framewidth with local variable width.// Don't use so much global variables! this will effctively prohibit // the code running with more than one webcam at a time.// As of now, i don't see any need of this, but if we start to do// things the right way, we will have much less cleanup when we reach 1.0// release (in some years ... :( )// I've also added an height variable. note this is not required here,// but IS required the YUV routine when support for planar formats is added.inline void gfxPixelRGB24(s16 x, s16 y, u8 b, u8 g, u8 r, u8 *vram, int width, int height){ Pixel24 *pVram = (Pixel24*)vram; pVram[x + y * width].B = b; pVram[x + y * width].G = g; pVram[x + y * width].R = r;}inline void gfxPixelRGB32(s16 x, s16 y, u8 b, u8 g, u8 r, u8 *vram, int width, int height){ Pixel32 *pVram = (Pixel32*)vram; pVram[x + y * width].B = b; pVram[x + y * width].G = g; pVram[x + y * width].R = r;}// this is to store _TWO_ pixels in some YUV 4:2:2 format. It's two pixels cause // UV are shared between two pixels.// Note that the cam will always output YUV 4:2:2, if it'll output YUV 4:2:0,// then chrominance is simply upscaled by duplicating every line.//// This only support UYUV but it should be very simple to implement other YUV 4:2:2 formats,// e.g. Planar, etc ... I'll do this when i see a need for this.// YUV 4:2:0, 4:1:1, 4:1:0 could be supported by adding some downscaling code here.inline void gfxPixelYUV(s16 x, s16 y, u8 y1, u8 u, u8 y2, u8 v, u8* vram, int width, int height){ PixelUYVY *pVram = (PixelUYVY*)vram; s16 fw = y * width / 2; x = x >> 1; pVram[x + fw].Y1 = y1; pVram[x + fw].Y2 = y2; pVram[x + fw].U = u; pVram[x + fw].V = v;}/*static inline int IsRGBformat (int format){ return ((format == VIDEO_PALETTE_RGB24) || (format == VIDEO_PALETTE_RGB32));}*/void _JPGToBGR (s16 y0, s16 cb0, s16 cr0, s16 *b0, s16 *g0, s16 *r0);/* Receive bits */s16 JPGReceiveBits (u16 cat, u8 * jpgdata);/* Zig-zag reordering indexes */const u8 JPGZig1 [64] = { 0,0,1,2,1,0,0,1,2,3,4,3,2,1,0,0,1,2,3,4,5,6,5,4,3,2,1,0,0,1,2,3, 4,5,6,7,7,6,5,4,3,2,1,2,3,4,5,6,7,7,6,5,4,3,4,5,6,7,7,6,5,6,7,7 };/* Zig-zag reordering indexes */const u8 JPGZig2 [64] = { 0,1,0,0,1,2,3,2,1,0,0,1,2,3,4,5,4,3,2,1,0,0,1,2,3,4,5,6,7,6,5,4, 3,2,1,0,1,2,3,4,5,6,7,7,6,5,4,3,2,3,4,5,6,7,7,6,5,4,5,6,7,7,6,7 };/* Precomputed fixed point iDCT&descalers coefficient */const u16 aanscales[64] = { /* precomputed values scaled up by 14 bits */ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 };/* Type definitions */struct JpegType{ u16 Rows; /* Picture's Height */ u16 Cols; /* Picture's Width */ u16 SamplesY; /* Sampling ratios */ u16 SamplesCbCr; u16 QuantTableY; /* Quantization table index */ u16 QuantTableCbCr; u16 HuffDCTableY; /* Huffman table index */ u16 HuffDCTableCbCr; u16 HuffACTableY; u16 HuffACTableCbCr; u16 NumComp; /* Components number */};/* An huffman entry is defined by its index, its code and its length */struct JPGHuffmanEntry { u16 Index; s16 Code; u16 Length;}__attribute__ ((packed));u32 findex = 0;u16 DCTables;u16 ACTables;u16 QTables;u8 curByte;u8 curBits;u8 EOI;struct JPGHuffmanEntry HuffmanDC0[256];struct JPGHuffmanEntry HuffmanDC1[256];struct JPGHuffmanEntry HuffmanAC0[256];struct JPGHuffmanEntry HuffmanAC1[256];//u16 ZigIndex;u16 QuantTable[2][8][8]; // 2 quantization tables (Y, CbCr)struct JpegType Image;//u16 flen;//s16 i;#define CompileTable// Modified by Cyril (Created)/* Forward declaration */typedef struct JPGHuffmanEntry * PJPGHuffmanEntry;/* Save an huffman table in the structure */u32 SaveTable(PJPGHuffmanEntry Huffman, u8 * bits, u8 * vals){ /* Total number of bits in the huffman table */ u16 total = 0; /* Iterators */ u32 i,j; /* Iterator and temporary values */ u16 CurNum = 0; u16 CurIndex = 0; u16 HuffAmount[16]; /* Read the number of codes for each code size */ for (i=0; i<16; i++) { total += bits[i]; HuffAmount[i] = bits[i]; } /* Read all codes, for each length */ for (i=0; i<total; i++) { Huffman[i].Code = vals[i]; } /* Now create the table correctly */ CurNum = 0; CurIndex = -1; for (i=0; i<16; i++) { for (j=0; j < HuffAmount[i]; j++) { CurIndex++; Huffman[CurIndex].Index = CurNum; Huffman[CurIndex].Length = i+1; CurNum++; } CurNum *= 2; } /* Exit */ return 0;}/* Left shift macro */#define JPGpower2(X) ( 1 << (X) )/* Get a byte from the stream */inline u8 JPGGetByte (u8 * jpgdata){ return (jpgdata[findex++]);}/* Get a endianness word from the stream */inline u16 JPGGetWord (u8 * jpgdata){ u16 i = JPGGetByte(jpgdata) << 8; i += JPGGetByte(jpgdata); return (i);}/* Get next byte from the stream */inline u8 JPGNextBit (u8 * jpgdata){ u8 NextBit; curBits >>= 1; NextBit = (curByte >> 7) & 1; curByte <<= 1; if (curBits == 0) { curBits = 128; curByte = JPGGetByte(jpgdata); if (curByte == 0xFF) if (JPGGetByte(jpgdata) == 0xD9) { EOI = 1; return(0); } } return(NextBit);}/* Decode a JPEG compressed block */inline s16 JPGDecode(struct JPGHuffmanEntry inArray[256], u8 * jpgdata){ u16 n1; u16 n2; u16 i; u16 l; s32 CurVal; s16 MatchFound; /* Check if we have a JPEG marker */ if (JPGGetByte(jpgdata) == 0xFF) { n1 = JPGGetByte(jpgdata); findex -= 2; if ((n1 >= 0xd0) && (n1 <= 0xd7)) { n2 = curBits - 1; /* Check for end of image (remaining bits = 1) */ if ((curByte & n2) == n2) { EOI = 1; return 0; } } } else findex--; /* Else try to find the huffman code */ CurVal = 0; MatchFound = -1; /* Cycle through the possible 16 bits huffman code length */ for (l=1; l<16+1; l++) { CurVal = (CurVal << 1) + JPGNextBit(jpgdata); if (EOI) return(0); /* Check the lookup table */ for (i=0; i<256; i++) { if (inArray[i].Length > l) break; if (inArray[i].Length == l) if (inArray[i].Index == CurVal) { MatchFound = i; break; } } if (MatchFound > -1) break; } if (MatchFound == -1) { PDEBUG(3,"Error with the current huffman table"); EOI = 1; return(-1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -