Remove the "** FIXME: THIS DOES NOT ACTUALLY WORK YET" lines.
[synfig.git] / ETL / trunk / test / pen.cpp
1 /*! ========================================================================
2 ** Extended Template and Library Test Suite
3 ** Handle Template Class Test
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
12 **
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #include <list>
25 #include <cstdio>
26 #include <cstdlib>
27 #include <string>
28 #include <utility>
29 #include <memory>
30 #include <map>
31 #include <ETL/pen>
32 #include <ETL/boxblur>
33 //#include <ETL/gaussian>
34 #include <math.h>
35
36 /* === M A C R O S ========================================================= */
37
38 using namespace std;
39 using namespace etl;
40
41 #define DEBUGPOINT()    fprintf(stderr,__FILE__":%d: Debugpoint\n",__LINE__)
42
43 /* === C L A S S E S ======================================================= */
44
45 int generic_pen_test(int w, int h)
46 {
47         printf("generic_pen(w:%d,h:%d): ",w,h);
48
49         auto_ptr<float> data(new float[w*h]);
50         if(!data.get())
51         {
52                 printf("Um..... malloc failure on line %d of "__FILE__"...\n",__LINE__);
53                 abort();
54         }
55
56         generic_pen<float> pen(data.get(),w,h);
57         generic_pen<float> pen2;
58
59         if(!pen)
60         {
61                 printf("FAILURE! "__FILE__"@%d: On pen bool test\n",__LINE__);
62                 return 1;
63         }
64
65         if(&pen.x()[2]!=&pen[0][2])
66         {
67                 printf("FAILURE! "__FILE__"@%d: On request for horizontal iterator\n",__LINE__);
68                 return 1;
69         }
70
71         if(&pen.y()[2]!=&pen[2][0])
72         {
73                 printf("FAILURE! "__FILE__"@%d: On request for vertical iterator\n",__LINE__);
74                 return 1;
75         }
76
77         pen.move(1,1);
78         pen2=pen;
79
80         if(pen!=pen2)
81         {
82                 printf("FAILURE! "__FILE__"@%d: On pen assignment or pen comparison\n",__LINE__);
83                 return 1;
84         }
85
86         pen2.move(w,h);
87         generic_pen<float>::difference_type diff(pen2-pen);
88
89         if(diff.x!=w || diff.y!=h)
90         {
91                 printf("FAILURE! "__FILE__"@%d: pen difference inconsistency ([%d,%d]!=[%d,%d])\n",__LINE__,diff.x,diff.y,w,h);
92                 return 1;
93         }
94
95         if(pen.end_x()-pen.x()!=w-1)
96         {
97                 printf("FAILURE! "__FILE__"@%d: iterator_x inconsistency (%d!=%d)\n",__LINE__,pen.end_x()-pen.x(),w);
98                 return 1;
99         }
100
101         if(pen.end_y()-pen.y()!=h-1)
102         {
103                 printf("FAILURE! "__FILE__"@%d: iterator_y inconsistency (%d!=%d)\n",__LINE__,pen.end_y()-pen.y(),h);
104                 return 1;
105         }
106
107         if(&pen.end_y()[-1]!=&pen.y()[(h-2)])
108         {
109                 printf("FAILURE! "__FILE__"@%d: iterator_y inconsistency\n",__LINE__);
110                 return 1;
111         }
112
113         if(&pen.end_x()[-1]!=&pen.x()[(w-2)])
114         {
115                 printf("FAILURE! "__FILE__"@%d: iterator_x inconsistency\n",__LINE__);
116                 return 1;
117         }
118
119         printf("PASSED\n");
120
121         return 0;
122 }
123
124 int alpha_pen_test(void)
125 {
126         printf("alpha_pen: ");
127         printf("SKIPPED\n");
128
129         return 0;
130 }
131
132 int bbox_pen_test(void)
133 {
134         printf("bbox_pen: ");
135
136
137
138         printf("SKIPPED\n");
139
140         return 0;
141 }
142
143 int display_pen(generic_pen<float> pen, int w, int h)
144 {
145         int ret=0;
146         int x, y;
147         // print out the after pic
148         for(y=0;y<h;y++,pen.inc_y())
149         {
150                 printf("|");
151                 for(x=0;x<w;x++,pen.inc_x())
152                 {
153                         if(pen.get_value()>=2.0f)
154                                 printf("#");
155                         else if(pen.get_value()>=1.0f)
156                                 printf("@");
157                         else if(pen.get_value()>=0.8f)
158                                 printf("%%");
159                         else if(pen.get_value()>=0.6f)
160                                 printf("O");
161                         else if(pen.get_value()>=0.4f)
162                                 printf(":");
163                         else if(pen.get_value()>=0.2f)
164                                 printf(".");
165                         else if(pen.get_value()>=-0.0001f)
166                                 printf(" ");
167                         else
168                                 printf("X"),ret++;
169                 }
170                 pen.dec_x(x);
171                 printf("|\n");
172         }
173         pen.dec_y(y);
174         return ret;
175 }
176
177 int display_pen(generic_pen<double> pen, int w, int h)
178 {
179         int ret=0;
180         int x, y;
181         // print out the after pic
182         for(y=0;y<h;y++,pen.inc_y())
183         {
184                 printf("|");
185                 for(x=0;x<w;x++,pen.inc_x())
186                 {
187                         if(pen.get_value()>=2.0f)
188                                 printf("#");
189                         else if(pen.get_value()>=1.0f)
190                                 printf("@");
191                         else if(pen.get_value()>=0.8f)
192                                 printf("%%");
193                         else if(pen.get_value()>=0.6f)
194                                 printf("O");
195                         else if(pen.get_value()>=0.4f)
196                                 printf(":");
197                         else if(pen.get_value()>=0.2f)
198                                 printf(".");
199                         else if(pen.get_value()>=-0.0001f)
200                                 printf(" ");
201                         else
202                                 printf("X"),ret++;
203                 }
204                 pen.dec_x(x);
205                 printf("|\n");
206         }
207         pen.dec_y(y);
208         return ret;
209 }
210
211 void emptyfunction(int v)
212 {
213         static int stupid = 0;
214         stupid = v;
215         //printf("Called... %d\n",v);
216 }
217
218 int box_blur_test(void)
219 {
220         typedef float boxblur_float;
221
222         printf("box_blur: ");
223
224         int w=25,h=25;
225
226         auto_ptr<boxblur_float> data(new boxblur_float[w*h]);
227         auto_ptr<boxblur_float> data2(new boxblur_float[w*h]);
228         if(!data.get())
229         {
230                 printf("Um..... malloc failure on line %d of "__FILE__"...\n",__LINE__);
231                 abort();
232         }
233
234         generic_pen<boxblur_float> pen(data.get(),w,h);
235         generic_pen<boxblur_float> pen2;
236
237         generic_pen<boxblur_float> pen3(data2.get(),w,h);
238         int x,y;
239
240         for(y=0;y<h;y++,pen.inc_y())
241         {
242                 for(x=0;x<w;x++,pen.inc_x())
243                 {
244                         if(x-y<=1 && y-x<=1 || y==h/2 || x==w/2)
245                                 pen.put_value(2);
246                         else
247                                 pen.put_value(0);
248                 }
249                 pen.dec_x(x);
250         }
251         pen.dec_y(y);
252
253         int bad_values=0;
254
255         printf("\nBEFORE BOX BLUR:\n");
256
257         // print out the before pic
258         display_pen(pen,w,h);
259
260         // Pen 2 will be the end
261         pen2=pen;
262         pen2.move(w,h);
263
264         //temporary
265         vbox_blur(pen,pen2,2,pen3);
266         printf("\n VBLUR ONLY:\n");
267         display_pen(pen3,w,h);
268
269 //      box_blur(pen,w,h,4);
270         hbox_blur(pen,pen2,2,pen3);
271
272         printf("\n HBLUR ONLY:\n");
273         display_pen(pen3,w,h);
274
275         pen2=pen3;
276         pen2.move(w,h);
277         vbox_blur(pen3,pen2,2,pen);
278
279         printf("\nAFTER BOX BLUR:\n");
280
281         // print out the after pic
282         bad_values=display_pen(pen,w,h);
283
284         if(bad_values)
285         {
286                 printf("FAILURE! "__FILE__"@%d: blur result contained %d bad values\n",__LINE__,bad_values);
287                 return 1;
288         }
289
290         boxblur_float max=0;
291         printf("CHECK BOXBLUR RESULTS %d,%d:\n",pen.diff_begin().x, pen.diff_begin().y);
292         for(y=0;y<h;y++,pen.inc_y())
293         {
294                 for(x=0;x<w;x++,pen.inc_x())
295                 {
296                         boxblur_float f = 0;
297
298                         for(int oy=-2; oy <= 2; ++oy)
299                         {
300                                 int iy = y+oy;
301                                 if(iy < 0) iy = 0;
302                                 if(iy >= h) iy = h-1;
303
304                                 for(int ox=-2; ox <= 2; ++ox)
305                                 {
306                                         int ix = x+ox;
307                                         if(ix < 0) ix = 0;
308                                         if(ix >= w) ix = w-1;
309
310                                         if(ix-iy<=1 && iy-ix<=1 || iy==h/2 || ix==w/2)
311                                                 f += 2;
312                                 }
313                         }
314
315                         //print out if the relative error is high
316                         /*f /= 25;
317                         float rf = pen.get_value() - f/25;
318                         if(f && rf > 0.3)
319                         {
320                                 printf("pixel (%d,%d) off by %f\n",x,y,rf);
321                         }*/
322                         boxblur_float diff = fabs(pen.get_value() - f/25);
323                         if(diff > max) max = diff;
324                         pen.put_value(f/25); //if length = 2 then dim = 5.. area = 25
325                 }
326                 pen.dec_x(x);
327         }
328         pen.dec_y(y);
329
330         /*if(max)
331         {
332                 for(y=0;y<h;y++,pen.inc_y())
333                 {
334                         for(x=0;x<w;x++,pen.inc_x())
335                         {
336                                 pen.put_value(pen.get_value()/max);
337                         }
338                         pen.dec_x(x);
339                 }
340                 pen.dec_y(y);
341         }*/
342
343         //printf("\nHBOXBLUR ERROR (max = %e):\n",max);
344         printf("\nCorrect results:\n");
345         display_pen(pen,w,h);
346
347         printf("PASSED\n");
348
349         return 0;
350 }
351
352 /*
353 float:
354 |@@%O.     :::::          |
355 |@@@%:.    :::::          |
356 |%@@%O:.   :::::          |
357 |O%%@%O:.  :::::          |
358 |.:O%@%O:. :::::          |
359 | .:O%@%O:.:::::          |
360 |  .:O%@%O:O::::          |
361 |   .:O%@%O%O:::          |
362 |    .:O%@%@%O::          |
363 |     .:O%@@@%::          |
364 |::.:::O%@@@@@%O::::::::::|
365 |::.::::O%@@@@@%::::::::::|
366 |::.:::::OO@@@@@%O::::::::|
367 |::.:::::::%@@@@@%O:::::::|
368 |::.::::::.O%@@@@@%O::::::|
369 |          ::%@@@%O:.     |
370 |          ::O%@%@%O:.    |
371 |          :.:O%O%@%O:.   |
372 |          :.::O:O%@%O:.  |
373 |          :.:.:.:O%@%O:. |
374 |          :.:.: .:O%@%O:.|
375 |          :.:.:  .:O%@%%O|
376 |          :.:.:   .:O%@@%|
377 |          :.:.:    .:%@@@|
378 |          :.:.:     .O%@@|
379
380 double:
381 |@@%O.     .....          |
382 |@@@O:.    .....          |
383 |%@@%O:.   .....          |
384 |OO%@%O:.  .....          |
385 |.:O%@%O:. .....          |
386 | .:O%@%O:.:....          |
387 |  .:O%@%O:O:...          |
388 |   .:O%@%O%O:..          |
389 |    .:O%@%@%O:.          |
390 |     .:O%@@@O:.          |
391 |.....:O%@@@@@%O..........|
392 |......:O%@@@@@%::........|
393 |.......:OO@@@@@OO:.......|
394 |........::%@@@@@%O:......|
395 |..........O%@@@@@%O:.....|
396 |          .:O@@@%O:.     |
397 |          .:O%@%@%O:.    |
398 |          ..:O%O%@%O:.   |
399 |          ...:O:O%@%O:.  |
400 |          ....:.:O%@%O:. |
401 |          ..... .:O%@%O:.|
402 |          .....  .:O%@%OO|
403 |          .....   .:O%@@%|
404 |          .....    .:O@@@|
405 |          .....     .O%@@|
406
407
408 */
409
410 int gaussian_blur_test(void)
411 {
412         printf("gaussian_blur: ");
413 #if 0
414         int w=25,h=25;
415         int bad_values=0;
416
417         auto_ptr<float> data(new float[w*h]);
418         if(!data.get())
419         {
420                 printf("Um..... malloc failure on line %d of "__FILE__"...\n",__LINE__);
421                 abort();
422         }
423
424         generic_pen<float> pen(data.get(),w,h);
425         generic_pen<float> pen2;
426         int x,y;
427
428         for(y=0;y<h;y++,pen.inc_y())
429         {
430                 for(x=0;x<w;x++,pen.inc_x())
431                 {
432                         if((x-y<=1 && y-x<=1) || y==h/2)
433                                 pen.put_value(2);
434                         else
435                                 pen.put_value(0);
436                 }
437                 pen.dec_x(x);
438         }
439         pen.dec_y(y);
440
441         printf("\nBEFORE GAUSSIAN BLUR:\n");
442
443         // print out the before pic
444         for(y=0;y<h;y++,pen.inc_y())
445         {
446                 printf("|");
447                 for(x=0;x<w;x++,pen.inc_x())
448                 {
449                         if(pen.get_value()>=2.0f)
450                                 printf("#");
451                         else if(pen.get_value()>=1.0f)
452                                 printf("@");
453                         else if(pen.get_value()>=0.8f)
454                                 printf("%%");
455                         else if(pen.get_value()>=0.6f)
456                                 printf("O");
457                         else if(pen.get_value()>=0.4f)
458                                 printf(":");
459                         else if(pen.get_value()>=0.2f)
460                                 printf(".");
461                         else if(pen.get_value()>=0.0f)
462                                 printf(" ");
463                         else
464                                 printf("X"),bad_values++;
465                 }
466                 pen.dec_x(x);
467                 printf("|\n");
468         }
469         pen.dec_y(y);
470
471         // Pen 2 will be the end
472         pen2=pen;
473         pen2.move(w,h);
474
475 #if 0
476         gaussian_blur_5x5(pen,pen2);
477         gaussian_blur_5x5(pen,pen2);
478         gaussian_blur_5x5(pen,pen2);
479 #endif
480
481 #if 0
482         gaussian_blur_3x3(pen,pen2);
483         gaussian_blur_3x3(pen,pen2);
484         gaussian_blur_3x3(pen,pen2);
485         gaussian_blur_3x3(pen,pen2);
486         gaussian_blur_3x3(pen,pen2);
487 #endif
488
489 //      gaussian_blur(pen,pen2,15);
490         gaussian_blur(pen,pen2,10,10);
491
492         printf("\nAFTER GAUSSIAN BLUR:\n");
493
494         // print out the after pic
495         for(y=0;y<h;y++,pen.inc_y())
496         {
497                 printf("|");
498                 for(x=0;x<w;x++,pen.inc_x())
499                 {
500                         if(pen.get_value()>=2.0f)
501                                 printf("#");
502                         else if(pen.get_value()>=1.0f)
503                                 printf("@");
504                         else if(pen.get_value()>=0.8f)
505                                 printf("%%");
506                         else if(pen.get_value()>=0.6f)
507                                 printf("O");
508                         else if(pen.get_value()>=0.4f)
509                                 printf(":");
510                         else if(pen.get_value()>=0.2f)
511                                 printf(".");
512                         else if(pen.get_value()>=0.0f)
513                                 printf(" ");
514                         else
515                                 printf("X"),bad_values++;
516                 }
517                 pen.dec_x(x);
518                 printf("|\n");
519         }
520         pen.dec_y(y);
521
522         if(bad_values)
523         {
524                 printf("FAILURE! "__FILE__"@%d: blur result contained bad values\n",__LINE__);
525                 return 1;
526         }
527 #endif
528         printf("PASSED\n");
529
530         return 0;
531 }
532
533 /* === E N T R Y P O I N T ================================================= */
534
535 int main()
536 {
537         int error=0;
538
539         error+=generic_pen_test(40,40);
540         error+=generic_pen_test(10,40);
541         error+=generic_pen_test(40,10);
542     if(error)return error;
543         error+=alpha_pen_test();
544         error+=bbox_pen_test();
545         error+=box_blur_test();
546     if(error)return error;
547         error+=gaussian_blur_test();
548
549         return error;
550 }