BaseJpegDeocde exampe program

Dependencies:   BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos

Fork of BaseJpegDecode by Norimasa Okamoto

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Sun Oct 07 12:03:40 2012 +0000
Child:
1:58dfd5386a92
Commit message:
first commit

Changed in this revision

BaseJpefDecode.cpp Show annotated file Show diff for this revision Revisions of this file
BaseJpegDecode.h Show annotated file Show diff for this revision Revisions of this file
BitPattern.cpp Show annotated file Show diff for this revision Revisions of this file
BitPattern.h Show annotated file Show diff for this revision Revisions of this file
HuffmanDecode.cpp Show annotated file Show diff for this revision Revisions of this file
HuffmanDecode.h Show annotated file Show diff for this revision Revisions of this file
example1_c270.cpp Show annotated file Show diff for this revision Revisions of this file
example2_vx700.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
uvchost.lib Show annotated file Show diff for this revision Revisions of this file
--- /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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseJpegDecode.h	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,33 @@
+#ifndef BASE_JPEG_DECODE_H
+#define BASE_JPEG_DECODE_H
+#include "HuffmanDecode.h"
+#include "BitPattern.h"
+
+#define JPEG_MCU_YBLOCKS 2
+
+class BaseJpegDecode {
+public:
+    BaseJpegDecode();
+    void clear();
+    void input(uint8_t c);
+    void input(uint8_t* buf, int len);
+    virtual void outputDC(int mcu, int block, int value) = 0;
+    virtual void outputAC(int mcu, int block, int scan, int value) = 0;
+    virtual void outputMARK(uint8_t c) = 0;
+private:
+    void inputScan(uint8_t c);
+    void restart();
+protected:
+    int m_seq;
+    int m_mcu;
+    int m_block;
+    int m_scan;
+    Huff* m_huff;
+    int m_old_DC_value[2];
+    BitPattern m_bitpat;
+    int m_skip;
+    uint8_t m_mark;
+    HuffmanDecode* pHD;
+    int m_yblocks;
+};
+#endif // BASE_JPEG_DECODE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BitPattern.cpp	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,104 @@
+#include "BitPattern.h"
+
+BitPattern::BitPattern()
+{
+    clear();
+}
+
+BitPattern::BitPattern(uint32_t value, int size)
+{
+    clear();
+    put(value, size);
+}
+
+BitPattern::BitPattern(const char* s)
+{
+    clear();
+    operator+=(s);
+}
+
+void BitPattern::clear()
+{
+    m_size = 0;
+    m_pat = 0;
+}
+
+void BitPattern::operator=(const char* s)
+{
+    clear();
+    operator+=(s);
+}
+
+void BitPattern::operator+=(uint8_t c)
+{
+    put(c);
+}
+
+void BitPattern::operator+=(const char* s)
+{
+    for(int i = 0; i < 32 && s[i]; i++) {
+        char c = s[i];
+        put(c-'0', 1);
+    }
+}
+
+int BitPattern::operator [](int index)
+{
+    uint32_t mask = 0x80000000;
+    for(int i = 0; i < index; i++) {
+        mask>>=1;
+    }
+    if (m_pat & mask) {
+        return 1;
+    }
+    return 0;
+}
+
+void BitPattern::put(uint32_t value, int size)
+{
+    m_pat <<= size;
+    m_pat |= value;
+    m_size += size;
+}
+
+uint32_t BitPattern::peek(int size)
+{
+    return m_pat >> (m_size - size);
+}
+
+uint32_t BitPattern::get(int size)
+{
+    uint32_t r = peek(size);
+    m_size -= size;
+    m_pat &= (1<<m_size)-1;
+    return r;
+}
+
+int BitPattern::size()
+{
+    return m_size;
+}
+
+bool BitPattern::match(BitPattern& b)
+{
+    if (b.m_size > m_size) {
+        return false;
+    }
+    return peek(b.size()) == b.peek(b.size());
+}
+
+bool BitPattern::match(const char* s)
+{
+    BitPattern a = s;
+    return match(a);
+}
+
+bool BitPattern::operator ==(BitPattern& b)
+{
+    if (b.m_size == m_size) {
+        if (b.m_pat == m_pat) {
+            return true;
+        }
+    }
+    return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BitPattern.h	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,26 @@
+#ifndef BIT_PATTERN_H
+#define BIT_PATTERN_H
+#include "mbed.h"
+
+class BitPattern {
+public:
+    BitPattern();
+    BitPattern(uint32_t value, int size);
+    BitPattern(const char* s);
+    void clear();
+    void operator +=(uint8_t c);
+    int operator [](int index);
+    void put(uint32_t value, int size = 8);
+    uint32_t peek(int size = 8);
+    uint32_t get(int size = 8);
+    int size();
+    bool match(BitPattern& b);
+    bool match(const char* s);
+    void operator =(const char* s);
+    void operator +=(const char* s);
+    bool operator ==(BitPattern& b);
+private:
+    uint32_t m_pat;
+    int m_size;
+};
+#endif // BIT_PATTERN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HuffmanDecode.cpp	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,417 @@
+#include "mbed.h"
+#include "HuffmanDecode.h"
+
+#if 1
+#define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
+#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(...)
+#define DBG_ASSERT(A) 
+#endif
+
+const Huff HT_DC_0[] = {
+/* 0 */ {0,0,2,0x0},
+/* 1 */ {0,1,3,0x2},
+/* 2 */ {0,2,3,0x3},
+/* 3 */ {0,3,3,0x4},
+/* 4 */ {0,4,3,0x5},
+/* 5 */ {0,5,3,0x6},
+/* 6 */ {0,6,4,0xe},
+/* 7 */ {0,7,5,0x1e},
+/* 8 */ {0,8,6,0x3e},
+/* 9 */ {0,9,7,0x7e},
+/* 10 */ {0,10,8,0xfe},
+/* 11 */ {0,11,9,0x1fe},
+};
+const Huff HT_AC_0[] = {
+/* 0 */ {0,1,2,0x0},
+/* 1 */ {0,2,2,0x1},
+/* 2 */ {0,3,3,0x4},
+/* 3 */ {0,0,4,0xa},
+/* 4 */ {0,4,4,0xb},
+/* 5 */ {1,1,4,0xc},
+/* 6 */ {0,5,5,0x1a},
+/* 7 */ {1,2,5,0x1b},
+/* 8 */ {2,1,5,0x1c},
+/* 9 */ {3,1,6,0x3a},
+/* 10 */ {4,1,6,0x3b},
+/* 11 */ {0,6,7,0x78},
+/* 12 */ {1,3,7,0x79},
+/* 13 */ {5,1,7,0x7a},
+/* 14 */ {6,1,7,0x7b},
+/* 15 */ {0,7,8,0xf8},
+/* 16 */ {2,2,8,0xf9},
+/* 17 */ {7,1,8,0xfa},
+/* 18 */ {1,4,9,0x1f6},
+/* 19 */ {3,2,9,0x1f7},
+/* 20 */ {8,1,9,0x1f8},
+/* 21 */ {9,1,9,0x1f9},
+/* 22 */ {10,1,9,0x1fa},
+/* 23 */ {0,8,10,0x3f6},
+/* 24 */ {2,3,10,0x3f7},
+/* 25 */ {4,2,10,0x3f8},
+/* 26 */ {11,1,10,0x3f9},
+/* 27 */ {12,1,10,0x3fa},
+/* 28 */ {1,5,11,0x7f6},
+/* 29 */ {5,2,11,0x7f7},
+/* 30 */ {13,1,11,0x7f8},
+/* 31 */ {15,0,11,0x7f9},
+/* 32 */ {2,4,12,0xff4},
+/* 33 */ {3,3,12,0xff5},
+/* 34 */ {6,2,12,0xff6},
+/* 35 */ {7,2,12,0xff7},
+/* 36 */ {8,2,15,0x7fc0},
+/* 37 */ {0,9,16,0xff82},
+/* 38 */ {0,10,16,0xff83},
+/* 39 */ {1,6,16,0xff84},
+/* 40 */ {1,7,16,0xff85},
+/* 41 */ {1,8,16,0xff86},
+/* 42 */ {1,9,16,0xff87},
+/* 43 */ {1,10,16,0xff88},
+/* 44 */ {2,5,16,0xff89},
+/* 45 */ {2,6,16,0xff8a},
+/* 46 */ {2,7,16,0xff8b},
+/* 47 */ {2,8,16,0xff8c},
+/* 48 */ {2,9,16,0xff8d},
+/* 49 */ {2,10,16,0xff8e},
+/* 50 */ {3,4,16,0xff8f},
+/* 51 */ {3,5,16,0xff90},
+/* 52 */ {3,6,16,0xff91},
+/* 53 */ {3,7,16,0xff92},
+/* 54 */ {3,8,16,0xff93},
+/* 55 */ {3,9,16,0xff94},
+/* 56 */ {3,10,16,0xff95},
+/* 57 */ {4,3,16,0xff96},
+/* 58 */ {4,4,16,0xff97},
+/* 59 */ {4,5,16,0xff98},
+/* 60 */ {4,6,16,0xff99},
+/* 61 */ {4,7,16,0xff9a},
+/* 62 */ {4,8,16,0xff9b},
+/* 63 */ {4,9,16,0xff9c},
+/* 64 */ {4,10,16,0xff9d},
+/* 65 */ {5,3,16,0xff9e},
+/* 66 */ {5,4,16,0xff9f},
+/* 67 */ {5,5,16,0xffa0},
+/* 68 */ {5,6,16,0xffa1},
+/* 69 */ {5,7,16,0xffa2},
+/* 70 */ {5,8,16,0xffa3},
+/* 71 */ {5,9,16,0xffa4},
+/* 72 */ {5,10,16,0xffa5},
+/* 73 */ {6,3,16,0xffa6},
+/* 74 */ {6,4,16,0xffa7},
+/* 75 */ {6,5,16,0xffa8},
+/* 76 */ {6,6,16,0xffa9},
+/* 77 */ {6,7,16,0xffaa},
+/* 78 */ {6,8,16,0xffab},
+/* 79 */ {6,9,16,0xffac},
+/* 80 */ {6,10,16,0xffad},
+/* 81 */ {7,3,16,0xffae},
+/* 82 */ {7,4,16,0xffaf},
+/* 83 */ {7,5,16,0xffb0},
+/* 84 */ {7,6,16,0xffb1},
+/* 85 */ {7,7,16,0xffb2},
+/* 86 */ {7,8,16,0xffb3},
+/* 87 */ {7,9,16,0xffb4},
+/* 88 */ {7,10,16,0xffb5},
+/* 89 */ {8,3,16,0xffb6},
+/* 90 */ {8,4,16,0xffb7},
+/* 91 */ {8,5,16,0xffb8},
+/* 92 */ {8,6,16,0xffb9},
+/* 93 */ {8,7,16,0xffba},
+/* 94 */ {8,8,16,0xffbb},
+/* 95 */ {8,9,16,0xffbc},
+/* 96 */ {8,10,16,0xffbd},
+/* 97 */ {9,2,16,0xffbe},
+/* 98 */ {9,3,16,0xffbf},
+/* 99 */ {9,4,16,0xffc0},
+/* 100 */ {9,5,16,0xffc1},
+/* 101 */ {9,6,16,0xffc2},
+/* 102 */ {9,7,16,0xffc3},
+/* 103 */ {9,8,16,0xffc4},
+/* 104 */ {9,9,16,0xffc5},
+/* 105 */ {9,10,16,0xffc6},
+/* 106 */ {10,2,16,0xffc7},
+/* 107 */ {10,3,16,0xffc8},
+/* 108 */ {10,4,16,0xffc9},
+/* 109 */ {10,5,16,0xffca},
+/* 110 */ {10,6,16,0xffcb},
+/* 111 */ {10,7,16,0xffcc},
+/* 112 */ {10,8,16,0xffcd},
+/* 113 */ {10,9,16,0xffce},
+/* 114 */ {10,10,16,0xffcf},
+/* 115 */ {11,2,16,0xffd0},
+/* 116 */ {11,3,16,0xffd1},
+/* 117 */ {11,4,16,0xffd2},
+/* 118 */ {11,5,16,0xffd3},
+/* 119 */ {11,6,16,0xffd4},
+/* 120 */ {11,7,16,0xffd5},
+/* 121 */ {11,8,16,0xffd6},
+/* 122 */ {11,9,16,0xffd7},
+/* 123 */ {11,10,16,0xffd8},
+/* 124 */ {12,2,16,0xffd9},
+/* 125 */ {12,3,16,0xffda},
+/* 126 */ {12,4,16,0xffdb},
+/* 127 */ {12,5,16,0xffdc},
+/* 128 */ {12,6,16,0xffdd},
+/* 129 */ {12,7,16,0xffde},
+/* 130 */ {12,8,16,0xffdf},
+/* 131 */ {12,9,16,0xffe0},
+/* 132 */ {12,10,16,0xffe1},
+/* 133 */ {13,2,16,0xffe2},
+/* 134 */ {13,3,16,0xffe3},
+/* 135 */ {13,4,16,0xffe4},
+/* 136 */ {13,5,16,0xffe5},
+/* 137 */ {13,6,16,0xffe6},
+/* 138 */ {13,7,16,0xffe7},
+/* 139 */ {13,8,16,0xffe8},
+/* 140 */ {13,9,16,0xffe9},
+/* 141 */ {13,10,16,0xffea},
+/* 142 */ {14,1,16,0xffeb},
+/* 143 */ {14,2,16,0xffec},
+/* 144 */ {14,3,16,0xffed},
+/* 145 */ {14,4,16,0xffee},
+/* 146 */ {14,5,16,0xffef},
+/* 147 */ {14,6,16,0xfff0},
+/* 148 */ {14,7,16,0xfff1},
+/* 149 */ {14,8,16,0xfff2},
+/* 150 */ {14,9,16,0xfff3},
+/* 151 */ {14,10,16,0xfff4},
+/* 152 */ {15,1,16,0xfff5},
+/* 153 */ {15,2,16,0xfff6},
+/* 154 */ {15,3,16,0xfff7},
+/* 155 */ {15,4,16,0xfff8},
+/* 156 */ {15,5,16,0xfff9},
+/* 157 */ {15,6,16,0xfffa},
+/* 158 */ {15,7,16,0xfffb},
+/* 159 */ {15,8,16,0xfffc},
+/* 160 */ {15,9,16,0xfffd},
+/* 161 */ {15,10,16,0xfffe},
+};
+const Huff HT_DC_1[] = {
+/* 0 */ {0,0,2,0x0},
+/* 1 */ {0,1,2,0x1},
+/* 2 */ {0,2,2,0x2},
+/* 3 */ {0,3,3,0x6},
+/* 4 */ {0,4,4,0xe},
+/* 5 */ {0,5,5,0x1e},
+/* 6 */ {0,6,6,0x3e},
+/* 7 */ {0,7,7,0x7e},
+/* 8 */ {0,8,8,0xfe},
+/* 9 */ {0,9,9,0x1fe},
+/* 10 */ {0,10,10,0x3fe},
+/* 11 */ {0,11,11,0x7fe},
+};
+const Huff HT_AC_1[] = {
+/* 0 */ {0,0,2,0x0},
+/* 1 */ {0,1,2,0x1},
+/* 2 */ {0,2,3,0x4},
+/* 3 */ {0,3,4,0xa},
+/* 4 */ {1,1,4,0xb},
+/* 5 */ {0,4,5,0x18},
+/* 6 */ {0,5,5,0x19},
+/* 7 */ {2,1,5,0x1a},
+/* 8 */ {3,1,5,0x1b},
+/* 9 */ {0,6,6,0x38},
+/* 10 */ {1,2,6,0x39},
+/* 11 */ {4,1,6,0x3a},
+/* 12 */ {5,1,6,0x3b},
+/* 13 */ {0,7,7,0x78},
+/* 14 */ {6,1,7,0x79},
+/* 15 */ {7,1,7,0x7a},
+/* 16 */ {1,3,8,0xf6},
+/* 17 */ {2,2,8,0xf7},
+/* 18 */ {3,2,8,0xf8},
+/* 19 */ {8,1,8,0xf9},
+/* 20 */ {0,8,9,0x1f4},
+/* 21 */ {1,4,9,0x1f5},
+/* 22 */ {4,2,9,0x1f6},
+/* 23 */ {9,1,9,0x1f7},
+/* 24 */ {10,1,9,0x1f8},
+/* 25 */ {11,1,9,0x1f9},
+/* 26 */ {12,1,9,0x1fa},
+/* 27 */ {0,9,10,0x3f6},
+/* 28 */ {2,3,10,0x3f7},
+/* 29 */ {3,3,10,0x3f8},
+/* 30 */ {5,2,10,0x3f9},
+/* 31 */ {15,0,10,0x3fa},
+/* 32 */ {1,5,11,0x7f6},
+/* 33 */ {6,2,11,0x7f7},
+/* 34 */ {7,2,11,0x7f8},
+/* 35 */ {13,1,11,0x7f9},
+/* 36 */ {0,10,12,0xff4},
+/* 37 */ {1,6,12,0xff5},
+/* 38 */ {2,4,12,0xff6},
+/* 39 */ {3,4,12,0xff7},
+/* 40 */ {14,1,14,0x3fe0},
+/* 41 */ {2,5,15,0x7fc2},
+/* 42 */ {15,1,15,0x7fc3},
+/* 43 */ {1,7,16,0xff88},
+/* 44 */ {1,8,16,0xff89},
+/* 45 */ {1,9,16,0xff8a},
+/* 46 */ {1,10,16,0xff8b},
+/* 47 */ {2,6,16,0xff8c},
+/* 48 */ {2,7,16,0xff8d},
+/* 49 */ {2,8,16,0xff8e},
+/* 50 */ {2,9,16,0xff8f},
+/* 51 */ {2,10,16,0xff90},
+/* 52 */ {3,5,16,0xff91},
+/* 53 */ {3,6,16,0xff92},
+/* 54 */ {3,7,16,0xff93},
+/* 55 */ {3,8,16,0xff94},
+/* 56 */ {3,9,16,0xff95},
+/* 57 */ {3,10,16,0xff96},
+/* 58 */ {4,3,16,0xff97},
+/* 59 */ {4,4,16,0xff98},
+/* 60 */ {4,5,16,0xff99},
+/* 61 */ {4,6,16,0xff9a},
+/* 62 */ {4,7,16,0xff9b},
+/* 63 */ {4,8,16,0xff9c},
+/* 64 */ {4,9,16,0xff9d},
+/* 65 */ {4,10,16,0xff9e},
+/* 66 */ {5,3,16,0xff9f},
+/* 67 */ {5,4,16,0xffa0},
+/* 68 */ {5,5,16,0xffa1},
+/* 69 */ {5,6,16,0xffa2},
+/* 70 */ {5,7,16,0xffa3},
+/* 71 */ {5,8,16,0xffa4},
+/* 72 */ {5,9,16,0xffa5},
+/* 73 */ {5,10,16,0xffa6},
+/* 74 */ {6,3,16,0xffa7},
+/* 75 */ {6,4,16,0xffa8},
+/* 76 */ {6,5,16,0xffa9},
+/* 77 */ {6,6,16,0xffaa},
+/* 78 */ {6,7,16,0xffab},
+/* 79 */ {6,8,16,0xffac},
+/* 80 */ {6,9,16,0xffad},
+/* 81 */ {6,10,16,0xffae},
+/* 82 */ {7,3,16,0xffaf},
+/* 83 */ {7,4,16,0xffb0},
+/* 84 */ {7,5,16,0xffb1},
+/* 85 */ {7,6,16,0xffb2},
+/* 86 */ {7,7,16,0xffb3},
+/* 87 */ {7,8,16,0xffb4},
+/* 88 */ {7,9,16,0xffb5},
+/* 89 */ {7,10,16,0xffb6},
+/* 90 */ {8,2,16,0xffb7},
+/* 91 */ {8,3,16,0xffb8},
+/* 92 */ {8,4,16,0xffb9},
+/* 93 */ {8,5,16,0xffba},
+/* 94 */ {8,6,16,0xffbb},
+/* 95 */ {8,7,16,0xffbc},
+/* 96 */ {8,8,16,0xffbd},
+/* 97 */ {8,9,16,0xffbe},
+/* 98 */ {8,10,16,0xffbf},
+/* 99 */ {9,2,16,0xffc0},
+/* 100 */ {9,3,16,0xffc1},
+/* 101 */ {9,4,16,0xffc2},
+/* 102 */ {9,5,16,0xffc3},
+/* 103 */ {9,6,16,0xffc4},
+/* 104 */ {9,7,16,0xffc5},
+/* 105 */ {9,8,16,0xffc6},
+/* 106 */ {9,9,16,0xffc7},
+/* 107 */ {9,10,16,0xffc8},
+/* 108 */ {10,2,16,0xffc9},
+/* 109 */ {10,3,16,0xffca},
+/* 110 */ {10,4,16,0xffcb},
+/* 111 */ {10,5,16,0xffcc},
+/* 112 */ {10,6,16,0xffcd},
+/* 113 */ {10,7,16,0xffce},
+/* 114 */ {10,8,16,0xffcf},
+/* 115 */ {10,9,16,0xffd0},
+/* 116 */ {10,10,16,0xffd1},
+/* 117 */ {11,2,16,0xffd2},
+/* 118 */ {11,3,16,0xffd3},
+/* 119 */ {11,4,16,0xffd4},
+/* 120 */ {11,5,16,0xffd5},
+/* 121 */ {11,6,16,0xffd6},
+/* 122 */ {11,7,16,0xffd7},
+/* 123 */ {11,8,16,0xffd8},
+/* 124 */ {11,9,16,0xffd9},
+/* 125 */ {11,10,16,0xffda},
+/* 126 */ {12,2,16,0xffdb},
+/* 127 */ {12,3,16,0xffdc},
+/* 128 */ {12,4,16,0xffdd},
+/* 129 */ {12,5,16,0xffde},
+/* 130 */ {12,6,16,0xffdf},
+/* 131 */ {12,7,16,0xffe0},
+/* 132 */ {12,8,16,0xffe1},
+/* 133 */ {12,9,16,0xffe2},
+/* 134 */ {12,10,16,0xffe3},
+/* 135 */ {13,2,16,0xffe4},
+/* 136 */ {13,3,16,0xffe5},
+/* 137 */ {13,4,16,0xffe6},
+/* 138 */ {13,5,16,0xffe7},
+/* 139 */ {13,6,16,0xffe8},
+/* 140 */ {13,7,16,0xffe9},
+/* 141 */ {13,8,16,0xffea},
+/* 142 */ {13,9,16,0xffeb},
+/* 143 */ {13,10,16,0xffec},
+/* 144 */ {14,2,16,0xffed},
+/* 145 */ {14,3,16,0xffee},
+/* 146 */ {14,4,16,0xffef},
+/* 147 */ {14,5,16,0xfff0},
+/* 148 */ {14,6,16,0xfff1},
+/* 149 */ {14,7,16,0xfff2},
+/* 150 */ {14,8,16,0xfff3},
+/* 151 */ {14,9,16,0xfff4},
+/* 152 */ {14,10,16,0xfff5},
+/* 153 */ {15,2,16,0xfff6},
+/* 154 */ {15,3,16,0xfff7},
+/* 155 */ {15,4,16,0xfff8},
+/* 156 */ {15,5,16,0xfff9},
+/* 157 */ {15,6,16,0xfffa},
+/* 158 */ {15,7,16,0xfffb},
+/* 159 */ {15,8,16,0xfffc},
+/* 160 */ {15,9,16,0xfffd},
+/* 161 */ {15,10,16,0xfffe},
+};
+
+Huff* HuffmanDecode::Lookup(int tc, int th, BitPattern* bitpat)
+{
+    Huff* huff;
+    int size;
+
+    if (tc == 0) {
+        if (th == 0) {
+            huff = (Huff*)HT_DC_0;
+            size = sizeof(HT_DC_0) / sizeof(Huff);
+        } else {
+            huff = (Huff*)HT_DC_1;
+            size = sizeof(HT_DC_1) / sizeof(Huff);
+        }
+    } else {
+        if (th == 0) {
+            huff = (Huff*)HT_AC_0;
+            size = sizeof(HT_AC_0) / sizeof(Huff);
+        } else {
+            huff = (Huff*)HT_AC_1;
+            size = sizeof(HT_AC_1) / sizeof(Huff);
+        }
+    }
+
+    for(int i = 0; i < size; i++) {
+        //DBG("%d %p\n", i, huff);
+        if (huff->code_size > bitpat->size()) {
+            return NULL;
+        }
+        BitPattern tmp(huff->code, huff->code_size);
+        if (bitpat->match(tmp)) {
+            return huff;
+        }
+        huff++;
+    }
+    return NULL;
+}
+
+int HuffmanDecode::getValue(Huff* huff, BitPattern* bitpat)
+{
+    int value = bitpat->get(huff->value_size);
+    if (huff->value_size == 0) {
+        return 0;
+    }
+    if (value & (1<<(huff->value_size-1))) {
+        return value;
+    }
+    value -= (1<<huff->value_size)-1;
+    return value;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HuffmanDecode.h	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,18 @@
+#ifndef HUFFMAN_DECODE_H
+#define HUFFMAN_DECODE_H
+#include "BitPattern.h"
+
+typedef struct sthuff {
+    int8_t run;
+    int8_t value_size;
+    int8_t code_size;
+    uint16_t code;
+} Huff;
+
+class HuffmanDecode {
+public:
+    Huff* Lookup(int tc, int th, BitPattern* bitpat);
+    int getValue(Huff* huff, BitPattern* bitpat);
+};
+
+#endif // HUFFMAN_DECODE_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example1_c270.cpp	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,84 @@
+#if 1
+#include "mbed.h"
+#include "BaseJpegDecode.h"
+#include "uvc.h"
+
+// Logitech C270
+#define WIDTH  320
+#define HEIGHT 176
+
+#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+Serial pc(USBTX, USBRX);
+
+class CalcCenter : public BaseJpegDecode {
+public:
+    int y_center, x_center;
+    int m_x_sum, m_y_sum, m_sum;
+    int8_t m_buf[WIDTH/16*HEIGHT/8];
+    virtual void outputDC(int mcu, int block, int value) {
+        if (mcu >= (WIDTH/16*HEIGHT/8)) {
+            return;
+        }
+        if (block == 3) { // 0-1:Y 2:Cb 3:Cr
+            m_buf[mcu] = value; // debug
+            if (value >= 2) { // red
+                m_x_sum += value*(mcu%(WIDTH/16));
+                m_y_sum += value*(mcu/(WIDTH/16));
+                m_sum += value;
+            }
+        }
+    }
+    virtual void outputAC(int mcu, int block, int scan, int value){};
+    virtual void outputMARK(uint8_t c){
+        if (c == 0xd9) { // EOI
+            if(m_sum == 0) {
+                x_center = y_center = -1; // not found
+            } else {
+                x_center = m_x_sum / m_sum;
+                y_center = m_y_sum / m_sum;
+            }
+            m_x_sum = m_y_sum = m_sum = 0; // reset
+            led2 = !led2;
+        }
+    };
+};
+
+CalcCenter* calc = NULL;
+
+void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len)
+{
+    if (calc) {
+        calc->input(buf+12, len-12);
+    }
+    led1 = buf[1]&1; // FID
+}
+
+int main() {
+    pc.baud(921600);
+    printf("%s\n", __FILE__);
+
+    calc = new CalcCenter;
+    ASSERT(calc);
+    uvc* cam = new uvc;
+    ASSERT(cam);
+    cam->SetImageSize(WIDTH, HEIGHT);
+    cam->SetFrameInterval(2000000); // 5.0fps
+    cam->setOnResult(callback_motion_jpeg);
+    ASSERT(cam->setup() >= 0);
+    while(1) {
+        printf("\n"); // start debug dump
+        for(int y = 0; y < HEIGHT/8; y++) {
+            for(int x = 0; x < WIDTH/16; x++) {
+                printf("%+3d,", calc->m_buf[y*WIDTH/16+x]);
+                cam->poll();
+            }
+            printf("\n");
+        }
+        printf("red:(%d,%d)\n", calc->x_center, calc->y_center);
+        cam->wait_ms(500);
+        led3 = !led3;
+    }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example2_vx700.cpp	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,65 @@
+#if 0
+#include "mbed.h"
+#include "BaseJpegDecode.h"
+#include "uvc.h"
+
+#define WIDTH  160
+#define HEIGHT 120
+
+//#define WIDTH  320
+//#define HEIGHT 240
+
+#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+Serial pc(USBTX, USBRX);
+
+class JpegDecode : public BaseJpegDecode {
+public:
+    int8_t m_buf[WIDTH/8*HEIGHT/8];
+    virtual void outputDC(int mcu, int block, int value) {
+        if (mcu < (WIDTH/8*HEIGHT/8/2)) {
+            if (block <= 1) { // 0-1:Y 2:Cb 3:Cr
+                m_buf[mcu*2+block] = value;
+            }
+        }
+    }
+    virtual void outputAC(int mcu, int block, int scan, int value){};
+    virtual void outputMARK(uint8_t c){};
+};
+
+JpegDecode* decode = NULL;
+
+void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len)
+{
+    if (decode) {
+        decode->input(buf+12, len-12);
+    }
+    led1 = buf[1]&1; // FID
+}
+
+int main() {
+    pc.baud(921600);
+    printf("%s\n", __FILE__);
+
+    decode = new JpegDecode;
+    ASSERT(decode);
+    uvc* cam = new uvc;
+    ASSERT(cam);
+    cam->SetImageSize(WIDTH, HEIGHT);
+    cam->setOnResult(callback_motion_jpeg);
+    ASSERT(cam->setup() >= 0);
+    while(1) {
+        printf("\n"); // start
+        for(int y = 0; y < HEIGHT/8; y++) {
+            for(int x = 0; x < WIDTH/8; x++) {
+                printf("%+4d,", decode->m_buf[y*WIDTH/8+x]);
+                cam->poll();
+            }
+            printf("\n");
+        }
+        cam->wait_ms(500);
+        led2 = !led2;
+    }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/cd19af002ccc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uvchost.lib	Sun Oct 07 12:03:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/va009039/code/uvchost/#3eb41d749f9a