Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Color_Targeting_Catapult
Fork of BaseJpegDecode by
BaseJpegDecode.cpp
00001 // BaseJpegDecode.cpp 2013/1/27 00002 #include "mbed.h" 00003 #include "BaseJpegDecode.h" 00004 00005 #if 0 00006 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0); 00007 #define DBG_WAIT(A) wait_ms(A) 00008 #else 00009 #define DBG(...) 00010 #define DBG_WAIT(A) 00011 #endif 00012 00013 #if 0 00014 #define DBG_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; 00015 #else 00016 #define DBG_ASSERT(A) 00017 #endif 00018 00019 #ifdef JPEG_USE_REPORT_CODE 00020 #define REPORT_CODE(A) (A) 00021 #else 00022 #define REPORT_CODE(A) 00023 #endif 00024 00025 #define MARK_SOF0 0xc0 00026 #define MARK_DHT 0xc4 00027 #define MARK_RST0 0xd0 00028 #define MARK_RST7 0xd7 00029 #define MARK_SOI 0xd8 00030 #define MARK_EOI 0xd9 00031 #define MARK_SOS 0xda 00032 #define MARK_DQT 0xdb 00033 #define MARK_DRI 0xdd 00034 #define MARK_APP 0xe0 00035 00036 #define SEQ_INIT 0 00037 #define SEQ_SOI 1 00038 #define SEQ_FRAME 2 00039 #define SEQ_MARK 3 00040 #define SEQ_SEG_LEN 4 00041 #define SEQ_SEG_LEN2 5 00042 #define SEQ_SEG_BODY 6 00043 #define SEQ_SOS 7 00044 #define SEQ_SOS2 8 00045 00046 #define HT_DC 0 00047 #define HT_AC 1 00048 00049 BaseJpegDecode::BaseJpegDecode() 00050 { 00051 yblock = JPEG_MCU_YBLOCK; // 2 or 4 00052 clear(); 00053 pHD = new HuffmanDecode; 00054 DBG_ASSERT(pHD); 00055 if (pHD == NULL) { 00056 return; 00057 } 00058 qt[0] = new uint8_t[64]; 00059 qt[1] = new uint8_t[64]; 00060 DBG_ASSERT(qt[0]); 00061 DBG_ASSERT(qt[1]); 00062 } 00063 00064 void BaseJpegDecode::clear() 00065 { 00066 m_seq = SEQ_INIT; 00067 } 00068 00069 void BaseJpegDecode::input(uint8_t* buf, int len) 00070 { 00071 for(int i = 0; i < len; i++) { 00072 input(buf[i]); 00073 printf("decode line %i\r\n", i); 00074 } 00075 } 00076 00077 void BaseJpegDecode::restart() 00078 { 00079 m_block = 0; 00080 m_scan = 0; 00081 m_pre_DC_value[0] = 0; 00082 m_pre_DC_value[1] = 0; 00083 m_pre_DC_value[2] = 0; 00084 m_bitpat.clear(); 00085 m_huff = NULL; 00086 } 00087 00088 void BaseJpegDecode::inputDQT(uint8_t c, int pos, int len) 00089 { 00090 if (pos == 0 || pos == 65) { 00091 m_param1 = c; 00092 DBG_ASSERT(m_param1 == 0 || m_param1 == 1); 00093 } else { 00094 if (m_param1 == 0 || m_param1 == 1) { 00095 if(qt[m_param1]) { 00096 qt[m_param1][(pos%65)-1] = c; 00097 } 00098 } 00099 } 00100 } 00101 00102 void BaseJpegDecode::inputSOF(uint8_t c, int pos, int len) 00103 { 00104 switch(pos) { 00105 case 1: 00106 height = (height&0x00ff) | (c<<8); 00107 break; 00108 case 2: 00109 height = (height&0xff00) | c; 00110 break; 00111 case 3: 00112 width = (width&0x00ff) | (c<<8); 00113 break; 00114 case 4: 00115 width = (width&0xff00) | c; 00116 break; 00117 case 7: 00118 if (c == 0x22) { 00119 yblock = 4; 00120 } else if (c == 0x21) { 00121 yblock = 2; 00122 } else { 00123 DBG_ASSERT(c == 0x22 || c == 0x21); 00124 } 00125 break; 00126 } 00127 } 00128 00129 void BaseJpegDecode::input(uint8_t c) 00130 { 00131 switch(m_seq) { 00132 case SEQ_INIT: 00133 if (c == 0xff) { 00134 m_seq = SEQ_SOI; 00135 } 00136 break; 00137 case SEQ_SOI: 00138 if (c == MARK_SOI) { 00139 outputMARK(c); 00140 m_seq = SEQ_FRAME; 00141 } else { 00142 m_seq = SEQ_INIT; 00143 } 00144 break; 00145 case SEQ_FRAME: 00146 if (c == 0xff) { 00147 m_seq = SEQ_MARK; 00148 } else { 00149 m_seq = SEQ_INIT; 00150 } 00151 break; 00152 case SEQ_MARK: 00153 outputMARK(c); 00154 if (c == MARK_SOI) { 00155 m_seq = SEQ_FRAME; 00156 break; 00157 } else if (c == MARK_EOI || c == 0x00) { 00158 m_seq = SEQ_INIT; 00159 break; 00160 } 00161 m_mark = c; 00162 m_seq = SEQ_SEG_LEN; 00163 break; 00164 case SEQ_SEG_LEN: 00165 m_seg_len = c; 00166 m_seq = SEQ_SEG_LEN2; 00167 break; 00168 case SEQ_SEG_LEN2: 00169 m_seg_len <<= 8; 00170 m_seg_len |= c; 00171 m_seg_len -= 2; 00172 m_seg_pos = 0; 00173 m_seq = SEQ_SEG_BODY; 00174 break; 00175 case SEQ_SEG_BODY: 00176 if (m_mark == MARK_DQT) { 00177 inputDQT(c, m_seg_pos, m_seg_len); 00178 } else if (m_mark == MARK_SOF0) { 00179 inputSOF(c, m_seg_pos, m_seg_len); 00180 } 00181 if (++m_seg_pos < m_seg_len) { 00182 break; 00183 } 00184 if (m_mark == MARK_SOS) { 00185 m_seq = SEQ_SOS; 00186 m_mcu = 0; 00187 restart(); 00188 break; 00189 } 00190 m_seq = SEQ_FRAME; 00191 break; 00192 case SEQ_SOS: 00193 if (c == 0xff) { 00194 m_seq = SEQ_SOS2; 00195 break; 00196 } 00197 inputScan(c); 00198 break; 00199 case SEQ_SOS2: 00200 if (c == 0x00) { 00201 inputScan(0xff); 00202 m_seq = SEQ_SOS; 00203 break; 00204 } else if (c >= MARK_RST0 && c <= MARK_RST7) { 00205 restart(); 00206 m_seq = SEQ_SOS; 00207 break; 00208 } 00209 outputMARK(c); 00210 m_seq = SEQ_INIT; 00211 break; 00212 default: 00213 break; 00214 } 00215 } 00216 00217 void BaseJpegDecode::inputScan(uint8_t c) 00218 { 00219 m_bitpat += c; 00220 while(m_bitpat.size() > 0) { 00221 int tc = (m_scan == 0) ? HT_DC : HT_AC; 00222 int th = (m_block < yblock) ? 0 : 1; 00223 DBG("%d %d %08x %d\n", tc, th, m_bitpat.peek(32), m_bitpat.size()); 00224 if (m_huff == NULL) { 00225 m_huff = pHD->Lookup(tc, th, &m_bitpat); 00226 if (m_huff == NULL) { 00227 break; 00228 } 00229 m_bitpat.get(m_huff->code_size); // skip code 00230 } 00231 if (m_huff->value_size > m_bitpat.size()) { 00232 break; 00233 } 00234 DBG("%d %d %d %02x\n", m_huff->run, m_huff->value_size, m_huff->code_size, m_huff->code); 00235 int value = pHD->getValue(m_huff, &m_bitpat); 00236 if (tc == HT_DC) { 00237 int sc = 0; // Y 00238 if (m_block == yblock) { 00239 sc = 1; // Cb 00240 } else if (m_block == (yblock+1)) { 00241 sc = 2; // Cr 00242 } 00243 value += m_pre_DC_value[sc]; 00244 outputDC(m_mcu, m_block, value); 00245 m_pre_DC_value[sc] = value; 00246 m_scan++; 00247 REPORT_CODE(report_scan_dc_count++); 00248 } else { // AC 00249 if (m_huff->value_size == 0 && m_huff->run == 0) { // EOB 00250 DBG("AC EOB\n"); 00251 outputAC(m_mcu, m_block, 63, 0); 00252 m_scan = 64; 00253 } else { 00254 for(int i = 0; i < m_huff->run; i++) { 00255 //outputAC(m_mcu, m_block, m_scan, 0); 00256 m_scan++; 00257 } 00258 outputAC(m_mcu, m_block, m_scan, value); 00259 m_scan++; 00260 } 00261 if (m_scan >= 64) { 00262 m_scan = 0; 00263 if (++m_block >= (yblock+2)) { 00264 m_block = 0; 00265 m_mcu++; 00266 } 00267 } 00268 REPORT_CODE(report_scan_ac_count++); 00269 } 00270 m_huff = NULL; 00271 REPORT_CODE(report_scan_count++); 00272 } 00273 }
Generated on Thu Jul 14 2022 19:18:05 by
1.7.2
