test

Dependencies:   Nanopb iSerial mbed BaseJpegDecode FatFileSystem SDFileSystem RingBuffer Camera_LS_Y201

Committer:
cgraham
Date:
Thu Sep 18 15:21:47 2014 +0000
Revision:
0:d69efd0ee139
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cgraham 0:d69efd0ee139 1 // BaseJpegDecode.cpp 2013/1/27
cgraham 0:d69efd0ee139 2 #include "mbed.h"
cgraham 0:d69efd0ee139 3 #include "BaseJpegDecode.h"
cgraham 0:d69efd0ee139 4
cgraham 0:d69efd0ee139 5 #if 0
cgraham 0:d69efd0ee139 6 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
cgraham 0:d69efd0ee139 7 #define DBG_WAIT(A) wait_ms(A)
cgraham 0:d69efd0ee139 8 #else
cgraham 0:d69efd0ee139 9 #define DBG(...)
cgraham 0:d69efd0ee139 10 #define DBG_WAIT(A)
cgraham 0:d69efd0ee139 11 #endif
cgraham 0:d69efd0ee139 12
cgraham 0:d69efd0ee139 13 #if 0
cgraham 0:d69efd0ee139 14 #define DBG_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
cgraham 0:d69efd0ee139 15 #else
cgraham 0:d69efd0ee139 16 #define DBG_ASSERT(A)
cgraham 0:d69efd0ee139 17 #endif
cgraham 0:d69efd0ee139 18
cgraham 0:d69efd0ee139 19 #ifdef JPEG_USE_REPORT_CODE
cgraham 0:d69efd0ee139 20 #define REPORT_CODE(A) (A)
cgraham 0:d69efd0ee139 21 #else
cgraham 0:d69efd0ee139 22 #define REPORT_CODE(A)
cgraham 0:d69efd0ee139 23 #endif
cgraham 0:d69efd0ee139 24
cgraham 0:d69efd0ee139 25 #define MARK_SOF0 0xc0
cgraham 0:d69efd0ee139 26 #define MARK_DHT 0xc4
cgraham 0:d69efd0ee139 27 #define MARK_RST0 0xd0
cgraham 0:d69efd0ee139 28 #define MARK_RST7 0xd7
cgraham 0:d69efd0ee139 29 #define MARK_SOI 0xd8
cgraham 0:d69efd0ee139 30 #define MARK_EOI 0xd9
cgraham 0:d69efd0ee139 31 #define MARK_SOS 0xda
cgraham 0:d69efd0ee139 32 #define MARK_DQT 0xdb
cgraham 0:d69efd0ee139 33 #define MARK_DRI 0xdd
cgraham 0:d69efd0ee139 34 #define MARK_APP 0xe0
cgraham 0:d69efd0ee139 35
cgraham 0:d69efd0ee139 36 #define SEQ_INIT 0
cgraham 0:d69efd0ee139 37 #define SEQ_SOI 1
cgraham 0:d69efd0ee139 38 #define SEQ_FRAME 2
cgraham 0:d69efd0ee139 39 #define SEQ_MARK 3
cgraham 0:d69efd0ee139 40 #define SEQ_SEG_LEN 4
cgraham 0:d69efd0ee139 41 #define SEQ_SEG_LEN2 5
cgraham 0:d69efd0ee139 42 #define SEQ_SEG_BODY 6
cgraham 0:d69efd0ee139 43 #define SEQ_SOS 7
cgraham 0:d69efd0ee139 44 #define SEQ_SOS2 8
cgraham 0:d69efd0ee139 45
cgraham 0:d69efd0ee139 46 #define HT_DC 0
cgraham 0:d69efd0ee139 47 #define HT_AC 1
cgraham 0:d69efd0ee139 48
cgraham 0:d69efd0ee139 49 BaseJpegDecode::BaseJpegDecode()
cgraham 0:d69efd0ee139 50 {
cgraham 0:d69efd0ee139 51 yblock = JPEG_MCU_YBLOCK; // 2 or 4
cgraham 0:d69efd0ee139 52 clear();
cgraham 0:d69efd0ee139 53 pHD = new HuffmanDecode;
cgraham 0:d69efd0ee139 54 DBG_ASSERT(pHD);
cgraham 0:d69efd0ee139 55 if (pHD == NULL) {
cgraham 0:d69efd0ee139 56 return;
cgraham 0:d69efd0ee139 57 }
cgraham 0:d69efd0ee139 58 qt[0] = new uint8_t[64];
cgraham 0:d69efd0ee139 59 qt[1] = new uint8_t[64];
cgraham 0:d69efd0ee139 60 DBG_ASSERT(qt[0]);
cgraham 0:d69efd0ee139 61 DBG_ASSERT(qt[1]);
cgraham 0:d69efd0ee139 62 }
cgraham 0:d69efd0ee139 63
cgraham 0:d69efd0ee139 64 void BaseJpegDecode::clear()
cgraham 0:d69efd0ee139 65 {
cgraham 0:d69efd0ee139 66 m_seq = SEQ_INIT;
cgraham 0:d69efd0ee139 67 }
cgraham 0:d69efd0ee139 68
cgraham 0:d69efd0ee139 69 void BaseJpegDecode::input(uint8_t* buf, int len)
cgraham 0:d69efd0ee139 70 {
cgraham 0:d69efd0ee139 71 for(int i = 0; i < len; i++) {
cgraham 0:d69efd0ee139 72 input(buf[i]);
cgraham 0:d69efd0ee139 73 }
cgraham 0:d69efd0ee139 74 }
cgraham 0:d69efd0ee139 75
cgraham 0:d69efd0ee139 76 void BaseJpegDecode::restart()
cgraham 0:d69efd0ee139 77 {
cgraham 0:d69efd0ee139 78 m_block = 0;
cgraham 0:d69efd0ee139 79 m_scan = 0;
cgraham 0:d69efd0ee139 80 m_pre_DC_value[0] = 0;
cgraham 0:d69efd0ee139 81 m_pre_DC_value[1] = 0;
cgraham 0:d69efd0ee139 82 m_pre_DC_value[2] = 0;
cgraham 0:d69efd0ee139 83 m_bitpat.clear();
cgraham 0:d69efd0ee139 84 m_huff = NULL;
cgraham 0:d69efd0ee139 85 }
cgraham 0:d69efd0ee139 86
cgraham 0:d69efd0ee139 87 void BaseJpegDecode::inputDQT(uint8_t c, int pos, int len)
cgraham 0:d69efd0ee139 88 {
cgraham 0:d69efd0ee139 89 if (pos == 0 || pos == 65) {
cgraham 0:d69efd0ee139 90 m_param1 = c;
cgraham 0:d69efd0ee139 91 DBG_ASSERT(m_param1 == 0 || m_param1 == 1);
cgraham 0:d69efd0ee139 92 } else {
cgraham 0:d69efd0ee139 93 if (m_param1 == 0 || m_param1 == 1) {
cgraham 0:d69efd0ee139 94 if(qt[m_param1]) {
cgraham 0:d69efd0ee139 95 qt[m_param1][(pos%65)-1] = c;
cgraham 0:d69efd0ee139 96 }
cgraham 0:d69efd0ee139 97 }
cgraham 0:d69efd0ee139 98 }
cgraham 0:d69efd0ee139 99 }
cgraham 0:d69efd0ee139 100
cgraham 0:d69efd0ee139 101 void BaseJpegDecode::inputSOF(uint8_t c, int pos, int len)
cgraham 0:d69efd0ee139 102 {
cgraham 0:d69efd0ee139 103 switch(pos) {
cgraham 0:d69efd0ee139 104 case 1:
cgraham 0:d69efd0ee139 105 height = (height&0x00ff) | (c<<8);
cgraham 0:d69efd0ee139 106 break;
cgraham 0:d69efd0ee139 107 case 2:
cgraham 0:d69efd0ee139 108 height = (height&0xff00) | c;
cgraham 0:d69efd0ee139 109 break;
cgraham 0:d69efd0ee139 110 case 3:
cgraham 0:d69efd0ee139 111 width = (width&0x00ff) | (c<<8);
cgraham 0:d69efd0ee139 112 break;
cgraham 0:d69efd0ee139 113 case 4:
cgraham 0:d69efd0ee139 114 width = (width&0xff00) | c;
cgraham 0:d69efd0ee139 115 break;
cgraham 0:d69efd0ee139 116 case 7:
cgraham 0:d69efd0ee139 117 if (c == 0x22) {
cgraham 0:d69efd0ee139 118 yblock = 4;
cgraham 0:d69efd0ee139 119 } else if (c == 0x21) {
cgraham 0:d69efd0ee139 120 yblock = 2;
cgraham 0:d69efd0ee139 121 } else {
cgraham 0:d69efd0ee139 122 DBG_ASSERT(c == 0x22 || c == 0x21);
cgraham 0:d69efd0ee139 123 }
cgraham 0:d69efd0ee139 124 break;
cgraham 0:d69efd0ee139 125 }
cgraham 0:d69efd0ee139 126 }
cgraham 0:d69efd0ee139 127
cgraham 0:d69efd0ee139 128 void BaseJpegDecode::input(uint8_t c)
cgraham 0:d69efd0ee139 129 {
cgraham 0:d69efd0ee139 130 switch(m_seq) {
cgraham 0:d69efd0ee139 131 case SEQ_INIT:
cgraham 0:d69efd0ee139 132 if (c == 0xff) {
cgraham 0:d69efd0ee139 133 m_seq = SEQ_SOI;
cgraham 0:d69efd0ee139 134 }
cgraham 0:d69efd0ee139 135 break;
cgraham 0:d69efd0ee139 136 case SEQ_SOI:
cgraham 0:d69efd0ee139 137 if (c == MARK_SOI) {
cgraham 0:d69efd0ee139 138 outputMARK(c);
cgraham 0:d69efd0ee139 139 m_seq = SEQ_FRAME;
cgraham 0:d69efd0ee139 140 } else {
cgraham 0:d69efd0ee139 141 m_seq = SEQ_INIT;
cgraham 0:d69efd0ee139 142 }
cgraham 0:d69efd0ee139 143 break;
cgraham 0:d69efd0ee139 144 case SEQ_FRAME:
cgraham 0:d69efd0ee139 145 if (c == 0xff) {
cgraham 0:d69efd0ee139 146 m_seq = SEQ_MARK;
cgraham 0:d69efd0ee139 147 } else {
cgraham 0:d69efd0ee139 148 m_seq = SEQ_INIT;
cgraham 0:d69efd0ee139 149 }
cgraham 0:d69efd0ee139 150 break;
cgraham 0:d69efd0ee139 151 case SEQ_MARK:
cgraham 0:d69efd0ee139 152 outputMARK(c);
cgraham 0:d69efd0ee139 153 if (c == MARK_SOI) {
cgraham 0:d69efd0ee139 154 m_seq = SEQ_FRAME;
cgraham 0:d69efd0ee139 155 break;
cgraham 0:d69efd0ee139 156 } else if (c == MARK_EOI || c == 0x00) {
cgraham 0:d69efd0ee139 157 m_seq = SEQ_INIT;
cgraham 0:d69efd0ee139 158 break;
cgraham 0:d69efd0ee139 159 }
cgraham 0:d69efd0ee139 160 m_mark = c;
cgraham 0:d69efd0ee139 161 m_seq = SEQ_SEG_LEN;
cgraham 0:d69efd0ee139 162 break;
cgraham 0:d69efd0ee139 163 case SEQ_SEG_LEN:
cgraham 0:d69efd0ee139 164 m_seg_len = c;
cgraham 0:d69efd0ee139 165 m_seq = SEQ_SEG_LEN2;
cgraham 0:d69efd0ee139 166 break;
cgraham 0:d69efd0ee139 167 case SEQ_SEG_LEN2:
cgraham 0:d69efd0ee139 168 m_seg_len <<= 8;
cgraham 0:d69efd0ee139 169 m_seg_len |= c;
cgraham 0:d69efd0ee139 170 m_seg_len -= 2;
cgraham 0:d69efd0ee139 171 m_seg_pos = 0;
cgraham 0:d69efd0ee139 172 m_seq = SEQ_SEG_BODY;
cgraham 0:d69efd0ee139 173 break;
cgraham 0:d69efd0ee139 174 case SEQ_SEG_BODY:
cgraham 0:d69efd0ee139 175 if (m_mark == MARK_DQT) {
cgraham 0:d69efd0ee139 176 inputDQT(c, m_seg_pos, m_seg_len);
cgraham 0:d69efd0ee139 177 } else if (m_mark == MARK_SOF0) {
cgraham 0:d69efd0ee139 178 inputSOF(c, m_seg_pos, m_seg_len);
cgraham 0:d69efd0ee139 179 }
cgraham 0:d69efd0ee139 180 if (++m_seg_pos < m_seg_len) {
cgraham 0:d69efd0ee139 181 break;
cgraham 0:d69efd0ee139 182 }
cgraham 0:d69efd0ee139 183 if (m_mark == MARK_SOS) {
cgraham 0:d69efd0ee139 184 m_seq = SEQ_SOS;
cgraham 0:d69efd0ee139 185 m_mcu = 0;
cgraham 0:d69efd0ee139 186 restart();
cgraham 0:d69efd0ee139 187 break;
cgraham 0:d69efd0ee139 188 }
cgraham 0:d69efd0ee139 189 m_seq = SEQ_FRAME;
cgraham 0:d69efd0ee139 190 break;
cgraham 0:d69efd0ee139 191 case SEQ_SOS:
cgraham 0:d69efd0ee139 192 if (c == 0xff) {
cgraham 0:d69efd0ee139 193 m_seq = SEQ_SOS2;
cgraham 0:d69efd0ee139 194 break;
cgraham 0:d69efd0ee139 195 }
cgraham 0:d69efd0ee139 196 inputScan(c);
cgraham 0:d69efd0ee139 197 break;
cgraham 0:d69efd0ee139 198 case SEQ_SOS2:
cgraham 0:d69efd0ee139 199 if (c == 0x00) {
cgraham 0:d69efd0ee139 200 inputScan(0xff);
cgraham 0:d69efd0ee139 201 m_seq = SEQ_SOS;
cgraham 0:d69efd0ee139 202 break;
cgraham 0:d69efd0ee139 203 } else if (c >= MARK_RST0 && c <= MARK_RST7) {
cgraham 0:d69efd0ee139 204 restart();
cgraham 0:d69efd0ee139 205 m_seq = SEQ_SOS;
cgraham 0:d69efd0ee139 206 break;
cgraham 0:d69efd0ee139 207 }
cgraham 0:d69efd0ee139 208 outputMARK(c);
cgraham 0:d69efd0ee139 209 m_seq = SEQ_INIT;
cgraham 0:d69efd0ee139 210 break;
cgraham 0:d69efd0ee139 211 default:
cgraham 0:d69efd0ee139 212 break;
cgraham 0:d69efd0ee139 213 }
cgraham 0:d69efd0ee139 214 }
cgraham 0:d69efd0ee139 215
cgraham 0:d69efd0ee139 216 void BaseJpegDecode::inputScan(uint8_t c)
cgraham 0:d69efd0ee139 217 {
cgraham 0:d69efd0ee139 218 m_bitpat += c;
cgraham 0:d69efd0ee139 219 while(m_bitpat.size() > 0) {
cgraham 0:d69efd0ee139 220 int tc = (m_scan == 0) ? HT_DC : HT_AC;
cgraham 0:d69efd0ee139 221 int th = (m_block < yblock) ? 0 : 1;
cgraham 0:d69efd0ee139 222 DBG("%d %d %08x %d\n", tc, th, m_bitpat.peek(32), m_bitpat.size());
cgraham 0:d69efd0ee139 223 if (m_huff == NULL) {
cgraham 0:d69efd0ee139 224 m_huff = pHD->Lookup(tc, th, &m_bitpat);
cgraham 0:d69efd0ee139 225 if (m_huff == NULL) {
cgraham 0:d69efd0ee139 226 break;
cgraham 0:d69efd0ee139 227 }
cgraham 0:d69efd0ee139 228 m_bitpat.get(m_huff->code_size); // skip code
cgraham 0:d69efd0ee139 229 }
cgraham 0:d69efd0ee139 230 if (m_huff->value_size > m_bitpat.size()) {
cgraham 0:d69efd0ee139 231 break;
cgraham 0:d69efd0ee139 232 }
cgraham 0:d69efd0ee139 233 DBG("%d %d %d %02x\n", m_huff->run, m_huff->value_size, m_huff->code_size, m_huff->code);
cgraham 0:d69efd0ee139 234 int value = pHD->getValue(m_huff, &m_bitpat);
cgraham 0:d69efd0ee139 235 if (tc == HT_DC) {
cgraham 0:d69efd0ee139 236 int sc = 0; // Y
cgraham 0:d69efd0ee139 237 if (m_block == yblock) {
cgraham 0:d69efd0ee139 238 sc = 1; // Cb
cgraham 0:d69efd0ee139 239 } else if (m_block == (yblock+1)) {
cgraham 0:d69efd0ee139 240 sc = 2; // Cr
cgraham 0:d69efd0ee139 241 }
cgraham 0:d69efd0ee139 242 value += m_pre_DC_value[sc];
cgraham 0:d69efd0ee139 243 outputDC(m_mcu, m_block, value);
cgraham 0:d69efd0ee139 244 m_pre_DC_value[sc] = value;
cgraham 0:d69efd0ee139 245 m_scan++;
cgraham 0:d69efd0ee139 246 REPORT_CODE(report_scan_dc_count++);
cgraham 0:d69efd0ee139 247 } else { // AC
cgraham 0:d69efd0ee139 248 if (m_huff->value_size == 0 && m_huff->run == 0) { // EOB
cgraham 0:d69efd0ee139 249 DBG("AC EOB\n");
cgraham 0:d69efd0ee139 250 outputAC(m_mcu, m_block, 63, 0);
cgraham 0:d69efd0ee139 251 m_scan = 64;
cgraham 0:d69efd0ee139 252 } else {
cgraham 0:d69efd0ee139 253 for(int i = 0; i < m_huff->run; i++) {
cgraham 0:d69efd0ee139 254 //outputAC(m_mcu, m_block, m_scan, 0);
cgraham 0:d69efd0ee139 255 m_scan++;
cgraham 0:d69efd0ee139 256 }
cgraham 0:d69efd0ee139 257 outputAC(m_mcu, m_block, m_scan, value);
cgraham 0:d69efd0ee139 258 m_scan++;
cgraham 0:d69efd0ee139 259 }
cgraham 0:d69efd0ee139 260 if (m_scan >= 64) {
cgraham 0:d69efd0ee139 261 m_scan = 0;
cgraham 0:d69efd0ee139 262 if (++m_block >= (yblock+2)) {
cgraham 0:d69efd0ee139 263 m_block = 0;
cgraham 0:d69efd0ee139 264 m_mcu++;
cgraham 0:d69efd0ee139 265 }
cgraham 0:d69efd0ee139 266 }
cgraham 0:d69efd0ee139 267 REPORT_CODE(report_scan_ac_count++);
cgraham 0:d69efd0ee139 268 }
cgraham 0:d69efd0ee139 269 m_huff = NULL;
cgraham 0:d69efd0ee139 270 REPORT_CODE(report_scan_count++);
cgraham 0:d69efd0ee139 271 }
cgraham 0:d69efd0ee139 272 }