OpenCores
URL https://opencores.org/ocsvn/mpeg2fpga/mpeg2fpga/trunk

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [tools/] [ieee1180/] [ieee1180/] [ieeetest.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * ieeetest.c --- test IDCT code against the IEEE Std 1180-1990 spec
3
 *
4
 * Note that this does only one pass of the test.
5
 * Six invocations of ieeetest are needed to complete the entire spec.
6
 * The shell script "doieee" performs the complete test.
7
 *
8
 * Written by Tom Lane (tgl@cs.cmu.edu).
9
 * Released to public domain 11/22/93.
10
 */
11
 
12
#include <stdio.h>
13
#include <string.h>
14
#include <stdlib.h>
15
#include <math.h>
16
 
17
#include "dct.h"
18
 
19
 
20
/* prototypes */
21
 
22
void usage (char *msg);
23
long ieeerand (long L, long H);
24
void dct_init(void);
25
void ref_fdct(DCTELEM block[8][8]);
26
void ref_idct(DCTELEM block[8][8]);
27
 
28
/* error stat accumulators -- assume initialized to 0 */
29
 
30
long sumerrs[DCTSIZE2];
31
long sumsqerrs[DCTSIZE2];
32
int maxerr[DCTSIZE2];
33
 
34
 
35
char * meets (double val, double limit)
36
{
37
  return ((fabs(val) <= limit) ? "meets" : "FAILS");
38
}
39
 
40
 
41
int
42
main(int argc, char **argv)
43
{
44
  long minpix, maxpix, sign;
45
  long curiter, niters;
46
  int i, j;
47
  double max, total;
48
  DCTELEM   block[DCTSIZE2];    /* random source data */
49
  DCTELEM   refcoefs[DCTSIZE2]; /* coefs from reference FDCT */
50
  DCTELEM   refout[DCTSIZE2];   /* output from reference IDCT */
51
  DCTELEM   testout[DCTSIZE2]; /* output from test IDCT */
52
 
53
  /* Argument parsing --- not very bulletproof at all */
54
 
55
  if (argc != 5) usage(NULL);
56
 
57
  minpix = atoi(argv[1]);
58
  maxpix = atoi(argv[2]);
59
  sign   = atoi(argv[3]);
60
  niters = atol(argv[4]);
61
 
62
  dct_init();
63
 
64
  /* Loop once per generated random-data block */
65
 
66
  for (curiter = 0; curiter < niters; curiter++) {
67
 
68
    /* generate a pseudo-random block of data */
69
    for (i = 0; i < DCTSIZE2; i++)
70
      block[i] = (DCTELEM) (ieeerand(-minpix,maxpix) * sign);
71
 
72
    /* perform reference FDCT */
73
    memcpy(refcoefs, block, sizeof(DCTELEM)*DCTSIZE2);
74
    ref_fdct(refcoefs);
75
    /* clip */
76
    for (i = 0; i < DCTSIZE2; i++) {
77
      if (refcoefs[i] < -2048) refcoefs[i] = -2048;
78
      else if (refcoefs[i] > 2047) refcoefs[i] = 2047;
79
    }
80
 
81
    /* perform reference IDCT */
82
    memcpy(refout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
83
    ref_idct(refout);
84
    /* clip */
85
    for (i = 0; i < DCTSIZE2; i++) {
86
      if (refout[i] < -256) refout[i] = -256;
87
      else if (refout[i] > 255) refout[i] = 255;
88
    }
89
 
90
    /* perform test IDCT */
91
    memcpy(testout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
92
    j_rev_dct(testout);
93
    /* clip */
94
    for (i = 0; i < DCTSIZE2; i++) {
95
      if (testout[i] < -256) testout[i] = -256;
96
      else if (testout[i] > 255) testout[i] = 255;
97
    }
98
 
99
    /* accumulate error stats */
100
    for (i = 0; i < DCTSIZE2; i++) {
101
      //printf(" testout: %d refout: %d \n", testout[i], refout[i]);
102
      register int err = testout[i] - refout[i];
103
      sumerrs[i] += err;
104
      sumsqerrs[i] += err * err;
105
      if (err < 0) err = -err;
106
      if (maxerr[i] < err) maxerr[i] = err;
107
    }
108
 
109
    if (curiter % 100 == 99) {
110
      fprintf(stderr, ".");
111
      fflush(stderr);
112
    }
113
  }
114
  fprintf(stderr, "\n");
115
 
116
  /* print results */
117
  printf("IEEE test conditions: -L = %ld, +H = %ld, sign = %ld, #iters = %ld\n",
118
         minpix, maxpix, sign, niters);
119
 
120
  printf("Peak absolute values of errors:\n");
121
  for (i = 0, j = 0; i < DCTSIZE2; i++) {
122
    if (j < maxerr[i]) j = maxerr[i];
123
    printf("%4d", maxerr[i]);
124
    if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
125
  }
126
  printf("Worst peak error = %d  (%s spec limit 1)\n\n", j,
127
         meets((double) j, 1.0));
128
 
129
  printf("Mean square errors:\n");
130
  max = total = 0.0;
131
  for (i = 0; i < DCTSIZE2; i++) {
132
    double err = (double) sumsqerrs[i]  / ((double) niters);
133
    total += (double) sumsqerrs[i];
134
    if (max < err) max = err;
135
    printf(" %8.4f", err);
136
    if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
137
  }
138
  printf("Worst pmse = %.6f  (%s spec limit 0.06)\n", max, meets(max, 0.06));
139
  total /= (double) (64*niters);
140
  printf("Overall mse = %.6f  (%s spec limit 0.02)\n\n", total,
141
         meets(total, 0.02));
142
 
143
  printf("Mean errors:\n");
144
  max = total = 0.0;
145
  for (i = 0; i < DCTSIZE2; i++) {
146
    double err = (double) sumerrs[i]  / ((double) niters);
147
    total += (double) sumerrs[i];
148
    printf(" %8.4f", err);
149
    if (err < 0.0) err = -err;
150
    if (max < err) max = err;
151
    if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
152
  }
153
  printf("Worst mean error = %.6f  (%s spec limit 0.015)\n", max,
154
         meets(max, 0.015));
155
  total /= (double) (64*niters);
156
  printf("Overall mean error = %.6f  (%s spec limit 0.0015)\n\n", total,
157
         meets(total, 0.0015));
158
 
159
  /* test for 0 input giving 0 output */
160
  memset(testout, 0, sizeof(DCTELEM)*DCTSIZE2);
161
  j_rev_dct(testout);
162
  for (i = 0, j=0; i < DCTSIZE2; i++) {
163
    if (testout[i]) {
164
      printf("Position %d of IDCT(0) = %d (FAILS)\n", i, testout[i]);
165
      j++;
166
    }
167
  }
168
  printf("%d elements of IDCT(0) were not zero\n\n\n", j);
169
 
170
  exit(0);
171
  return 0;
172
}
173
 
174
 
175
void usage (char *msg)
176
{
177
  if (msg != NULL)
178
    fprintf(stderr, "\nerror: %s\n", msg);
179
 
180
  fprintf(stderr, "\n");
181
  fprintf(stderr, "usage: ieeetest minpix maxpix sign niters\n");
182
  fprintf(stderr, "\n");
183
  fprintf(stderr, "  minpix = -L value per IEEE spec\n");
184
  fprintf(stderr, "  maxpix =  H value per IEEE spec\n");
185
  fprintf(stderr, "  sign = +1 for normal, -1 to run negated test\n");
186
  fprintf(stderr, "  niters = # iterations (10000 for full test)\n");
187
  fprintf(stderr, "\n");
188
 
189
  exit(1);
190
}
191
 
192
 
193
/* Pseudo-random generator specified by IEEE 1180 */
194
 
195
long ieeerand (long L, long H)
196
{
197
  static long randx = 1;
198
  static double z = (double) 0x7fffffff;
199
 
200
  long i,j;
201
  double x;
202
 
203
  randx = (randx * 1103515245) + 12345;
204
  i = randx & 0x7ffffffe;
205
  x = ((double) i) / z;
206
  x *= (L+H+1);
207
  j = x;
208
  return j-L;
209
}
210
 
211
 
212
/* Reference double-precision FDCT and IDCT */
213
 
214
 
215
/* The cosine lookup table */
216
/* coslu[a][b] = C(b)/2 * cos[(2a+1)b*pi/16] */
217
double coslu[8][8];
218
 
219
 
220
/* Routine to initialise the cosine lookup table */
221
void dct_init(void)
222
{
223
  int a,b;
224
  double tmp;
225
 
226
  for(a=0;a<8;a++)
227
    for(b=0;b<8;b++) {
228
      tmp = cos((double)((a+a+1)*b) * (3.14159265358979323846 / 16.0));
229
      if(b==0)
230
        tmp /= sqrt(2.0);
231
      coslu[a][b] = tmp * 0.5;
232
    }
233
}
234
 
235
 
236
void ref_fdct (DCTELEM block[8][8])
237
{
238
  int x,y,u,v;
239
  double tmp, tmp2;
240
  double res[8][8];
241
 
242
  for (v=0; v<8; v++) {
243
    for (u=0; u<8; u++) {
244
      tmp = 0.0;
245
      for (y=0; y<8; y++) {
246
        tmp2 = 0.0;
247
        for (x=0; x<8; x++) {
248
          tmp2 += (double) block[y][x] * coslu[x][u];
249
        }
250
        tmp += coslu[y][v] * tmp2;
251
      }
252
      res[v][u] = tmp;
253
    }
254
  }
255
 
256
  for (v=0; v<8; v++) {
257
    for (u=0; u<8; u++) {
258
      tmp = res[v][u];
259
      if (tmp < 0.0) {
260
        x = - ((int) (0.5 - tmp));
261
      } else {
262
        x = (int) (tmp + 0.5);
263
      }
264
      block[v][u] = (DCTELEM) x;
265
    }
266
  }
267
}
268
 
269
 
270
void ref_idct (DCTELEM block[8][8])
271
{
272
  int x,y,u,v;
273
  double tmp, tmp2;
274
  double res[8][8];
275
 
276
  for (y=0; y<8; y++) {
277
    for (x=0; x<8; x++) {
278
      tmp = 0.0;
279
      for (v=0; v<8; v++) {
280
        tmp2 = 0.0;
281
        for (u=0; u<8; u++) {
282
          tmp2 += (double) block[v][u] * coslu[x][u];
283
        }
284
        tmp += coslu[y][v] * tmp2;
285
      }
286
      res[y][x] = tmp;
287
    }
288
  }
289
 
290
  for (v=0; v<8; v++) {
291
    for (u=0; u<8; u++) {
292
      tmp = res[v][u];
293
      if (tmp < 0.0) {
294
        x = - ((int) (0.5 - tmp));
295
      } else {
296
        x = (int) (tmp + 0.5);
297
      }
298
      block[v][u] = (DCTELEM) x;
299
    }
300
  }
301
}

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.