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
Diff: BaseJpefDecode.cpp
- Revision:
- 0:417b7ae90eff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseJpefDecode.cpp Mon Oct 22 13:55:09 2012 +0000
@@ -0,0 +1,179 @@
+#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
+
+#if 1
+#define DBG_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
+#else
+#define DBG_ASSERT(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;
+ }
+}