Any changes are to allow conversion to BMP

Dependents:   Color_Targeting_Catapult

Fork of BaseJpegDecode by Norimasa Okamoto

Committer:
va009039
Date:
Mon Nov 05 22:47:05 2012 +0000
Revision:
3:a7547692071d
Parent:
2:5b1dd4e34857
Child:
4:e243fa781e5c
change to AAN inverse DCT

Who changed what in which revision?

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