File Coverage

DCT.xs
Criterion Covered Total %
statement 172 178 96.6
branch 62 68 91.1
condition n/a
subroutine n/a
pod n/a
total 234 246 95.1


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #ifndef M_PI
6             #define M_PI 3.14159265358979323846
7             #endif
8              
9             void transform_recursive(double input[], double temp[], int size, double coef[]);
10              
11 34           void fct8_1d(char *inbuf) {
12 34           double *vector = (double *) inbuf;
13              
14 34           const double v0 = vector[0] + vector[7];
15 34           const double v1 = vector[1] + vector[6];
16 34           const double v2 = vector[2] + vector[5];
17 34           const double v3 = vector[3] + vector[4];
18 34           const double v4 = vector[3] - vector[4];
19 34           const double v5 = vector[2] - vector[5];
20 34           const double v6 = vector[1] - vector[6];
21 34           const double v7 = vector[0] - vector[7];
22              
23 34           const double v8 = v0 + v3;
24 34           const double v9 = v1 + v2;
25 34           const double v10 = v1 - v2;
26 34           const double v11 = v0 - v3;
27 34           const double v12 = -v4 - v5;
28 34           const double v13 = (v5 + v6) * 0.707106781186547524400844;
29 34           const double v14 = v6 + v7;
30              
31 34           const double v15 = v8 + v9;
32 34           const double v16 = v8 - v9;
33 34           const double v17 = (v10 + v11) * 0.707106781186547524400844;
34 34           const double v18 = (v12 + v14) * 0.382683432365089771728460;
35              
36 34           const double v19 = -v12 * 0.541196100146196984399723 - v18;
37 34           const double v20 = v14 * 1.306562964876376527856643 - v18;
38              
39 34           const double v21 = v17 + v11;
40 34           const double v22 = v11 - v17;
41 34           const double v23 = v13 + v7;
42 34           const double v24 = v7 - v13;
43              
44 34           const double v25 = v19 + v24;
45 34           const double v26 = v23 + v20;
46 34           const double v27 = v23 - v20;
47 34           const double v28 = v24 - v19;
48              
49 34           vector[0] = v15;
50 34           vector[1] = 0.509795579104157595 * v26;
51 34           vector[2] = 0.54119610014619577 * v21;
52 34           vector[3] = 0.60134488693504412 * v28;
53 34           vector[4] = 0.707106781186547 * v16;
54 34           vector[5] = 0.8999762231364133 * v25;
55 34           vector[6] = 1.30656296487637502 * v22;
56 34           vector[7] = 2.5629154477415022505 * v27;
57 34           }
58              
59 2           void fct8_2d(
60             char *inbuf)
61             {
62 2           double *input = (double *) inbuf;
63             double temp[64];
64             int x,y;
65              
66 18 100         for (x = 0; x < 64; x+=8) {
67 16           fct8_1d((char *)&input[x]);
68             }
69              
70 18 100         for (x = 0; x < 8; x++) {
71 144 100         for (y = 0; y < 8; y++) {
72 128           temp[y*8+x]=input[x*8+y];
73             }
74             }
75              
76 18 100         for (y = 0; y < 64; y+=8) {
77 16           fct8_1d((char *)&temp[y]);
78             }
79              
80 18 100         for (x = 0; x < 8; x++) {
81 144 100         for (y = 0; y < 8; y++) {
82 128           input[y*8+x]=temp[x*8+y];
83             }
84             }
85 2           }
86              
87 4           void dct_1d(
88             char *inbuf,
89             int size)
90 4           {
91 4           double *input = (double *) inbuf;
92 4           double temp[size];
93 4           double factor = M_PI/size;
94              
95             int i,j;
96 32 100         for(i = 0; i < size; ++i) {
97 28           double sum = 0;
98 288 100         for(j = 0; j < size; ++j) {
99 260           sum += input[j] * cos((j+0.5)*i*factor);
100             }
101 28           temp[i]=sum;
102             }
103              
104 32 100         for(i = 0; i < size; ++i) {
105 28           input[i]=temp[i];
106             }
107 4           }
108              
109 4           void dct_coef(int size, double coef[size][size]) {
110 4           double factor = M_PI/size;
111              
112             int i, j;
113 32 100         for (i = 0; i < size; i++) {
114 288 100         for (j = 0; j < size; j++) {
115 260           coef[j][i] = cos((j+0.5)*i*factor);
116             }
117             }
118 4           }
119              
120 4           void dct_2d(
121             char *inbuf,
122             int size)
123 4           {
124 4           double *input = (double *) inbuf;
125 4           double coef[size][size];
126 4           double temp[size*size];
127             int x, y, i, j;
128              
129 4           dct_coef(size, coef);
130              
131 32 100         for (x = 0; x < size; x++) {
132 288 100         for (i = 0; i < size; i++) {
133 260           double sum = 0;
134 2976 100         for (j = 0; j < size; j++) {
135 2716           sum += input[x*size+j] * coef[j][i];
136             }
137 260           temp[x*size+i] = sum;
138             }
139             }
140              
141 32 100         for (y = 0; y < size; y++) {
142 288 100         for (i = 0; i < size; i++) {
143 260           double sum = 0;
144 2976 100         for (j = 0; j < size; j++) {
145 2716           sum += temp[j*size+y] * coef[j][i];
146             }
147 260           input[i*size+y] = sum;
148             }
149             }
150 4           }
151              
152 420           void fast_dct_1d_precalc(
153             char *inbuf,
154             int size,
155             double coef[])
156 420           {
157 420           double *input = (double *) inbuf;
158 420           double temp[size];
159              
160 420           transform_recursive(input, temp, size, coef);
161 420           }
162              
163 18           void fast_dct_coef(int size, double coef[size]) {
164              
165             int i, j;
166 77 100         for (i = 1; i <= size/2; i*=2) {
167 59           double factor = M_PI/(i*2);
168 456 100         for (j = 0; j < i; j++) {
169 397           coef[i+j] = cos((j+0.5)*factor)*2;
170             }
171             }
172 18           }
173              
174 8           void fast_dct_1d(
175             char *inbuf,
176             int size)
177 8           {
178 8           double coef[size];
179              
180 8           fast_dct_coef(size, coef);
181              
182 8           fast_dct_1d_precalc(inbuf, size, coef);
183 8           }
184              
185 10           void fast_dct_2d(
186             char *inbuf,
187             int size)
188 10           {
189 10           double *input = (double *) inbuf;
190 10           double coef[size];
191 10           double temp[size*size];
192             int x,y;
193              
194 10           fast_dct_coef(size, coef);
195              
196 216 100         for (x = 0; x < size*size; x+=size) {
197 206           fast_dct_1d_precalc((char *)&input[x], size, coef);
198             }
199              
200 216 100         for (x = 0; x < size; x++) {
201 10490 100         for (y = 0; y < size; y++) {
202 10284           temp[y*size+x]=input[x*size+y];
203             }
204             }
205              
206 216 100         for (y = 0; y < size*size; y+=size) {
207 206           fast_dct_1d_precalc((char *)&temp[y], size, coef);
208             }
209              
210 216 100         for (x = 0; x < size; x++) {
211 10490 100         for (y = 0; y < size; y++) {
212 10284           input[y*size+x]=temp[x*size+y];
213             }
214             }
215 10           }
216              
217 41132           void transform_recursive(double input[], double temp[], int size, double coef[]) {
218 41132 100         if (size == 1)
219 20776           return;
220              
221             int i;
222 20356           int half = size / 2;
223              
224 80384 100         for (i = 0; i < half; i++) {
225 60028           double x = input[i];
226 60028           double y = input[size-1-i];
227 60028           temp[i] = x+y;
228 60028           temp[i+half] = (x-y)/coef[half+i];
229             }
230              
231 20356           transform_recursive(temp, input, half, coef);
232 20356           transform_recursive(&temp[half], input, half, coef);
233              
234 60028 100         for (i = 0; i < half-1; i++) {
235 39672           input[i*2+0] = temp[i];
236 39672           input[i*2+1] = temp[i+half] + temp[i+half+1];
237             }
238 20356           input[size-2] = temp[half-1];
239 20356           input[size-1] = temp[size-1];
240             }
241              
242              
243             MODULE = Math::DCT PACKAGE = Math::DCT
244              
245             PROTOTYPES: DISABLE
246              
247              
248             void
249             fct8_1d (inbuf)
250             char * inbuf
251             PREINIT:
252             I32* temp;
253             PPCODE:
254 2           temp = PL_markstack_ptr++;
255 2           fct8_1d(inbuf);
256 2 50         if (PL_markstack_ptr != temp) {
257             /* truly void, because dXSARGS not invoked */
258 2           PL_markstack_ptr = temp;
259 2           XSRETURN_EMPTY; /* return empty stack */
260             }
261             /* must have used dXSARGS; list context implied */
262 0           return; /* assume stack size is correct */
263              
264             void
265             fct8_2d (inbuf)
266             char * inbuf
267             PREINIT:
268             I32* temp;
269             PPCODE:
270 2           temp = PL_markstack_ptr++;
271 2           fct8_2d(inbuf);
272 2 50         if (PL_markstack_ptr != temp) {
273             /* truly void, because dXSARGS not invoked */
274 2           PL_markstack_ptr = temp;
275 2           XSRETURN_EMPTY; /* return empty stack */
276             }
277             /* must have used dXSARGS; list context implied */
278 0           return; /* assume stack size is correct */
279              
280             void
281             dct_1d (inbuf, size)
282             char * inbuf
283             int size
284             PREINIT:
285             I32* temp;
286             PPCODE:
287 4           temp = PL_markstack_ptr++;
288 4           dct_1d(inbuf, size);
289 4 50         if (PL_markstack_ptr != temp) {
290             /* truly void, because dXSARGS not invoked */
291 4           PL_markstack_ptr = temp;
292 4           XSRETURN_EMPTY; /* return empty stack */
293             }
294             /* must have used dXSARGS; list context implied */
295 0           return; /* assume stack size is correct */
296              
297             void
298             dct_2d (inbuf, size)
299             char * inbuf
300             int size
301             PREINIT:
302             I32* temp;
303             PPCODE:
304 4           temp = PL_markstack_ptr++;
305 4           dct_2d(inbuf, size);
306 4 50         if (PL_markstack_ptr != temp) {
307             /* truly void, because dXSARGS not invoked */
308 4           PL_markstack_ptr = temp;
309 4           XSRETURN_EMPTY; /* return empty stack */
310             }
311             /* must have used dXSARGS; list context implied */
312 0           return; /* assume stack size is correct */
313              
314             void
315             fast_dct_1d (inbuf, size)
316             char * inbuf
317             int size
318             PREINIT:
319             I32* temp;
320             PPCODE:
321 8           temp = PL_markstack_ptr++;
322 8           fast_dct_1d(inbuf, size);
323 8 50         if (PL_markstack_ptr != temp) {
324             /* truly void, because dXSARGS not invoked */
325 8           PL_markstack_ptr = temp;
326 8           XSRETURN_EMPTY; /* return empty stack */
327             }
328             /* must have used dXSARGS; list context implied */
329 0           return; /* assume stack size is correct */
330              
331             void
332             fast_dct_2d (inbuf, size)
333             char * inbuf
334             int size
335             PREINIT:
336             I32* temp;
337             PPCODE:
338 10           temp = PL_markstack_ptr++;
339 10           fast_dct_2d(inbuf, size);
340 10 50         if (PL_markstack_ptr != temp) {
341             /* truly void, because dXSARGS not invoked */
342 10           PL_markstack_ptr = temp;
343 10           XSRETURN_EMPTY; /* return empty stack */
344             }
345             /* must have used dXSARGS; list context implied */
346 0           return; /* assume stack size is correct */
347