📄 zc030x_jpeg.c
字号:
u16 i,j; u16 i2; u16 j2; s16 cb; s16 cr; u16 xj; u16 yi; s16 r; s16 g; s16 b; // This is offset to place the decoded picture u8 x0 = 0; u8 y0 = 0; QTables = 0; // Initialize some checkpoint variables ACTables = 0; DCTables = 0; findex = 0; if (JPGGetByte(jpgdata) == 0xff) { if (JPGGetByte(jpgdata) == 0xd8) exit = 0; } // Exit if not a JPEG file if (exit) return(0); //THOMMY: //get Width and Height from Jpeg header instead of relying on global variables. //this will prevent crashes if the variables FrameWidth and FrameHeight are set up inproperly. //this should allow me to test what happens if i set up framewidth and frameheigt to 640x480 wWidth = ((int)jpgdata[12]<<8) | (int)jpgdata[13]; height = ((int)jpgdata[14]<<8) | (int)jpgdata[15]; if (height < wHeight) wHeight = height; while (!exit) { if (JPGGetByte(jpgdata) == 0xff) { switch (JPGGetByte(jpgdata)) { case 0x00: //not important break; case 0xc0: //SOF0 PDEBUG(3,"Found start of frame 0"); JPGGetImageAttr(jpgdata); break; case 0xc1: //SOF1 PDEBUG(3,"Found start of frame 1"); JPGGetImageAttr(jpgdata); break; case 0xc4: //DHT PDEBUG(3,"Found huffman tables (A:%d,D:%d)", ACTables, DCTables ); if ((ACTables < 2) || (DCTables < 2)) JPGGetHuffTables(jpgdata); PDEBUG(3,"NbAC : %d, NbDC : %d", ACTables, DCTables); break; case 0xc9: //SOF9 break; case 0xd9: //EOI PDEBUG(3,"Found end of image"); exit = 1; break; case 0xda: //SOS PDEBUG(3,"Found start of scan"); JPGGetSOS(jpgdata); if ( ((DCTables == 2) && (ACTables == 2) && (QTables == 2)) || (Image.NumComp == 1) ) { EOI = 0; exit = 1; // Go on to secondary control loop } else { PDEBUG(3,"Not enough tables"); } break; case 0xdb: //DQT PDEBUG(3,"Found quantification tables"); if (QTables < 2) JPGGetQuantTables(jpgdata); break; case 0xdd: //DRI PDEBUG(3,"Found restart interval"); (void) JPGGetWord(jpgdata); // Length of segment Restart = JPGGetWord(jpgdata); PDEBUG(3,"Restart read : %d", Restart); break; case 0xe0: //APP0 PDEBUG(3,"Found application specific"); (void) JPGGetWord(jpgdata); // Length of segment findex += 5; (void) JPGGetByte(jpgdata); // Major revision (void) JPGGetByte(jpgdata); // Minor revision (void) JPGGetByte(jpgdata); // Density definition (void) JPGGetByte(jpgdata); // X density (void) JPGGetByte(jpgdata); // Y density (void) JPGGetByte(jpgdata); // Thumbnail width (void) JPGGetByte(jpgdata); // Thumbnail height break; case 0xfe: //COM// Modified by Cyril// In Zc0302 modules, comment block is just before the real data// So we just have to consider this as an header (need to specify value here)// Modified by Cyril 26/9/04 - Forgot to think that JPGGetWord also advance findex// Remark : Should read the picture size here, directly from the comment block.// But for that, it would be better to be able to send the correct init sequence first. findex += JPGGetWord(jpgdata) - 2; // Length of segment; // Set to 1 for GreyScale pictures Image.NumComp = bGrey ? 1 : 3; // This is because this stream is in 4:2:2 format (ie YYUV YYUV etc) Image.SamplesY = 2; Image.Cols = wWidth; Image.Rows = wHeight; Image.HuffACTableY = 0; Image.HuffDCTableY = 0; Image.HuffACTableCbCr = 1; Image.HuffDCTableCbCr = 1; EOI = 0; exit = 1; break; } } } XPos = 0; YPos = 0; // Initialize active variables dcY = 0; dcCb = 0; dcCr = 0; xindex = 0; yindex = 0; mcu = 0; r = 0; g = 0; b = 0; mcu = 0; curBits = 128; // Start with the seventh bit curByte = JPGGetByte(jpgdata); // Of the first byte switch (Image.NumComp) // How many components does the image have? { case 3: // 3 components (Y-Cb-Cr) { PDEBUG(3,"The sampling ratio is : %d", Image.SamplesY); switch (Image.SamplesY) // What's the sampling ratio of Y to CbCr? { case 2: // 2 pixels to 1 do { JPGGetBlock (YVector1, Image.HuffDCTableY, Image.HuffACTableY, Image.QuantTableY, &dcY, jpgdata); JPGGetBlock (YVector2, Image.HuffDCTableY, Image.HuffACTableY, Image.QuantTableY, &dcY, jpgdata); JPGGetBlock (CbVector, Image.HuffDCTableCbCr, Image.HuffACTableCbCr, Image.QuantTableCbCr, &dcCb, jpgdata); JPGGetBlock (CrVector, Image.HuffDCTableCbCr, Image.HuffACTableCbCr, Image.QuantTableCbCr, &dcCr, jpgdata); // YCbCr vectors have been obtained// PDEBUG(3,"Got the 4 blocks (now at %d,%d)", xindex, yindex); mcu++; if (EOI) { PDEBUG(3,"Error appeared with this picture"); return 0; } //modified by tommy //for YUV colorspaces for (i=0; i<8; i++) // Draw left 8x8 pixels for (j=0; j<8; j++) { y = YVector1[i][j]; i2 = i >> 1; j2 = j >> 1; cb = CbVector[i2][j2]; cr = CrVector[i2][j2]; JPGToBGR (y, cb, cr, &b, &g, &r); xj = xindex + j; yi = yindex + i; if ((xj < Image.Cols) && (yi < Image.Rows)) gfxPixelRGB32 (xj + x0, yi + y0, BGR(b, g, r), vram, wWidth, wHeight); } for (i=0; i<8; i++) // Draw right 8x8 pixels for (j=8; j<16; j++) { y = YVector2[i][j - 8]; i2 = i >> 1; j2 = j >> 1; cb = CbVector[i2][j2]; cr = CrVector[i2][j2]; JPGToBGR (y, cb, cr, &b, &g, &r); xj = xindex + j; yi = yindex + i; if ((xj < Image.Cols) && (yi < Image.Rows)) gfxPixelRGB32 (xj + x0, yi + y0, BGR(b, g, r), vram, wWidth, wHeight); } xindex += 16; if (Restart && mcu == Restart) { // eject restart marker now u8 marker0 = JPGGetByte(jpgdata); u8 marker1 = JPGGetByte(jpgdata); if (marker0 != 0xFF || (marker1 < 0xD0 && marker1 > 0xD7)) { // A restart marker should be here, but not found PDEBUG(3,"Restart should be here, but not found, arounding byte are :"); PDEBUG(3,"%02X%02X%02X%02X%02X%02X%02X%02X %02X%02X%02X%02X%02X%02X%02X%02X", jpgdata[findex - 10], jpgdata[findex - 9], jpgdata[findex - 8], jpgdata[findex - 6], jpgdata[findex - 5], jpgdata[findex - 4], jpgdata[findex - 3], jpgdata[findex - 2], jpgdata[findex - 1], jpgdata[findex ], jpgdata[findex + 1], jpgdata[findex + 2], jpgdata[findex + 3], jpgdata[findex + 4], jpgdata[findex + 5], jpgdata[findex + 6]); PDEBUG(3,"Resync the stream now"); // Look in the +/- 8 bytes to find restart marker for (j = 0; j < 16; j++) { if (jpgdata[findex - 10 + j] == 0xFF && (jpgdata[findex - 9 + j] >= 0xD0 && jpgdata[findex - 9 + j] <= 0xD7 )) { // Found restart marker, sync the stream now findex -= (10 - j); marker0 = JPGGetByte(jpgdata); marker1 = JPGGetByte(jpgdata); PDEBUG(3,"Marker found : %02X, %02X", marker0, marker1); break; } } // No restart marker found, so stop decoding if (j == 16) return(0); } // Feed again the decoder curByte = JPGGetByte(jpgdata); PDEBUG(3,"%02X", curByte); curBits = 128; dcY = 0; dcCb = 0; dcCr = 0; mcu = 0; //Reset the DC value } if (xindex >= Image.Cols) { xindex = 0; yindex += 8; //mcu = 0; } } while (yindex < Image.Rows); break; } } case 1: do { JPGGetBlock (YVector1, Image.HuffDCTableY, Image.HuffACTableY, Image.QuantTableY, &dcY, jpgdata); for (i=0; i<8; i++) // Draw 8x8 pixels for (j=0; j<8; j++) { y = YVector1[i][j]; if (y < 0) y = 0; if (y > 255) y = 255; xj = xindex + j; yi = yindex + i; if ((xj < Image.Cols) && (yi < Image.Rows)) gfxPixelRGB32 (xj + x0, yi + y0, y, y, y, vram, wWidth, wHeight); } xindex += 8; if (xindex >= Image.Cols) { xindex = 0; yindex += 8; mcu = 1; } if ((mcu == 1) && (Restart != 0)) // execute the restart interval { curByte = JPGGetByte(jpgdata); curByte = JPGGetByte(jpgdata); curByte = JPGGetByte(jpgdata); curBits = 128; dcY = 0; mcu = 0; } } while (yindex < Image.Rows); break; } return(1);}/* Decode a picture */u32 gfxJpegRGB24 (u8 bGrey, u16 wWidth, u16 wHeight, u8 *vram, u8 * jpgdata, int format){ u8 exit = 1;// u16 u,v;// s16 x; s16 y;// float t; u16 Restart = 0; u16 XPos; u16 YPos; s16 dcY; s16 dcCb; s16 dcCr; u16 xindex; u16 yindex; u16 mcu; s16 YVector1[8][8]; // 4 vectors for Y attribute s16 YVector2[8][8]; // (not all may be needed) s16 CbVector[8][8]; // 1 vector for Cb attribute s16 CrVector[8][8]; // 1 vector for Cr attribute s16 height; u16 i,j; u16 i2; u16 j2; s16 cb; s16 cr; u16 xj; u16 yi; s16 r; s16 g; s16 b; // This is offset to place the decoded picture u8 x0 = 0; u8 y0 = 0; QTables = 0; // Initialize some checkpoint variables ACTables = 0; DCTables = 0; findex = 0; if (JPGGetByte(jpgdata) == 0xff) { if (JPGGetByte(jpgdata) == 0xd8) exit = 0; } // Exit if not a JPEG file if (exit) return(0); //THOMMY: //get Width and Height from Jpeg header instead of relying on global variables. //this will prevent crashes if the variables FrameWidth and FrameHeight are set up inproperly. //this should allow me to test what happens if i set up framewidth and frameheigt to 640x480 wWidth = ((int)jpgdata[12]<<8) | (int)jpgdata[13]; height = ((int)jpgdata[14]<<8) | (int)jpgdata[15]; if (height < wHeight) wHeight = height; while (!exit) { if (JPGGetByte(jpgdata) == 0xff) { switch (JPGGetByte(jpgdata)) { case 0x00: //not important break; case 0xc0: //SOF0 PDEBUG(3,"Found start of frame 0"); JPGGetImageAttr(jpgdata); break; case 0xc1: //SOF1 PDEBUG(3,"Found start of frame 1"); JPGGetImageAttr(jpgdata); break; case 0xc4: //DHT PDEBUG(3,"Found huffman tables (A:%d,D:%d)", ACTables, DCTables ); if ((ACTables < 2) || (DCTables < 2)) JPGGetHuffTables(jpgdata); PDEBUG(3,"NbAC : %d, NbDC : %d", ACTables, DCTables); break; case 0xc9: //SOF9 break; case 0xd9: //EOI PDEBUG(3,"Found end of image"); exit = 1; break; case 0xda: //SOS PDEBUG(3,"Found start of scan"); JPGGetSOS(jpgdata); if ( ((DCTables == 2) && (ACTables == 2) && (QTables == 2)) || (Image.NumComp == 1) ) { EOI = 0; exit = 1; // Go on to secondary control loop } else { PDEBUG(3,"Not enough tables");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -