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: BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2
BaseJpefDecode.cpp@0:417b7ae90eff, 2012-10-22 (annotated)
- Committer:
- va009039
- Date:
- Mon Oct 22 13:55:09 2012 +0000
- Revision:
- 0:417b7ae90eff
convert to library
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |