Any changes are to allow conversion to BMP
Dependents: Color_Targeting_Catapult
Fork of BaseJpegDecode by
inverseDCT.cpp@2:5b1dd4e34857, 2012-10-30 (annotated)
- Committer:
- va009039
- Date:
- Tue Oct 30 13:22:08 2012 +0000
- Revision:
- 2:5b1dd4e34857
- Child:
- 3:a7547692071d
add inverseDCT
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 2:5b1dd4e34857 | 1 | #include "mbed.h" |
va009039 | 2:5b1dd4e34857 | 2 | #include <math.h> |
va009039 | 2:5b1dd4e34857 | 3 | #include "inverseDCT.h" |
va009039 | 2:5b1dd4e34857 | 4 | |
va009039 | 2:5b1dd4e34857 | 5 | #define PI 3.14159265 |
va009039 | 2:5b1dd4e34857 | 6 | |
va009039 | 2:5b1dd4e34857 | 7 | const int zigzag[64] = |
va009039 | 2:5b1dd4e34857 | 8 | {0, |
va009039 | 2:5b1dd4e34857 | 9 | 1, 8, |
va009039 | 2:5b1dd4e34857 | 10 | 16, 9, 2, |
va009039 | 2:5b1dd4e34857 | 11 | 3,10,17,24, |
va009039 | 2:5b1dd4e34857 | 12 | 32,25,18,11, 4, |
va009039 | 2:5b1dd4e34857 | 13 | 5,12,19,26,33,40, |
va009039 | 2:5b1dd4e34857 | 14 | 48,41,34,27,20,13,6, |
va009039 | 2:5b1dd4e34857 | 15 | 7,14,21,28,35,42,49,56, |
va009039 | 2:5b1dd4e34857 | 16 | 57,50,43,36,29,22,15, |
va009039 | 2:5b1dd4e34857 | 17 | 23,30,37,44,51,58, |
va009039 | 2:5b1dd4e34857 | 18 | 59,52,45,38,31, |
va009039 | 2:5b1dd4e34857 | 19 | 39,46,53,60, |
va009039 | 2:5b1dd4e34857 | 20 | 61,54,47, |
va009039 | 2:5b1dd4e34857 | 21 | 55,62, |
va009039 | 2:5b1dd4e34857 | 22 | 63}; |
va009039 | 2:5b1dd4e34857 | 23 | |
va009039 | 2:5b1dd4e34857 | 24 | int adjust(int value) { |
va009039 | 2:5b1dd4e34857 | 25 | value += 128; |
va009039 | 2:5b1dd4e34857 | 26 | if (value < 0) { |
va009039 | 2:5b1dd4e34857 | 27 | return 0; |
va009039 | 2:5b1dd4e34857 | 28 | } else if (value > 255) { |
va009039 | 2:5b1dd4e34857 | 29 | return 255; |
va009039 | 2:5b1dd4e34857 | 30 | } |
va009039 | 2:5b1dd4e34857 | 31 | return value; |
va009039 | 2:5b1dd4e34857 | 32 | } |
va009039 | 2:5b1dd4e34857 | 33 | |
va009039 | 2:5b1dd4e34857 | 34 | #if DCT_USE_INT |
va009039 | 2:5b1dd4e34857 | 35 | inverseDCT::inverseDCT() |
va009039 | 2:5b1dd4e34857 | 36 | { |
va009039 | 2:5b1dd4e34857 | 37 | for(int x = 0; x < 8; x++) { |
va009039 | 2:5b1dd4e34857 | 38 | for(int u = 0; u < 8; u++) { |
va009039 | 2:5b1dd4e34857 | 39 | float value = cos((x*2+1)*u*PI/16); |
va009039 | 2:5b1dd4e34857 | 40 | m_cosxu[x*8+u] = value * 32; |
va009039 | 2:5b1dd4e34857 | 41 | } |
va009039 | 2:5b1dd4e34857 | 42 | } |
va009039 | 2:5b1dd4e34857 | 43 | |
va009039 | 2:5b1dd4e34857 | 44 | for(int v = 0; v < 8; v++) { |
va009039 | 2:5b1dd4e34857 | 45 | for(int u = 0; u < 8; u++) { |
va009039 | 2:5b1dd4e34857 | 46 | float value = 1.0 / 4.0; |
va009039 | 2:5b1dd4e34857 | 47 | if (v == 0 && u == 0) { |
va009039 | 2:5b1dd4e34857 | 48 | value /= 2.0; |
va009039 | 2:5b1dd4e34857 | 49 | } else if (v == 0 || u == 0) { |
va009039 | 2:5b1dd4e34857 | 50 | value /= sqrt(2.0); |
va009039 | 2:5b1dd4e34857 | 51 | } |
va009039 | 2:5b1dd4e34857 | 52 | m_cucv[v*8+u] = value * 32; |
va009039 | 2:5b1dd4e34857 | 53 | } |
va009039 | 2:5b1dd4e34857 | 54 | } |
va009039 | 2:5b1dd4e34857 | 55 | } |
va009039 | 2:5b1dd4e34857 | 56 | |
va009039 | 2:5b1dd4e34857 | 57 | void inverseDCT::inputBLOCK(int mcu, int block, int scan, int value) |
va009039 | 2:5b1dd4e34857 | 58 | { |
va009039 | 2:5b1dd4e34857 | 59 | if (scan == 0) { |
va009039 | 2:5b1dd4e34857 | 60 | for(int i = 0; i < 64; i++) { |
va009039 | 2:5b1dd4e34857 | 61 | m_sum[i] = 0; |
va009039 | 2:5b1dd4e34857 | 62 | } |
va009039 | 2:5b1dd4e34857 | 63 | } |
va009039 | 2:5b1dd4e34857 | 64 | |
va009039 | 2:5b1dd4e34857 | 65 | if (value != 0) { |
va009039 | 2:5b1dd4e34857 | 66 | int uv = zigzag[scan]; |
va009039 | 2:5b1dd4e34857 | 67 | int u = uv % 8; |
va009039 | 2:5b1dd4e34857 | 68 | int v = uv / 8; |
va009039 | 2:5b1dd4e34857 | 69 | for(int y = 0; y < 8; y++) { |
va009039 | 2:5b1dd4e34857 | 70 | for(int x = 0; x < 8; x++) { |
va009039 | 2:5b1dd4e34857 | 71 | int t = m_cucv[uv] * value * m_cosxu[x*8+u] * m_cosxu[y*8+v] / 32 / 32; |
va009039 | 2:5b1dd4e34857 | 72 | m_sum[y*8+x] += t; |
va009039 | 2:5b1dd4e34857 | 73 | } |
va009039 | 2:5b1dd4e34857 | 74 | } |
va009039 | 2:5b1dd4e34857 | 75 | } |
va009039 | 2:5b1dd4e34857 | 76 | |
va009039 | 2:5b1dd4e34857 | 77 | if (scan == 63) { |
va009039 | 2:5b1dd4e34857 | 78 | uint8_t result[64]; |
va009039 | 2:5b1dd4e34857 | 79 | for(int i = 0; i < 64; i++) { |
va009039 | 2:5b1dd4e34857 | 80 | int value = m_sum[i] / 32; |
va009039 | 2:5b1dd4e34857 | 81 | result[i] = adjust(value); |
va009039 | 2:5b1dd4e34857 | 82 | } |
va009039 | 2:5b1dd4e34857 | 83 | outputBLOCK(mcu, block, result); |
va009039 | 2:5b1dd4e34857 | 84 | } |
va009039 | 2:5b1dd4e34857 | 85 | } |
va009039 | 2:5b1dd4e34857 | 86 | |
va009039 | 2:5b1dd4e34857 | 87 | #else |
va009039 | 2:5b1dd4e34857 | 88 | |
va009039 | 2:5b1dd4e34857 | 89 | inverseDCT::inverseDCT() |
va009039 | 2:5b1dd4e34857 | 90 | { |
va009039 | 2:5b1dd4e34857 | 91 | } |
va009039 | 2:5b1dd4e34857 | 92 | |
va009039 | 2:5b1dd4e34857 | 93 | void inverseDCT::input(int mcu, int block, int scan, int value) { |
va009039 | 2:5b1dd4e34857 | 94 | if (scan == 0) { |
va009039 | 2:5b1dd4e34857 | 95 | for(int i = 0; i < 64; i++) { |
va009039 | 2:5b1dd4e34857 | 96 | m_s[i] = 0; |
va009039 | 2:5b1dd4e34857 | 97 | } |
va009039 | 2:5b1dd4e34857 | 98 | } |
va009039 | 2:5b1dd4e34857 | 99 | m_s[zigzag[scan]] = value; |
va009039 | 2:5b1dd4e34857 | 100 | if (scan == 63) { |
va009039 | 2:5b1dd4e34857 | 101 | calc(mcu, block, m_s); |
va009039 | 2:5b1dd4e34857 | 102 | } |
va009039 | 2:5b1dd4e34857 | 103 | } |
va009039 | 2:5b1dd4e34857 | 104 | |
va009039 | 2:5b1dd4e34857 | 105 | void inverseDCT::calc(int mcu, int block, int s[]) { |
va009039 | 2:5b1dd4e34857 | 106 | for(int y = 0; y < 8; y++) { |
va009039 | 2:5b1dd4e34857 | 107 | for(int x = 0; x < 8; x++) { |
va009039 | 2:5b1dd4e34857 | 108 | float sum = 0.0; |
va009039 | 2:5b1dd4e34857 | 109 | for(int v = 0; v < 8; v++) { |
va009039 | 2:5b1dd4e34857 | 110 | float cv = 1.0; |
va009039 | 2:5b1dd4e34857 | 111 | if (v == 0) { |
va009039 | 2:5b1dd4e34857 | 112 | cv /= sqrt(2.0); |
va009039 | 2:5b1dd4e34857 | 113 | } |
va009039 | 2:5b1dd4e34857 | 114 | for(int u = 0; u < 8; u++) { |
va009039 | 2:5b1dd4e34857 | 115 | float cu = 1.0; |
va009039 | 2:5b1dd4e34857 | 116 | if (u == 0) { |
va009039 | 2:5b1dd4e34857 | 117 | cu /= sqrt(2.0); |
va009039 | 2:5b1dd4e34857 | 118 | } |
va009039 | 2:5b1dd4e34857 | 119 | int vu = v * 8 + u; |
va009039 | 2:5b1dd4e34857 | 120 | float cosxu = cos((x*2+1) * u * PI / 16); |
va009039 | 2:5b1dd4e34857 | 121 | float cosyv = cos((y*2+1) * v * PI / 16); |
va009039 | 2:5b1dd4e34857 | 122 | sum += cu * cv * s[vu] * cosxu * cosyv; |
va009039 | 2:5b1dd4e34857 | 123 | } |
va009039 | 2:5b1dd4e34857 | 124 | } |
va009039 | 2:5b1dd4e34857 | 125 | sum /= 4; |
va009039 | 2:5b1dd4e34857 | 126 | m_result[y*8+x] = adjust(sum); |
va009039 | 2:5b1dd4e34857 | 127 | } |
va009039 | 2:5b1dd4e34857 | 128 | } |
va009039 | 2:5b1dd4e34857 | 129 | } |
va009039 | 2:5b1dd4e34857 | 130 | #endif |