huffmancode to decode in real-time for motion-jpeg

Dependents:   BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aanIDCT.cpp Source File

aanIDCT.cpp

00001 // aanIDCT.cpp 2013/2/1
00002 // based: http://www.ijg.org/ libjpeg(jpeg-8d)jidctfst.c jidctflt.c jidctmgr.c
00003 #include "mbed.h"
00004 #include "aanIDCT.h"
00005 
00006 #define DCTSIZE 8
00007 #define DCTSIZE2 64
00008 #define CONST_BITS 8
00009 #define PASS1_BITS 2
00010 #define SCALE_BITS 14
00011 #define LOG2_CONST 3
00012 #define FIX_1_082392200 277
00013 #define FIX_1_414213562 362
00014 #define FIX_1_847759065 473
00015 #define FIX_2_613125930 668
00016 const uint16_t aanscales[] = {
00017 16384, 22725, 21406, 19265, 16384, 12872,  8866,  4520,
00018 22725, 31520, 29691, 26722, 22725, 17855, 12298,  6269,
00019 21406, 29691, 27969, 25171, 21406, 16819, 11585,  5906,
00020 19265, 26722, 25171, 22653, 19265, 15136, 10426,  5315,
00021 16384, 22725, 21406, 19265, 16384, 12872,  8866,  4520,
00022 12872, 17855, 16819, 15136, 12872, 10114,  6966,  3551,
00023  8866, 12298, 11585, 10426,  8866,  6966,  4798,  2446,
00024  4520,  6269,  5906,  5315,  4520,  3551,  2446,  1247,
00025 };
00026 
00027 #if 0
00028 inline int DESCALE(int x, int n) {
00029     return (x / (1<<(n)));
00030 }
00031 #else
00032 #define DESCALE(x, n) ((x)/(1<<(n)))
00033 #endif
00034 
00035 int DEQUANTIZE(int coef, int quantval) {
00036     return DESCALE(coef * quantval, SCALE_BITS-PASS1_BITS);
00037 }
00038 
00039 #if 1
00040 int MULTIPLY(int a, int b) {
00041     return DESCALE(a * b, CONST_BITS);
00042 }
00043 #else
00044 #define MULTIPLY(a, b) (((a)*(b))/(1<<CONST_BITS))
00045 #endif
00046 
00047 int IDESCALE(int x) {
00048     return DESCALE(x, PASS1_BITS+LOG2_CONST);
00049 }
00050 
00051 #if 1
00052 int8_t range_limit(int val) {
00053     if (val < -128) {
00054         return -128;
00055     } else if (val > 127) {
00056         return 127;
00057     }
00058     return val;
00059 }
00060 #else
00061 inline int8_t range_limit(int val) {
00062     if (val < -128) {
00063         return -128;
00064     } else if (val > 127) {
00065         return 127;
00066     }
00067     return val;
00068 }
00069 #endif
00070 
00071 void aanIDCT::conv(int8_t output[], int16_t input[])
00072 {
00073     uint16_t* quant = (uint16_t*)aanscales;
00074     for(int pos = 0; pos < DCTSIZE; pos++) {
00075         if (input[pos+DCTSIZE*1] == 0 && input[pos+DCTSIZE*2] == 0 &&
00076                input[pos+DCTSIZE*3] == 0 && input[pos+DCTSIZE*4] == 0 &&
00077                input[pos+DCTSIZE*5] == 0 && input[pos+DCTSIZE*6] == 0 &&
00078                input[pos+DCTSIZE*7] == 0) {
00079             int dcval = DEQUANTIZE(input[pos+DCTSIZE*0], quant[pos+DCTSIZE*0]);
00080             for(int y = 0; y < DCTSIZE; y++) {
00081                 ws[pos+DCTSIZE*y] = dcval;
00082             }
00083             continue;
00084         }
00085         // Even part
00086         int tmp0 = DEQUANTIZE(input[pos+DCTSIZE*0], quant[pos+DCTSIZE*0]);
00087         int tmp1 = DEQUANTIZE(input[pos+DCTSIZE*2], quant[pos+DCTSIZE*2]);
00088         int tmp2 = DEQUANTIZE(input[pos+DCTSIZE*4], quant[pos+DCTSIZE*4]);
00089         int tmp3 = DEQUANTIZE(input[pos+DCTSIZE*6], quant[pos+DCTSIZE*6]);
00090 
00091         int tmp10 = tmp0 + tmp2;    // phase 3
00092         int tmp11 = tmp0 - tmp2;
00093 
00094         int tmp13 = tmp1 + tmp3;    // phases 5-3
00095         int tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; // 2*c4
00096 
00097         tmp0 = tmp10 + tmp13;   // phase 2
00098         tmp3 = tmp10 - tmp13;
00099         tmp1 = tmp11 + tmp12;
00100         tmp2 = tmp11 - tmp12;
00101 
00102         // Odd part
00103         int tmp4 = DEQUANTIZE(input[pos+DCTSIZE*1], quant[pos+DCTSIZE*1]);
00104         int tmp5 = DEQUANTIZE(input[pos+DCTSIZE*3], quant[pos+DCTSIZE*3]);
00105         int tmp6 = DEQUANTIZE(input[pos+DCTSIZE*5], quant[pos+DCTSIZE*5]);
00106         int tmp7 = DEQUANTIZE(input[pos+DCTSIZE*7], quant[pos+DCTSIZE*7]);
00107 
00108         int z13 = tmp6 + tmp5;  // phase 6
00109         int z10 = tmp6 - tmp5;  
00110         int z11 = tmp4 + tmp7;
00111         int z12 = tmp4 - tmp7;
00112 
00113         tmp7 = z11 + z13;       // phase 5
00114         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);   // 2*c4
00115 
00116         int z5 = MULTIPLY(z10 + z12, FIX_1_847759065);  // 2*c2
00117         tmp10 = MULTIPLY(z12, - FIX_1_082392200) + z5;  // 2*(c2-c6)
00118         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;  // -2*(c2+c6)
00119 
00120         tmp6 = tmp12 - tmp7;    // phase 2
00121         tmp5 = tmp11 - tmp6;
00122         tmp4 = tmp10 - tmp5;
00123 
00124         ws[pos+DCTSIZE*0] = tmp0 + tmp7;
00125         ws[pos+DCTSIZE*7] = tmp0 - tmp7;
00126         ws[pos+DCTSIZE*1] = tmp1 + tmp6;
00127         ws[pos+DCTSIZE*6] = tmp1 - tmp6;
00128         ws[pos+DCTSIZE*2] = tmp2 + tmp5;
00129         ws[pos+DCTSIZE*5] = tmp2 - tmp5;
00130         ws[pos+DCTSIZE*3] = tmp3 + tmp4;
00131         ws[pos+DCTSIZE*4] = tmp3 - tmp4;
00132     }
00133     
00134     for(int pos = 0; pos < DCTSIZE2; pos += DCTSIZE) {
00135         if (ws[pos+1] == 0 && ws[pos+2] == 0 && ws[pos+3] == 0 &&
00136                ws[pos+4] == 0 && ws[pos+5] == 0 && ws[pos+6] == 0 &&
00137                ws[pos+7] == 0) {
00138             int dcval = ws[pos+0];
00139             for(int x = 0; x < DCTSIZE; x++) {
00140                 output[pos+x] = range_limit(IDESCALE(dcval));
00141             }
00142             continue;
00143         }
00144         // Even part
00145         int tmp10 = ws[pos+0] + ws[pos+4];
00146         int tmp11 = ws[pos+0] - ws[pos+4];
00147 
00148         int tmp13 = ws[pos+2] + ws[pos+6];
00149         int tmp12 = MULTIPLY(ws[pos+2] - ws[pos+6], FIX_1_414213562) - tmp13;
00150 
00151         int tmp0 = tmp10 + tmp13;
00152         int tmp3 = tmp10 - tmp13;
00153         int tmp1 = tmp11 + tmp12;
00154         int tmp2 = tmp11 - tmp12;
00155 
00156         // Odd part
00157         int z13 = ws[pos+5] + ws[pos+3];
00158         int z10 = ws[pos+5] - ws[pos+3];
00159         int z11 = ws[pos+1] + ws[pos+7];
00160         int z12 = ws[pos+1] - ws[pos+7];
00161 
00162         int tmp7 = z11 + z13;       // phase 5
00163         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);   // 2*c4
00164 
00165         int z5 = MULTIPLY(z10 + z12, FIX_1_847759065);  // 2*c2
00166         tmp10 = MULTIPLY(z12, - FIX_1_082392200) + z5;  // 2*(c2-c6)
00167         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;  // -2*(c2+c6)
00168 
00169         int tmp6 = tmp12 - tmp7;    // phase 2
00170         int tmp5 = tmp11 - tmp6;
00171         int tmp4 = tmp10 - tmp5;
00172 
00173         output[pos+0] = range_limit(IDESCALE(tmp0 + tmp7));
00174         output[pos+7] = range_limit(IDESCALE(tmp0 - tmp7));
00175         output[pos+1] = range_limit(IDESCALE(tmp1 + tmp6));
00176         output[pos+6] = range_limit(IDESCALE(tmp1 - tmp6));
00177         output[pos+2] = range_limit(IDESCALE(tmp2 + tmp5));
00178         output[pos+5] = range_limit(IDESCALE(tmp2 - tmp5));
00179         output[pos+3] = range_limit(IDESCALE(tmp3 + tmp4));
00180         output[pos+4] = range_limit(IDESCALE(tmp3 - tmp4));
00181     }
00182 }