test
Dependencies: Nanopb iSerial mbed BaseJpegDecode FatFileSystem SDFileSystem RingBuffer Camera_LS_Y201
extlib/BaseJpegDecode/aanIDCT.cpp@0:d69efd0ee139, 2014-09-18 (annotated)
- Committer:
- cgraham
- Date:
- Thu Sep 18 15:21:47 2014 +0000
- Revision:
- 0:d69efd0ee139
test
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cgraham | 0:d69efd0ee139 | 1 | // aanIDCT.cpp 2013/2/1 |
cgraham | 0:d69efd0ee139 | 2 | // based: http://www.ijg.org/ libjpeg(jpeg-8d)jidctfst.c jidctflt.c jidctmgr.c |
cgraham | 0:d69efd0ee139 | 3 | #include "mbed.h" |
cgraham | 0:d69efd0ee139 | 4 | #include "aanIDCT.h" |
cgraham | 0:d69efd0ee139 | 5 | |
cgraham | 0:d69efd0ee139 | 6 | #define DCTSIZE 8 |
cgraham | 0:d69efd0ee139 | 7 | #define DCTSIZE2 64 |
cgraham | 0:d69efd0ee139 | 8 | #define CONST_BITS 8 |
cgraham | 0:d69efd0ee139 | 9 | #define PASS1_BITS 2 |
cgraham | 0:d69efd0ee139 | 10 | #define SCALE_BITS 14 |
cgraham | 0:d69efd0ee139 | 11 | #define LOG2_CONST 3 |
cgraham | 0:d69efd0ee139 | 12 | #define FIX_1_082392200 277 |
cgraham | 0:d69efd0ee139 | 13 | #define FIX_1_414213562 362 |
cgraham | 0:d69efd0ee139 | 14 | #define FIX_1_847759065 473 |
cgraham | 0:d69efd0ee139 | 15 | #define FIX_2_613125930 668 |
cgraham | 0:d69efd0ee139 | 16 | const uint16_t aanscales[] = { |
cgraham | 0:d69efd0ee139 | 17 | 16384, 22725, 21406, 19265, 16384, 12872, 8866, 4520, |
cgraham | 0:d69efd0ee139 | 18 | 22725, 31520, 29691, 26722, 22725, 17855, 12298, 6269, |
cgraham | 0:d69efd0ee139 | 19 | 21406, 29691, 27969, 25171, 21406, 16819, 11585, 5906, |
cgraham | 0:d69efd0ee139 | 20 | 19265, 26722, 25171, 22653, 19265, 15136, 10426, 5315, |
cgraham | 0:d69efd0ee139 | 21 | 16384, 22725, 21406, 19265, 16384, 12872, 8866, 4520, |
cgraham | 0:d69efd0ee139 | 22 | 12872, 17855, 16819, 15136, 12872, 10114, 6966, 3551, |
cgraham | 0:d69efd0ee139 | 23 | 8866, 12298, 11585, 10426, 8866, 6966, 4798, 2446, |
cgraham | 0:d69efd0ee139 | 24 | 4520, 6269, 5906, 5315, 4520, 3551, 2446, 1247, |
cgraham | 0:d69efd0ee139 | 25 | }; |
cgraham | 0:d69efd0ee139 | 26 | |
cgraham | 0:d69efd0ee139 | 27 | #if 0 |
cgraham | 0:d69efd0ee139 | 28 | inline int DESCALE(int x, int n) { |
cgraham | 0:d69efd0ee139 | 29 | return (x / (1<<(n))); |
cgraham | 0:d69efd0ee139 | 30 | } |
cgraham | 0:d69efd0ee139 | 31 | #else |
cgraham | 0:d69efd0ee139 | 32 | #define DESCALE(x, n) ((x)/(1<<(n))) |
cgraham | 0:d69efd0ee139 | 33 | #endif |
cgraham | 0:d69efd0ee139 | 34 | |
cgraham | 0:d69efd0ee139 | 35 | int DEQUANTIZE(int coef, int quantval) { |
cgraham | 0:d69efd0ee139 | 36 | return DESCALE(coef * quantval, SCALE_BITS-PASS1_BITS); |
cgraham | 0:d69efd0ee139 | 37 | } |
cgraham | 0:d69efd0ee139 | 38 | |
cgraham | 0:d69efd0ee139 | 39 | #if 1 |
cgraham | 0:d69efd0ee139 | 40 | int MULTIPLY(int a, int b) { |
cgraham | 0:d69efd0ee139 | 41 | return DESCALE(a * b, CONST_BITS); |
cgraham | 0:d69efd0ee139 | 42 | } |
cgraham | 0:d69efd0ee139 | 43 | #else |
cgraham | 0:d69efd0ee139 | 44 | #define MULTIPLY(a, b) (((a)*(b))/(1<<CONST_BITS)) |
cgraham | 0:d69efd0ee139 | 45 | #endif |
cgraham | 0:d69efd0ee139 | 46 | |
cgraham | 0:d69efd0ee139 | 47 | int IDESCALE(int x) { |
cgraham | 0:d69efd0ee139 | 48 | return DESCALE(x, PASS1_BITS+LOG2_CONST); |
cgraham | 0:d69efd0ee139 | 49 | } |
cgraham | 0:d69efd0ee139 | 50 | |
cgraham | 0:d69efd0ee139 | 51 | #if 1 |
cgraham | 0:d69efd0ee139 | 52 | int8_t range_limit(int val) { |
cgraham | 0:d69efd0ee139 | 53 | if (val < -128) { |
cgraham | 0:d69efd0ee139 | 54 | return -128; |
cgraham | 0:d69efd0ee139 | 55 | } else if (val > 127) { |
cgraham | 0:d69efd0ee139 | 56 | return 127; |
cgraham | 0:d69efd0ee139 | 57 | } |
cgraham | 0:d69efd0ee139 | 58 | return val; |
cgraham | 0:d69efd0ee139 | 59 | } |
cgraham | 0:d69efd0ee139 | 60 | #else |
cgraham | 0:d69efd0ee139 | 61 | inline int8_t range_limit(int val) { |
cgraham | 0:d69efd0ee139 | 62 | if (val < -128) { |
cgraham | 0:d69efd0ee139 | 63 | return -128; |
cgraham | 0:d69efd0ee139 | 64 | } else if (val > 127) { |
cgraham | 0:d69efd0ee139 | 65 | return 127; |
cgraham | 0:d69efd0ee139 | 66 | } |
cgraham | 0:d69efd0ee139 | 67 | return val; |
cgraham | 0:d69efd0ee139 | 68 | } |
cgraham | 0:d69efd0ee139 | 69 | #endif |
cgraham | 0:d69efd0ee139 | 70 | |
cgraham | 0:d69efd0ee139 | 71 | void aanIDCT::conv(int8_t output[], int16_t input[]) |
cgraham | 0:d69efd0ee139 | 72 | { |
cgraham | 0:d69efd0ee139 | 73 | uint16_t* quant = (uint16_t*)aanscales; |
cgraham | 0:d69efd0ee139 | 74 | for(int pos = 0; pos < DCTSIZE; pos++) { |
cgraham | 0:d69efd0ee139 | 75 | if (input[pos+DCTSIZE*1] == 0 && input[pos+DCTSIZE*2] == 0 && |
cgraham | 0:d69efd0ee139 | 76 | input[pos+DCTSIZE*3] == 0 && input[pos+DCTSIZE*4] == 0 && |
cgraham | 0:d69efd0ee139 | 77 | input[pos+DCTSIZE*5] == 0 && input[pos+DCTSIZE*6] == 0 && |
cgraham | 0:d69efd0ee139 | 78 | input[pos+DCTSIZE*7] == 0) { |
cgraham | 0:d69efd0ee139 | 79 | int dcval = DEQUANTIZE(input[pos+DCTSIZE*0], quant[pos+DCTSIZE*0]); |
cgraham | 0:d69efd0ee139 | 80 | for(int y = 0; y < DCTSIZE; y++) { |
cgraham | 0:d69efd0ee139 | 81 | ws[pos+DCTSIZE*y] = dcval; |
cgraham | 0:d69efd0ee139 | 82 | } |
cgraham | 0:d69efd0ee139 | 83 | continue; |
cgraham | 0:d69efd0ee139 | 84 | } |
cgraham | 0:d69efd0ee139 | 85 | // Even part |
cgraham | 0:d69efd0ee139 | 86 | int tmp0 = DEQUANTIZE(input[pos+DCTSIZE*0], quant[pos+DCTSIZE*0]); |
cgraham | 0:d69efd0ee139 | 87 | int tmp1 = DEQUANTIZE(input[pos+DCTSIZE*2], quant[pos+DCTSIZE*2]); |
cgraham | 0:d69efd0ee139 | 88 | int tmp2 = DEQUANTIZE(input[pos+DCTSIZE*4], quant[pos+DCTSIZE*4]); |
cgraham | 0:d69efd0ee139 | 89 | int tmp3 = DEQUANTIZE(input[pos+DCTSIZE*6], quant[pos+DCTSIZE*6]); |
cgraham | 0:d69efd0ee139 | 90 | |
cgraham | 0:d69efd0ee139 | 91 | int tmp10 = tmp0 + tmp2; // phase 3 |
cgraham | 0:d69efd0ee139 | 92 | int tmp11 = tmp0 - tmp2; |
cgraham | 0:d69efd0ee139 | 93 | |
cgraham | 0:d69efd0ee139 | 94 | int tmp13 = tmp1 + tmp3; // phases 5-3 |
cgraham | 0:d69efd0ee139 | 95 | int tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; // 2*c4 |
cgraham | 0:d69efd0ee139 | 96 | |
cgraham | 0:d69efd0ee139 | 97 | tmp0 = tmp10 + tmp13; // phase 2 |
cgraham | 0:d69efd0ee139 | 98 | tmp3 = tmp10 - tmp13; |
cgraham | 0:d69efd0ee139 | 99 | tmp1 = tmp11 + tmp12; |
cgraham | 0:d69efd0ee139 | 100 | tmp2 = tmp11 - tmp12; |
cgraham | 0:d69efd0ee139 | 101 | |
cgraham | 0:d69efd0ee139 | 102 | // Odd part |
cgraham | 0:d69efd0ee139 | 103 | int tmp4 = DEQUANTIZE(input[pos+DCTSIZE*1], quant[pos+DCTSIZE*1]); |
cgraham | 0:d69efd0ee139 | 104 | int tmp5 = DEQUANTIZE(input[pos+DCTSIZE*3], quant[pos+DCTSIZE*3]); |
cgraham | 0:d69efd0ee139 | 105 | int tmp6 = DEQUANTIZE(input[pos+DCTSIZE*5], quant[pos+DCTSIZE*5]); |
cgraham | 0:d69efd0ee139 | 106 | int tmp7 = DEQUANTIZE(input[pos+DCTSIZE*7], quant[pos+DCTSIZE*7]); |
cgraham | 0:d69efd0ee139 | 107 | |
cgraham | 0:d69efd0ee139 | 108 | int z13 = tmp6 + tmp5; // phase 6 |
cgraham | 0:d69efd0ee139 | 109 | int z10 = tmp6 - tmp5; |
cgraham | 0:d69efd0ee139 | 110 | int z11 = tmp4 + tmp7; |
cgraham | 0:d69efd0ee139 | 111 | int z12 = tmp4 - tmp7; |
cgraham | 0:d69efd0ee139 | 112 | |
cgraham | 0:d69efd0ee139 | 113 | tmp7 = z11 + z13; // phase 5 |
cgraham | 0:d69efd0ee139 | 114 | tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); // 2*c4 |
cgraham | 0:d69efd0ee139 | 115 | |
cgraham | 0:d69efd0ee139 | 116 | int z5 = MULTIPLY(z10 + z12, FIX_1_847759065); // 2*c2 |
cgraham | 0:d69efd0ee139 | 117 | tmp10 = MULTIPLY(z12, - FIX_1_082392200) + z5; // 2*(c2-c6) |
cgraham | 0:d69efd0ee139 | 118 | tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; // -2*(c2+c6) |
cgraham | 0:d69efd0ee139 | 119 | |
cgraham | 0:d69efd0ee139 | 120 | tmp6 = tmp12 - tmp7; // phase 2 |
cgraham | 0:d69efd0ee139 | 121 | tmp5 = tmp11 - tmp6; |
cgraham | 0:d69efd0ee139 | 122 | tmp4 = tmp10 - tmp5; |
cgraham | 0:d69efd0ee139 | 123 | |
cgraham | 0:d69efd0ee139 | 124 | ws[pos+DCTSIZE*0] = tmp0 + tmp7; |
cgraham | 0:d69efd0ee139 | 125 | ws[pos+DCTSIZE*7] = tmp0 - tmp7; |
cgraham | 0:d69efd0ee139 | 126 | ws[pos+DCTSIZE*1] = tmp1 + tmp6; |
cgraham | 0:d69efd0ee139 | 127 | ws[pos+DCTSIZE*6] = tmp1 - tmp6; |
cgraham | 0:d69efd0ee139 | 128 | ws[pos+DCTSIZE*2] = tmp2 + tmp5; |
cgraham | 0:d69efd0ee139 | 129 | ws[pos+DCTSIZE*5] = tmp2 - tmp5; |
cgraham | 0:d69efd0ee139 | 130 | ws[pos+DCTSIZE*3] = tmp3 + tmp4; |
cgraham | 0:d69efd0ee139 | 131 | ws[pos+DCTSIZE*4] = tmp3 - tmp4; |
cgraham | 0:d69efd0ee139 | 132 | } |
cgraham | 0:d69efd0ee139 | 133 | |
cgraham | 0:d69efd0ee139 | 134 | for(int pos = 0; pos < DCTSIZE2; pos += DCTSIZE) { |
cgraham | 0:d69efd0ee139 | 135 | if (ws[pos+1] == 0 && ws[pos+2] == 0 && ws[pos+3] == 0 && |
cgraham | 0:d69efd0ee139 | 136 | ws[pos+4] == 0 && ws[pos+5] == 0 && ws[pos+6] == 0 && |
cgraham | 0:d69efd0ee139 | 137 | ws[pos+7] == 0) { |
cgraham | 0:d69efd0ee139 | 138 | int dcval = ws[pos+0]; |
cgraham | 0:d69efd0ee139 | 139 | for(int x = 0; x < DCTSIZE; x++) { |
cgraham | 0:d69efd0ee139 | 140 | output[pos+x] = range_limit(IDESCALE(dcval)); |
cgraham | 0:d69efd0ee139 | 141 | } |
cgraham | 0:d69efd0ee139 | 142 | continue; |
cgraham | 0:d69efd0ee139 | 143 | } |
cgraham | 0:d69efd0ee139 | 144 | // Even part |
cgraham | 0:d69efd0ee139 | 145 | int tmp10 = ws[pos+0] + ws[pos+4]; |
cgraham | 0:d69efd0ee139 | 146 | int tmp11 = ws[pos+0] - ws[pos+4]; |
cgraham | 0:d69efd0ee139 | 147 | |
cgraham | 0:d69efd0ee139 | 148 | int tmp13 = ws[pos+2] + ws[pos+6]; |
cgraham | 0:d69efd0ee139 | 149 | int tmp12 = MULTIPLY(ws[pos+2] - ws[pos+6], FIX_1_414213562) - tmp13; |
cgraham | 0:d69efd0ee139 | 150 | |
cgraham | 0:d69efd0ee139 | 151 | int tmp0 = tmp10 + tmp13; |
cgraham | 0:d69efd0ee139 | 152 | int tmp3 = tmp10 - tmp13; |
cgraham | 0:d69efd0ee139 | 153 | int tmp1 = tmp11 + tmp12; |
cgraham | 0:d69efd0ee139 | 154 | int tmp2 = tmp11 - tmp12; |
cgraham | 0:d69efd0ee139 | 155 | |
cgraham | 0:d69efd0ee139 | 156 | // Odd part |
cgraham | 0:d69efd0ee139 | 157 | int z13 = ws[pos+5] + ws[pos+3]; |
cgraham | 0:d69efd0ee139 | 158 | int z10 = ws[pos+5] - ws[pos+3]; |
cgraham | 0:d69efd0ee139 | 159 | int z11 = ws[pos+1] + ws[pos+7]; |
cgraham | 0:d69efd0ee139 | 160 | int z12 = ws[pos+1] - ws[pos+7]; |
cgraham | 0:d69efd0ee139 | 161 | |
cgraham | 0:d69efd0ee139 | 162 | int tmp7 = z11 + z13; // phase 5 |
cgraham | 0:d69efd0ee139 | 163 | tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); // 2*c4 |
cgraham | 0:d69efd0ee139 | 164 | |
cgraham | 0:d69efd0ee139 | 165 | int z5 = MULTIPLY(z10 + z12, FIX_1_847759065); // 2*c2 |
cgraham | 0:d69efd0ee139 | 166 | tmp10 = MULTIPLY(z12, - FIX_1_082392200) + z5; // 2*(c2-c6) |
cgraham | 0:d69efd0ee139 | 167 | tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; // -2*(c2+c6) |
cgraham | 0:d69efd0ee139 | 168 | |
cgraham | 0:d69efd0ee139 | 169 | int tmp6 = tmp12 - tmp7; // phase 2 |
cgraham | 0:d69efd0ee139 | 170 | int tmp5 = tmp11 - tmp6; |
cgraham | 0:d69efd0ee139 | 171 | int tmp4 = tmp10 - tmp5; |
cgraham | 0:d69efd0ee139 | 172 | |
cgraham | 0:d69efd0ee139 | 173 | output[pos+0] = range_limit(IDESCALE(tmp0 + tmp7)); |
cgraham | 0:d69efd0ee139 | 174 | output[pos+7] = range_limit(IDESCALE(tmp0 - tmp7)); |
cgraham | 0:d69efd0ee139 | 175 | output[pos+1] = range_limit(IDESCALE(tmp1 + tmp6)); |
cgraham | 0:d69efd0ee139 | 176 | output[pos+6] = range_limit(IDESCALE(tmp1 - tmp6)); |
cgraham | 0:d69efd0ee139 | 177 | output[pos+2] = range_limit(IDESCALE(tmp2 + tmp5)); |
cgraham | 0:d69efd0ee139 | 178 | output[pos+5] = range_limit(IDESCALE(tmp2 - tmp5)); |
cgraham | 0:d69efd0ee139 | 179 | output[pos+3] = range_limit(IDESCALE(tmp3 + tmp4)); |
cgraham | 0:d69efd0ee139 | 180 | output[pos+4] = range_limit(IDESCALE(tmp3 - tmp4)); |
cgraham | 0:d69efd0ee139 | 181 | } |
cgraham | 0:d69efd0ee139 | 182 | } |