1 /*
2
3 TestImageFilter.c: test program for MMX filter routines
4
5 (C) A. Schiffler, 2006, zlib license
6 (C) Sylvain Beucler, 2013, zlib license
7
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14
15 #include "SDL.h"
16
17 #ifdef WIN32
18 #include <windows.h>
19 #include "SDL_imageFilter.h"
20 #ifndef bcmp
21 #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
22 #endif
23 #else
24 #include "SDL/SDL_imageFilter.h"
25 #endif
26
27 #define SRC_SIZE 23
28
29 int total_count = 0;
30 int ok_count = 0;
31
setup_src(unsigned char * src1,unsigned char * src2)32 void setup_src(unsigned char *src1, unsigned char *src2)
33 {
34 int i;
35
36 src1[0]=1;
37 src1[2]=1;
38 src1[1]=4;
39 src1[3]=3;
40 src1[4]=33;
41 for (i=5; i<14; i++) src1[i]=i;
42 src1[14]=8;
43 for (i=15; i<SRC_SIZE; i++) src1[i]=rand();
44
45 src2[0]=1;
46 src2[1]=3;
47 src2[2]=3;
48 src2[3]=2;
49 src2[4]=44;
50 for (i=5; i<14; i++) src2[i]=14-i;
51 src2[14]=10;
52 for (i=15; i<SRC_SIZE; i++) src2[i]=src1[i];
53 }
54
print_result(int mmx,char * label,unsigned char * src1,unsigned char * src2,unsigned char * dst)55 void print_result(int mmx, char *label, unsigned char *src1, unsigned char *src2, unsigned char *dst)
56 {
57 char blabel[80];
58 int i;
59 memset((void *)blabel, ' ', 80);
60 blabel[strlen(label)+4]=0;
61
62 printf("\n");
63 printf ("%s pos ", blabel);
64 for (i = 0; i < SRC_SIZE; i++)
65 printf("%2d ", i);
66 printf("\n");
67
68 printf ("%s src1 ", blabel);
69 for (i = 0; i < SRC_SIZE; i++)
70 printf("%02x ", src1[i]);
71 printf("\n");
72
73 if (src2) {
74 printf ("%s src2 ", blabel);
75 for (i = 0; i < SRC_SIZE; i++)
76 printf("%02x ", src2[i]);
77 }
78 printf("\n");
79
80 printf ("%s %s dest ",mmx?"MMX":" C ",label);
81 for (i = 0; i < SRC_SIZE; i++)
82 printf("%02x ", dst[i]);
83 printf("\n");
84 }
85
print_compare(unsigned char * dst1,unsigned char * dst2)86 void print_compare(unsigned char *dst1, unsigned char *dst2)
87 {
88 total_count++;
89 if (bcmp(dst1,dst2,SRC_SIZE)==0) {
90 printf ("OK\n");
91 ok_count++;
92 } else {
93 printf ("ERROR\n");
94 }
95 }
96
print_line()97 void print_line()
98 {
99 printf ("------------------------------------------------------------------------\n\n\n");
100 }
101
pause()102 void pause()
103 {
104 char ch;
105 do {
106 ch = getchar();
107 putchar('.');
108 } while (ch != '\n');
109 }
110
111 /* ----------- main ---------- */
112
main(int argc,char * argv[])113 int main(int argc, char *argv[])
114 {
115 unsigned char src1[SRC_SIZE], src2[SRC_SIZE], dstm[SRC_SIZE], dstc[SRC_SIZE];
116 int size = 2*1024*1024;
117 unsigned char *t1 = (unsigned char *)malloc(size), *t2 = (unsigned char *)malloc(size), *d = (unsigned char *)malloc(size);
118 int i;
119
120 // Interestingly, C tests are about 4x faster
121 // on malloc(size) than on char[size]
122
123 printf("src1:\t%s (%p)\tsrc2:\t%s (%p)\tdstm:\t%s (%p)\tdstc:\t%s (%p)\n",
124 ((long long)src1%8) ? "not aligned" : "aligned", src1,
125 ((long long)src2%8) ? "not aligned" : "aligned", src2,
126 ((long long)dstm%8) ? "not aligned" : "aligned", dstm,
127 ((long long)dstc%8) ? "not aligned" : "aligned", dstc);
128
129 printf("t1:\t%s (%p)\tt2:\t%s (%p)\td:\t%s (%p)\n",
130 ((long long)t1%8) ? "not aligned" : "aligned", t1,
131 ((long long)t2%8) ? "not aligned" : "aligned", t2,
132 ((long long) d%8) ? "not aligned" : "aligned", d);
133
134 {
135 /* Initialize to make valgrind happy */
136 srand((unsigned int)time(NULL));
137 for (i = 0; i < size; i++) {
138 /* use more random lower-order bits (int->char) */
139 t1[i] = rand(); t2[i] = rand(); d[i] = rand();
140 }
141 }
142
143 SDL_Init(SDL_INIT_TIMER);
144
145 /* SDL_imageFilter Test */
146
147 printf ("TestImageFilter\n\n");
148 printf ("Testing an array of 23 bytes - first 16 bytes should be processed\n");
149 printf ("by MMX or C code, the last 7 bytes only by C code.\n\n");
150
151 print_line();
152
153
154 #define TEST_C 0
155 #define TEST_MMX 1
156 {
157 #define FUNC(f) { #f, SDL_imageFilter ## f }
158 struct func {
159 char* name;
160 int (*f)(unsigned char*, unsigned char*, unsigned char*, unsigned int);
161 };
162 struct func funcs[] = {
163 FUNC(BitAnd),
164 FUNC(BitOr),
165 FUNC(Add),
166 FUNC(AbsDiff),
167 FUNC(Mean),
168 FUNC(Sub),
169 FUNC(Mult),
170 FUNC(MultNor),
171 FUNC(MultDivby2),
172 FUNC(MultDivby4),
173 FUNC(Div),
174 };
175
176 int k;
177 for (k = 0; k < sizeof(funcs)/sizeof(struct func); k++) {
178 Uint32 start;
179 int i;
180
181 setup_src(src1, src2);
182
183 SDL_imageFilterMMXon();
184 funcs[k].f(src1, src2, dstm, SRC_SIZE);
185 print_result(TEST_MMX, funcs[k].name, src1, src2, dstm);
186 start = SDL_GetTicks();
187 for (i = 0; i < 50; i++) {
188 funcs[k].f(t1, t2, d, size);
189 }
190 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
191
192 SDL_imageFilterMMXoff();
193 funcs[k].f(src1, src2, dstc, SRC_SIZE);
194 print_result(TEST_C, funcs[k].name, src1, src2, dstc);
195 start = SDL_GetTicks();
196 for (i = 0; i < 50; i++) {
197 funcs[k].f(t1, t2, d, size);
198 }
199 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
200
201 print_compare(dstm,dstc);
202 print_line();
203 }
204 }
205
206 {
207 Uint32 start;
208 int i;
209 char call[1024];
210 sprintf(call, "BitNegation");
211
212 setup_src(src1, src2);
213
214 SDL_imageFilterMMXon();
215 SDL_imageFilterBitNegation(src1, dstm, SRC_SIZE);
216 print_result(TEST_MMX, call, src1, NULL, dstm);
217 start = SDL_GetTicks();
218 for (i = 0; i < 50; i++) {
219 SDL_imageFilterBitNegation(t1, d, size);
220 }
221 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
222
223 SDL_imageFilterMMXoff();
224 SDL_imageFilterBitNegation(src1, dstc, SRC_SIZE);
225 print_result(TEST_C, call, src1, NULL, dstc);
226 start = SDL_GetTicks();
227 for (i = 0; i < 50; i++) {
228 SDL_imageFilterBitNegation(t1, d, size);
229 }
230 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
231
232 print_compare(dstm,dstc);
233 print_line();
234 }
235
236
237 {
238 #undef FUNC
239 #define FUNC(f, c) { #f, SDL_imageFilter ## f, c }
240 struct func {
241 char* name;
242 int (*f)(unsigned char*, unsigned char*, unsigned int, unsigned char);
243 unsigned char arg;
244 };
245 struct func funcs[] = {
246 FUNC(AddByte, 3),
247 FUNC(AddByteToHalf, 3),
248 FUNC(SubByte, 3),
249 FUNC(ShiftRight, 1),
250 FUNC(ShiftRightUint, 4),
251 FUNC(MultByByte, 3),
252 FUNC(ShiftLeftByte, 3),
253 FUNC(ShiftLeft, 3),
254 FUNC(ShiftLeftUint, 4),
255 FUNC(BinarizeUsingThreshold, 9),
256 };
257
258 int k;
259 for (k = 0; k < sizeof(funcs)/sizeof(struct func); k++) {
260 Uint32 start;
261 int i;
262 char call[1024];
263 sprintf(call, "%s(%u)", funcs[k].name, funcs[k].arg);
264
265 setup_src(src1, src2);
266
267 SDL_imageFilterMMXon();
268 funcs[k].f(src1, dstm, SRC_SIZE, funcs[k].arg);
269 print_result(TEST_MMX, call, src1, NULL, dstm);
270 start = SDL_GetTicks();
271 for (i = 0; i < 50; i++) {
272 funcs[k].f(t1, d, size, funcs[k].arg);
273 }
274 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
275
276 SDL_imageFilterMMXoff();
277 funcs[k].f(src1, dstc, SRC_SIZE, funcs[k].arg);
278 print_result(TEST_C, call, src1, NULL, dstc);
279 start = SDL_GetTicks();
280 for (i = 0; i < 50; i++) {
281 funcs[k].f(t1, d, size, funcs[k].arg);
282 }
283 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
284
285 print_compare(dstm,dstc);
286 print_line();
287 }
288 }
289
290
291 {
292 #undef FUNC
293 #define FUNC(f, c1, c2) { #f, SDL_imageFilter ## f, c1, c2 }
294 struct func {
295 char* name;
296 int (*f)(unsigned char*, unsigned char*, unsigned int, unsigned char, unsigned char);
297 unsigned char arg1, arg2;
298 };
299 struct func funcs[] = {
300 FUNC(ShiftRightAndMultByByte, 1, 3),
301 FUNC(ClipToRange, 3, 8),
302 };
303
304 int k;
305 for (k = 0; k < sizeof(funcs)/sizeof(struct func); k++) {
306 Uint32 start;
307 int i;
308 char call[1024];
309 sprintf(call, "%s(%u,%u)", funcs[k].name, funcs[k].arg1, funcs[k].arg2);
310
311 setup_src(src1, src2);
312
313 SDL_imageFilterMMXon();
314 funcs[k].f(src1, dstm, SRC_SIZE, funcs[k].arg1, funcs[k].arg2);
315 print_result(TEST_MMX, call, src1, NULL, dstm);
316 start = SDL_GetTicks();
317 for (i = 0; i < 50; i++) {
318 funcs[k].f(t1, d, size, funcs[k].arg1, funcs[k].arg2);
319 }
320 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
321
322 SDL_imageFilterMMXoff();
323 funcs[k].f(src1, dstc, SRC_SIZE, funcs[k].arg1, funcs[k].arg2);
324 print_result(TEST_C, call, src1, NULL, dstc);
325 start = SDL_GetTicks();
326 for (i = 0; i < 50; i++) {
327 funcs[k].f(t1, d, size, funcs[k].arg1, funcs[k].arg2);
328 }
329 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
330
331 print_compare(dstm,dstc);
332 print_line();
333 }
334 }
335
336
337 {
338 Uint32 start;
339 int i;
340 char call[1024];
341 sprintf(call, "NormalizeLinear(0,33,0,255)");
342
343 setup_src(src1, src2);
344
345 SDL_imageFilterMMXon();
346 SDL_imageFilterNormalizeLinear(src1, dstm, SRC_SIZE, 0,33, 0,255);
347 print_result(TEST_MMX, call, src1, NULL, dstm);
348 start = SDL_GetTicks();
349 for (i = 0; i < 50; i++) {
350 SDL_imageFilterNormalizeLinear(t1, d, size, 0,33, 0,255);
351 }
352 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
353
354 SDL_imageFilterMMXoff();
355 SDL_imageFilterNormalizeLinear(src1, dstc, SRC_SIZE, 0,33, 0,255);
356 print_result(TEST_C, call, src1, NULL, dstc);
357 start = SDL_GetTicks();
358 for (i = 0; i < 50; i++) {
359 SDL_imageFilterNormalizeLinear(t1, d, size, 0,33, 0,255);
360 }
361 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
362
363 print_compare(dstm,dstc);
364 print_line();
365 }
366
367
368 /* Uint functions */
369 /* Disabled, since broken *//* ??? */
370 {
371 #undef FUNC
372 #define FUNC(f, c) { #f, SDL_imageFilter ## f, c }
373 struct func {
374 char* name;
375 int (*f)(unsigned char*, unsigned char*, unsigned int, unsigned int);
376 unsigned int arg;
377 };
378 struct func funcs[] = {
379 FUNC(AddUint, 0x01020304),
380 FUNC(SubUint, 0x01020304),
381 };
382
383 int k;
384 for (k = 0; k < sizeof(funcs)/sizeof(struct func); k++) {
385 Uint32 start;
386 int i;
387 char call[1024];
388 sprintf(call, "%s(%u)", funcs[k].name, funcs[k].arg);
389
390 setup_src(src1, src2);
391
392 SDL_imageFilterMMXon();
393 funcs[k].f(src1, dstm, SRC_SIZE, funcs[k].arg);
394 print_result(TEST_MMX, call, src1, NULL, dstm);
395 start = SDL_GetTicks();
396 for (i = 0; i < 50; i++) {
397 funcs[k].f(t1, d, size, funcs[k].arg);
398 }
399 printf("MMX %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
400
401 SDL_imageFilterMMXoff();
402 funcs[k].f(src1, dstc, SRC_SIZE, funcs[k].arg);
403 print_result(TEST_C, call, src1, NULL, dstc);
404 start = SDL_GetTicks();
405 for (i = 0; i < 50; i++) {
406 funcs[k].f(t1, d, size, funcs[k].arg);
407 }
408 printf(" C %dx%dk: %dms\n", i, size/1024, SDL_GetTicks() - start);
409
410 print_compare(dstm,dstc);
411 print_line();
412 }
413 }
414
415
416 SDL_imageFilterMMXon();
417 if (SDL_imageFilterMMXdetect())
418 {
419 printf("MMX was detected\n\n");
420 }
421 else
422 {
423 printf("MMX was NOT detected\n\n");
424 }
425
426 printf ("Result: %i of %i passed OK.\n", ok_count, total_count);
427
428 #ifdef WIN32
429 printf("Press Enter to continue ...");
430 pause();
431 #endif
432
433 SDL_Quit();
434 free(d);
435 free(t2);
436 free(t1);
437 exit(0);
438 }
439