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
inverseDCT.cpp
- Committer:
- va009039
- Date:
- 2012-10-30
- Revision:
- 2:5b1dd4e34857
- Child:
- 3:a7547692071d
File content as of revision 2:5b1dd4e34857:
#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