huffmancode to decode in real-time for motion-jpeg

Dependents:   BaseJpegDecode_example SimpleJpegDecode_example Dumb_box_rev2

example code:

Import programBaseJpegDecode_example

BaseJpegDeocde exampe program

Import programSimpleJpegDecode_example

convert JPEG stream data to bitmap, BaseJpegDecode example program

Committer:
va009039
Date:
Sat Feb 02 01:18:15 2013 +0000
Revision:
6:d7ee458cacd1
Parent:
3:a7547692071d
aanIDCT add range_limit()

Who changed what in which revision?

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