Norimasa Okamoto / BaseJpegDecode

Dependents:   BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2

Committer:
va009039
Date:
Mon Oct 22 13:55:09 2012 +0000
Revision:
0:417b7ae90eff
convert to library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:417b7ae90eff 1 #include "mbed.h"
va009039 0:417b7ae90eff 2 #include "BaseJpegDecode.h"
va009039 0:417b7ae90eff 3
va009039 0:417b7ae90eff 4 #if 0
va009039 0:417b7ae90eff 5 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
va009039 0:417b7ae90eff 6 #define DBG_WAIT(A) wait_ms(A)
va009039 0:417b7ae90eff 7 #else
va009039 0:417b7ae90eff 8 #define DBG(...)
va009039 0:417b7ae90eff 9 #define DBG_WAIT(A)
va009039 0:417b7ae90eff 10 #endif
va009039 0:417b7ae90eff 11
va009039 0:417b7ae90eff 12 #if 1
va009039 0:417b7ae90eff 13 #define DBG_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
va009039 0:417b7ae90eff 14 #else
va009039 0:417b7ae90eff 15 #define DBG_ASSERT(A)
va009039 0:417b7ae90eff 16 #endif
va009039 0:417b7ae90eff 17
va009039 0:417b7ae90eff 18 #define MARK_SOF 0xc0
va009039 0:417b7ae90eff 19 #define MARK_DHT 0xc4
va009039 0:417b7ae90eff 20 #define MARK_RST0 0xd0
va009039 0:417b7ae90eff 21 #define MARK_RST7 0xd7
va009039 0:417b7ae90eff 22 #define MARK_SOI 0xd8
va009039 0:417b7ae90eff 23 #define MARK_EOI 0xd9
va009039 0:417b7ae90eff 24 #define MARK_SOS 0xda
va009039 0:417b7ae90eff 25 #define MARK_DQT 0xdb
va009039 0:417b7ae90eff 26 #define MARK_DRI 0xdd
va009039 0:417b7ae90eff 27 #define MARK_APP 0xe0
va009039 0:417b7ae90eff 28
va009039 0:417b7ae90eff 29 #define SEQ_INIT 0
va009039 0:417b7ae90eff 30 #define SEQ_MARK 1
va009039 0:417b7ae90eff 31 #define SEQ_LEN 2
va009039 0:417b7ae90eff 32 #define SEQ_LEN2 3
va009039 0:417b7ae90eff 33 #define SEQ_SKIP 4
va009039 0:417b7ae90eff 34 #define SEQ_SOS 5
va009039 0:417b7ae90eff 35 #define SEQ_SOS2 6
va009039 0:417b7ae90eff 36
va009039 0:417b7ae90eff 37 #define HT_DC 0
va009039 0:417b7ae90eff 38 #define HT_AC 1
va009039 0:417b7ae90eff 39
va009039 0:417b7ae90eff 40 BaseJpegDecode::BaseJpegDecode()
va009039 0:417b7ae90eff 41 {
va009039 0:417b7ae90eff 42 m_yblocks = JPEG_MCU_YBLOCKS; // 2 or 4
va009039 0:417b7ae90eff 43 clear();
va009039 0:417b7ae90eff 44 pHD = new HuffmanDecode;
va009039 0:417b7ae90eff 45 }
va009039 0:417b7ae90eff 46
va009039 0:417b7ae90eff 47 void BaseJpegDecode::clear()
va009039 0:417b7ae90eff 48 {
va009039 0:417b7ae90eff 49 m_seq = SEQ_INIT;
va009039 0:417b7ae90eff 50 }
va009039 0:417b7ae90eff 51
va009039 0:417b7ae90eff 52 void BaseJpegDecode::input(uint8_t* buf, int len)
va009039 0:417b7ae90eff 53 {
va009039 0:417b7ae90eff 54 for(int i = 0; i < len; i++) {
va009039 0:417b7ae90eff 55 input(buf[i]);
va009039 0:417b7ae90eff 56 }
va009039 0:417b7ae90eff 57 }
va009039 0:417b7ae90eff 58
va009039 0:417b7ae90eff 59 void BaseJpegDecode::restart()
va009039 0:417b7ae90eff 60 {
va009039 0:417b7ae90eff 61 m_block = 0;
va009039 0:417b7ae90eff 62 m_scan = 0;
va009039 0:417b7ae90eff 63 m_old_DC_value[0] = 0;
va009039 0:417b7ae90eff 64 m_old_DC_value[1] = 0;
va009039 0:417b7ae90eff 65 m_bitpat.clear();
va009039 0:417b7ae90eff 66 m_huff = NULL;
va009039 0:417b7ae90eff 67 }
va009039 0:417b7ae90eff 68
va009039 0:417b7ae90eff 69 void BaseJpegDecode::input(uint8_t c)
va009039 0:417b7ae90eff 70 {
va009039 0:417b7ae90eff 71 switch(m_seq) {
va009039 0:417b7ae90eff 72 case SEQ_INIT:
va009039 0:417b7ae90eff 73 if (c == 0xff) {
va009039 0:417b7ae90eff 74 m_seq = SEQ_MARK;
va009039 0:417b7ae90eff 75 }
va009039 0:417b7ae90eff 76 break;
va009039 0:417b7ae90eff 77 case SEQ_MARK:
va009039 0:417b7ae90eff 78 outputMARK(c);
va009039 0:417b7ae90eff 79 if (c == MARK_SOI || c == MARK_EOI) {
va009039 0:417b7ae90eff 80 m_seq = SEQ_INIT;
va009039 0:417b7ae90eff 81 break;
va009039 0:417b7ae90eff 82 }
va009039 0:417b7ae90eff 83 m_mark = c;
va009039 0:417b7ae90eff 84 m_seq = SEQ_LEN;
va009039 0:417b7ae90eff 85 break;
va009039 0:417b7ae90eff 86 case SEQ_LEN:
va009039 0:417b7ae90eff 87 m_skip = c;
va009039 0:417b7ae90eff 88 m_seq = SEQ_LEN2;
va009039 0:417b7ae90eff 89 break;
va009039 0:417b7ae90eff 90 case SEQ_LEN2:
va009039 0:417b7ae90eff 91 m_skip <<= 8;
va009039 0:417b7ae90eff 92 m_skip |= c;
va009039 0:417b7ae90eff 93 m_skip -= 2;
va009039 0:417b7ae90eff 94 m_seq = SEQ_SKIP;
va009039 0:417b7ae90eff 95 break;
va009039 0:417b7ae90eff 96 case SEQ_SKIP:
va009039 0:417b7ae90eff 97 if (--m_skip > 0) {
va009039 0:417b7ae90eff 98 break;
va009039 0:417b7ae90eff 99 }
va009039 0:417b7ae90eff 100 if (m_mark == MARK_SOS) {
va009039 0:417b7ae90eff 101 m_seq = SEQ_SOS;
va009039 0:417b7ae90eff 102 m_mcu = 0;
va009039 0:417b7ae90eff 103 restart();
va009039 0:417b7ae90eff 104 break;
va009039 0:417b7ae90eff 105 }
va009039 0:417b7ae90eff 106 m_seq = SEQ_INIT;
va009039 0:417b7ae90eff 107 break;
va009039 0:417b7ae90eff 108 case SEQ_SOS:
va009039 0:417b7ae90eff 109 if (c == 0xff) {
va009039 0:417b7ae90eff 110 m_seq = SEQ_SOS2;
va009039 0:417b7ae90eff 111 break;
va009039 0:417b7ae90eff 112 }
va009039 0:417b7ae90eff 113 inputScan(c);
va009039 0:417b7ae90eff 114 break;
va009039 0:417b7ae90eff 115 case SEQ_SOS2:
va009039 0:417b7ae90eff 116 if (c == 0x00) {
va009039 0:417b7ae90eff 117 inputScan(0xff);
va009039 0:417b7ae90eff 118 m_seq = SEQ_SOS;
va009039 0:417b7ae90eff 119 break;
va009039 0:417b7ae90eff 120 } else if (c >= MARK_RST0 && c <= MARK_RST7) {
va009039 0:417b7ae90eff 121 restart();
va009039 0:417b7ae90eff 122 m_seq = SEQ_SOS;
va009039 0:417b7ae90eff 123 break;
va009039 0:417b7ae90eff 124 }
va009039 0:417b7ae90eff 125 outputMARK(c);
va009039 0:417b7ae90eff 126 m_seq = SEQ_INIT;
va009039 0:417b7ae90eff 127 break;
va009039 0:417b7ae90eff 128 default:
va009039 0:417b7ae90eff 129 break;
va009039 0:417b7ae90eff 130 }
va009039 0:417b7ae90eff 131 }
va009039 0:417b7ae90eff 132
va009039 0:417b7ae90eff 133 void BaseJpegDecode::inputScan(uint8_t c)
va009039 0:417b7ae90eff 134 {
va009039 0:417b7ae90eff 135 m_bitpat += c;
va009039 0:417b7ae90eff 136 while(m_bitpat.size() > 0) {
va009039 0:417b7ae90eff 137 int tc = (m_scan == 0) ? HT_DC : HT_AC;
va009039 0:417b7ae90eff 138 int th = (m_block < m_yblocks) ? 0 : 1;
va009039 0:417b7ae90eff 139 DBG("%d %d %08x %d\n", tc, th, m_bitpat.peek(32), m_bitpat.size());
va009039 0:417b7ae90eff 140 if (m_huff == NULL) {
va009039 0:417b7ae90eff 141 m_huff = pHD->Lookup(tc, th, &m_bitpat);
va009039 0:417b7ae90eff 142 if (m_huff == NULL) {
va009039 0:417b7ae90eff 143 break;
va009039 0:417b7ae90eff 144 }
va009039 0:417b7ae90eff 145 m_bitpat.get(m_huff->code_size); // skip code
va009039 0:417b7ae90eff 146 }
va009039 0:417b7ae90eff 147 if (m_huff->value_size > m_bitpat.size()) {
va009039 0:417b7ae90eff 148 break;
va009039 0:417b7ae90eff 149 }
va009039 0:417b7ae90eff 150 DBG("%d %d %d %02x\n", m_huff->run, m_huff->value_size, m_huff->code_size, m_huff->code);
va009039 0:417b7ae90eff 151 int value = pHD->getValue(m_huff, &m_bitpat);
va009039 0:417b7ae90eff 152 if (tc == HT_DC) {
va009039 0:417b7ae90eff 153 value += m_old_DC_value[th];
va009039 0:417b7ae90eff 154 outputDC(m_mcu, m_block, value);
va009039 0:417b7ae90eff 155 m_old_DC_value[th] = value;
va009039 0:417b7ae90eff 156 m_scan++;
va009039 0:417b7ae90eff 157 } else { // AC
va009039 0:417b7ae90eff 158 if (m_huff->value_size == 0 && m_huff->run == 0) { // EOB
va009039 0:417b7ae90eff 159 DBG("AC EOB\n");
va009039 0:417b7ae90eff 160 m_scan = 64;
va009039 0:417b7ae90eff 161 } else {
va009039 0:417b7ae90eff 162 for(int i = 0; i < m_huff->run; i++) {
va009039 0:417b7ae90eff 163 outputAC(m_mcu, m_block, m_scan, 0);
va009039 0:417b7ae90eff 164 m_scan++;
va009039 0:417b7ae90eff 165 }
va009039 0:417b7ae90eff 166 outputAC(m_mcu, m_block, m_scan, value);
va009039 0:417b7ae90eff 167 m_scan++;
va009039 0:417b7ae90eff 168 }
va009039 0:417b7ae90eff 169 if (m_scan >= 64) {
va009039 0:417b7ae90eff 170 m_scan = 0;
va009039 0:417b7ae90eff 171 if (++m_block >= (m_yblocks+2)) {
va009039 0:417b7ae90eff 172 m_block = 0;
va009039 0:417b7ae90eff 173 m_mcu++;
va009039 0:417b7ae90eff 174 }
va009039 0:417b7ae90eff 175 }
va009039 0:417b7ae90eff 176 }
va009039 0:417b7ae90eff 177 m_huff = NULL;
va009039 0:417b7ae90eff 178 }
va009039 0:417b7ae90eff 179 }