Any changes are to allow conversion to BMP
Dependents: Color_Targeting_Catapult
Fork of BaseJpegDecode by
Diff: inverseDCT.cpp
- Revision:
- 2:5b1dd4e34857
- Child:
- 3:a7547692071d
--- /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