huffmancode to decode in real-time for motion-jpeg
Dependents: BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2
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 }
Generated on Thu Jul 14 2022 18:10:56 by 1.7.2