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