
BaseJpegDeocde exampe program
Dependencies: BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos
Fork of BaseJpegDecode by
Diff: BaseJpefDecode.cpp
- Revision:
- 0:7121d9fb45f4
- Child:
- 1:58dfd5386a92
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BaseJpefDecode.cpp Sun Oct 07 12:03:40 2012 +0000 @@ -0,0 +1,173 @@ +#include "mbed.h" +#include "BaseJpegDecode.h" + +#if 0 +#define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0); +#define DBG_WAIT(A) wait_ms(A) +#else +#define DBG(...) +#define DBG_WAIT(A) +#endif + +#define MARK_SOF 0xc0 +#define MARK_DHT 0xc4 +#define MARK_RST0 0xd0 +#define MARK_RST7 0xd7 +#define MARK_SOI 0xd8 +#define MARK_EOI 0xd9 +#define MARK_SOS 0xda +#define MARK_DQT 0xdb +#define MARK_DRI 0xdd +#define MARK_APP 0xe0 + +#define SEQ_INIT 0 +#define SEQ_MARK 1 +#define SEQ_LEN 2 +#define SEQ_LEN2 3 +#define SEQ_SKIP 4 +#define SEQ_SOS 5 +#define SEQ_SOS2 6 + +#define HT_DC 0 +#define HT_AC 1 + +BaseJpegDecode::BaseJpegDecode() +{ + m_yblocks = JPEG_MCU_YBLOCKS; // 2 or 4 + clear(); + pHD = new HuffmanDecode; +} + +void BaseJpegDecode::clear() +{ + m_seq = SEQ_INIT; +} + +void BaseJpegDecode::input(uint8_t* buf, int len) +{ + for(int i = 0; i < len; i++) { + input(buf[i]); + } +} + +void BaseJpegDecode::restart() +{ + m_block = 0; + m_scan = 0; + m_old_DC_value[0] = 0; + m_old_DC_value[1] = 0; + m_bitpat.clear(); + m_huff = NULL; +} + +void BaseJpegDecode::input(uint8_t c) +{ + switch(m_seq) { + case SEQ_INIT: + if (c == 0xff) { + m_seq = SEQ_MARK; + } + break; + case SEQ_MARK: + outputMARK(c); + if (c == MARK_SOI || c == MARK_EOI) { + m_seq = SEQ_INIT; + break; + } + m_mark = c; + m_seq = SEQ_LEN; + break; + case SEQ_LEN: + m_skip = c; + m_seq = SEQ_LEN2; + break; + case SEQ_LEN2: + m_skip <<= 8; + m_skip |= c; + m_skip -= 2; + m_seq = SEQ_SKIP; + break; + case SEQ_SKIP: + if (--m_skip > 0) { + break; + } + if (m_mark == MARK_SOS) { + m_seq = SEQ_SOS; + m_mcu = 0; + restart(); + break; + } + m_seq = SEQ_INIT; + break; + case SEQ_SOS: + if (c == 0xff) { + m_seq = SEQ_SOS2; + break; + } + inputScan(c); + break; + case SEQ_SOS2: + if (c == 0x00) { + inputScan(0xff); + m_seq = SEQ_SOS; + break; + } else if (c >= MARK_RST0 && c <= MARK_RST7) { + restart(); + m_seq = SEQ_SOS; + break; + } + outputMARK(c); + m_seq = SEQ_INIT; + break; + default: + break; + } +} + +void BaseJpegDecode::inputScan(uint8_t c) +{ + m_bitpat += c; + while(m_bitpat.size() > 0) { + int tc = (m_scan == 0) ? HT_DC : HT_AC; + int th = (m_block < m_yblocks) ? 0 : 1; + DBG("%d %d %08x %d\n", tc, th, m_bitpat.peek(32), m_bitpat.size()); + if (m_huff == NULL) { + m_huff = pHD->Lookup(tc, th, &m_bitpat); + if (m_huff == NULL) { + break; + } + m_bitpat.get(m_huff->code_size); // skip code + } + if (m_huff->value_size > m_bitpat.size()) { + break; + } + DBG("%d %d %d %02x\n", m_huff->run, m_huff->value_size, m_huff->code_size, m_huff->code); + int value = pHD->getValue(m_huff, &m_bitpat); + if (tc == HT_DC) { + value += m_old_DC_value[th]; + outputDC(m_mcu, m_block, value); + m_old_DC_value[th] = value; + m_scan++; + } else { // AC + if (m_huff->value_size == 0 && m_huff->run == 0) { // EOB + DBG("AC EOB\n"); + m_scan = 64; + } else { + for(int i = 0; i < m_huff->run; i++) { + outputAC(m_mcu, m_block, m_scan, 0); + m_scan++; + } + outputAC(m_mcu, m_block, m_scan, value); + m_scan++; + } + if (m_scan >= 64) { + m_scan = 0; + if (++m_block >= (m_yblocks+2)) { + m_block = 0; + m_mcu++; + } + } + } + m_huff = NULL; + } +}