huffmancode to decode in real-time for motion-jpeg
Dependents: BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2
example code:
Import programBaseJpegDecode_example
BaseJpegDeocde exampe program
Import programSimpleJpegDecode_example
convert JPEG stream data to bitmap, BaseJpegDecode example program
Revision 2:5b1dd4e34857, committed 2012-10-30
- Comitter:
- va009039
- Date:
- Tue Oct 30 13:22:08 2012 +0000
- Parent:
- 1:bfbc18000cca
- Child:
- 3:a7547692071d
- Commit message:
- add inverseDCT
Changed in this revision
--- a/BaseJpegDecode.cpp Thu Oct 25 11:00:05 2012 +0000 +++ b/BaseJpegDecode.cpp Tue Oct 30 13:22:08 2012 +0000 @@ -71,8 +71,9 @@ { m_block = 0; m_scan = 0; - m_old_DC_value[0] = 0; - m_old_DC_value[1] = 0; + m_pre_DC_value[0] = 0; + m_pre_DC_value[1] = 0; + m_pre_DC_value[2] = 0; m_bitpat.clear(); m_huff = NULL; } @@ -95,10 +96,10 @@ m_param1 = c<<8; break; case 2: - width = m_param1 | c; + height = m_param1 | c; break; case 4: - height = m_param1 | c; + width = m_param1 | c; break; case 7: if (c == 0x22) { @@ -202,18 +203,25 @@ 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]; + int sc = 0; // Y + if (m_block == m_yblocks) { + sc = 1; // Cb + } else if (m_block == (m_yblocks+1)) { + sc = 2; // Cr + } + value += m_pre_DC_value[sc]; outputDC(m_mcu, m_block, value); - m_old_DC_value[th] = value; + m_pre_DC_value[sc] = value; m_scan++; REPORT_CODE(report_scan_dc_count++); } else { // AC if (m_huff->value_size == 0 && m_huff->run == 0) { // EOB DBG("AC EOB\n"); + outputAC(m_mcu, m_block, 63, 0); m_scan = 64; } else { for(int i = 0; i < m_huff->run; i++) { - outputAC(m_mcu, m_block, m_scan, 0); + //outputAC(m_mcu, m_block, m_scan, 0); m_scan++; } outputAC(m_mcu, m_block, m_scan, value);
--- a/BaseJpegDecode.h Thu Oct 25 11:00:05 2012 +0000 +++ b/BaseJpegDecode.h Tue Oct 30 13:22:08 2012 +0000 @@ -33,7 +33,7 @@ int m_block; int m_scan; Huff* m_huff; - int m_old_DC_value[2]; + int m_pre_DC_value[3]; BitPattern m_bitpat; uint8_t m_mark; HuffmanDecode* pHD;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inverseDCT.cpp Tue Oct 30 13:22:08 2012 +0000 @@ -0,0 +1,130 @@ +#include "mbed.h" +#include <math.h> +#include "inverseDCT.h" + +#define PI 3.14159265 + +const int zigzag[64] = + {0, + 1, 8, + 16, 9, 2, + 3,10,17,24, + 32,25,18,11, 4, + 5,12,19,26,33,40, + 48,41,34,27,20,13,6, + 7,14,21,28,35,42,49,56, + 57,50,43,36,29,22,15, + 23,30,37,44,51,58, + 59,52,45,38,31, + 39,46,53,60, + 61,54,47, + 55,62, + 63}; + +int adjust(int value) { + value += 128; + if (value < 0) { + return 0; + } else if (value > 255) { + return 255; + } + return value; +} + +#if DCT_USE_INT +inverseDCT::inverseDCT() +{ + for(int x = 0; x < 8; x++) { + for(int u = 0; u < 8; u++) { + float value = cos((x*2+1)*u*PI/16); + m_cosxu[x*8+u] = value * 32; + } + } + + for(int v = 0; v < 8; v++) { + for(int u = 0; u < 8; u++) { + float value = 1.0 / 4.0; + if (v == 0 && u == 0) { + value /= 2.0; + } else if (v == 0 || u == 0) { + value /= sqrt(2.0); + } + m_cucv[v*8+u] = value * 32; + } + } +} + +void inverseDCT::inputBLOCK(int mcu, int block, int scan, int value) +{ + if (scan == 0) { + for(int i = 0; i < 64; i++) { + m_sum[i] = 0; + } + } + + if (value != 0) { + int uv = zigzag[scan]; + int u = uv % 8; + int v = uv / 8; + for(int y = 0; y < 8; y++) { + for(int x = 0; x < 8; x++) { + int t = m_cucv[uv] * value * m_cosxu[x*8+u] * m_cosxu[y*8+v] / 32 / 32; + m_sum[y*8+x] += t; + } + } + } + + if (scan == 63) { + uint8_t result[64]; + for(int i = 0; i < 64; i++) { + int value = m_sum[i] / 32; + result[i] = adjust(value); + } + outputBLOCK(mcu, block, result); + } +} + +#else + +inverseDCT::inverseDCT() +{ +} + +void inverseDCT::input(int mcu, int block, int scan, int value) { + if (scan == 0) { + for(int i = 0; i < 64; i++) { + m_s[i] = 0; + } + } + m_s[zigzag[scan]] = value; + if (scan == 63) { + calc(mcu, block, m_s); + } +} + +void inverseDCT::calc(int mcu, int block, int s[]) { + for(int y = 0; y < 8; y++) { + for(int x = 0; x < 8; x++) { + float sum = 0.0; + for(int v = 0; v < 8; v++) { + float cv = 1.0; + if (v == 0) { + cv /= sqrt(2.0); + } + for(int u = 0; u < 8; u++) { + float cu = 1.0; + if (u == 0) { + cu /= sqrt(2.0); + } + int vu = v * 8 + u; + float cosxu = cos((x*2+1) * u * PI / 16); + float cosyv = cos((y*2+1) * v * PI / 16); + sum += cu * cv * s[vu] * cosxu * cosyv; + } + } + sum /= 4; + m_result[y*8+x] = adjust(sum); + } + } +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inverseDCT.h Tue Oct 30 13:22:08 2012 +0000 @@ -0,0 +1,35 @@ +#ifndef INVERSE_DCT_H +#define INVERSE_DCT_H + +#define DCT_USE_INT 1 + +#ifdef DCT_USE_INT + +class inverseDCT { +public: + inverseDCT(); + void inputBLOCK(int mcu, int block, int scan, int value); + virtual void outputBLOCK(int mcu, int block, unsigned char* values) = 0; +private: + int16_t m_sum[64]; + int8_t m_cosxu[64]; + int8_t m_cucv[64]; +}; + +#else + +class inverseDCT { +public: + inverseDCT(); + void input(int mcu, int block, int scan, int value); + int m_result[64]; +private: + int m_sum[64]; + void calc(int mcu, int block, int s[]); + int m_s[64]; + void outputDot(int mcu, int block, int x, int y, int value); +}; + +#endif + +#endif // INVERSE_DCT_H \ No newline at end of file