test
Dependencies: Nanopb iSerial mbed BaseJpegDecode FatFileSystem SDFileSystem RingBuffer Camera_LS_Y201
SimpleJpegDecode.cpp
00001 #include "SimpleJpegDecode.h" 00002 00003 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0); 00004 #define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; 00005 00006 00007 #define _1_4020 45 00008 #define _0_3441 11 00009 #define _0_7139 23 00010 #define _1_7718 57 00011 #define _0_0012 0 00012 00013 int adjust(int r) { 00014 if (r >= 0) { 00015 if (r <= 255) { 00016 return r; 00017 } else { 00018 return 255; 00019 } 00020 } else { 00021 return 0; 00022 } 00023 } 00024 00025 void convYUVtoRGB(uint8_t rgb[], int y, int u, int v) 00026 { 00027 rgb[0] = adjust((y*32 + v*_1_4020)/32 + 128); 00028 rgb[1] = adjust((y*32 - u*_0_3441 - v*_0_7139)/32 + 128); 00029 rgb[2] = adjust((y*32 + u*_1_7718 - v*_0_0012)/32 + 128); 00030 } 00031 00032 SimpleJpegDecode::SimpleJpegDecode(uint8_t output_mode) 00033 { 00034 m_output_mode = output_mode; 00035 clearOnResult(); 00036 } 00037 00038 00039 void SimpleJpegDecode::output(int mcu, int block, int scan, int value) 00040 { 00041 int sc = (block < yblock) ? 0 : 1; 00042 inputBLOCK(mcu, block, scan, value * qt[sc][scan]); 00043 } 00044 00045 void SimpleJpegDecode::outputDC(int mcu, int block, int value) 00046 { 00047 output(mcu, block, 0, value); 00048 DC_count++; 00049 } 00050 00051 void SimpleJpegDecode::outputAC(int mcu, int block, int scan, int value) 00052 { 00053 output(mcu, block, scan, value); 00054 AC_count++; 00055 } 00056 00057 void SimpleJpegDecode::outputMARK(uint8_t c) 00058 { 00059 } 00060 00061 void SimpleJpegDecode::format_YUV(int mcu, int block, int8_t* values) 00062 { 00063 if (block < yblock+1) { 00064 memcpy(m_block_data[block], values, 64); 00065 return; 00066 } 00067 int mcu_x_count = (width+15)/16; 00068 int mcu_x = mcu % mcu_x_count; 00069 int mcu_y = mcu / mcu_x_count; 00070 uint8_t yuv[3]; 00071 if (yblock == 2) { 00072 for(int y = 0; y < 8; y++) { 00073 for(int x = 0; x < 16; x++) { 00074 yuv[0] = m_block_data[x/8][y*8+x%8] + 128; 00075 yuv[1] = m_block_data[2][y*8+x/2] + 128; 00076 yuv[2] = values[y*8+x/2] + 128; 00077 onResult(mcu_x * 16 + x, mcu_y * 8 + y, yuv); 00078 } 00079 } 00080 } else if (yblock == 4) { 00081 for(int y = 0; y < 16; y++) { 00082 for(int x = 0; x < 16; x++) { 00083 yuv[0] = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8] + 128; 00084 yuv[1] = m_block_data[4][(y/2)*8+x/2] + 128; 00085 yuv[2] = values[(y/2)*8+x/2] + 128; 00086 onResult(mcu_x * 16 + x, mcu_y * 16 + y, yuv); 00087 } 00088 } 00089 } else { 00090 ASSERT(yblock == 2 || yblock == 4); 00091 } 00092 } 00093 00094 void SimpleJpegDecode::format_RGB24(int mcu, int block, int8_t* values) 00095 { 00096 if (block < yblock+1) { 00097 memcpy(m_block_data[block], values, 64); 00098 return; 00099 } 00100 int mcu_x_count = (width+15)/16; 00101 int mcu_x = mcu % mcu_x_count; 00102 int mcu_y = mcu / mcu_x_count; 00103 uint8_t rgb[3]; 00104 if (yblock == 2) { 00105 for(int y = 0; y < 8; y++) { 00106 for(int x = 0; x < 16; x++) { 00107 int8_t yuv_y = m_block_data[x/8][y*8+x%8]; 00108 int8_t yuv_u = m_block_data[2][y*8+x/2]; 00109 int8_t yuv_v = values[y*8+x/2]; 00110 convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v); 00111 onResult(mcu_x * 16 + x, mcu_y * 8 + y, rgb); 00112 } 00113 } 00114 } else if (yblock == 4) { 00115 for(int y = 0; y < 16; y++) { 00116 for(int x = 0; x < 16; x++) { 00117 int8_t yuv_y = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8]; 00118 int8_t yuv_u = m_block_data[4][(y/2)*8+x/2]; 00119 int8_t yuv_v = values[(y/2)*8+x/2]; 00120 convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v); 00121 onResult(mcu_x * 16 + x, mcu_y * 16 + y, rgb); 00122 } 00123 } 00124 } else { 00125 ASSERT(yblock == 2 || yblock == 4); 00126 } 00127 } 00128 00129 void SimpleJpegDecode::outputBLOCK(int mcu, int block, int8_t* values) 00130 { 00131 BLOCK_count++; 00132 if (m_output_mode == YUV) { 00133 format_YUV(mcu, block, values); 00134 } else if (m_output_mode == RGB24) { 00135 format_RGB24(mcu, block, values); 00136 } else { 00137 ASSERT(m_output_mode == YUV || m_output_mode == RGB24); 00138 } 00139 } 00140 00141 void SimpleJpegDecode::onResult(int x, int y, uint8_t* yuv) 00142 { 00143 if(m_pCbItem && m_pCbMeth) 00144 (m_pCbItem->*m_pCbMeth)(x, y, yuv); 00145 else if(m_pCb) 00146 m_pCb(x, y, yuv); 00147 } 00148 00149 void SimpleJpegDecode::setOnResult( void (*pMethod)(int, int, uint8_t*) ) 00150 { 00151 m_pCb = pMethod; 00152 m_pCbItem = NULL; 00153 m_pCbMeth = NULL; 00154 } 00155 00156 void SimpleJpegDecode::clearOnResult() 00157 { 00158 m_pCb = NULL; 00159 m_pCbItem = NULL; 00160 m_pCbMeth = NULL; 00161 }
Generated on Wed Jul 13 2022 04:41:35 by 1.7.2