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