Any changes are to allow conversion to BMP

Dependents:   Color_Targeting_Catapult

Fork of BaseJpegDecode by Norimasa Okamoto

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