]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/pixops/timescale.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / gdk-pixbuf / pixops / timescale.c
1 #include <config.h>
2 #include <glib.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 #include "pixops.h"
8
9 static GTimeVal start_time;
10
11 void start_timing (void)
12 {
13   g_get_current_time (&start_time);
14 }
15
16 double
17 stop_timing (const char *test, int iterations, int bytes)
18 {
19   GTimeVal stop_time;
20   double msecs;
21   
22   g_get_current_time (&stop_time);
23   if (stop_time.tv_usec < start_time.tv_usec)
24     {
25       stop_time.tv_usec += 1000000;
26       stop_time.tv_sec -= 1;
27     }
28
29   msecs = (stop_time.tv_sec - start_time.tv_sec) * 1000. +
30           (stop_time.tv_usec - start_time.tv_usec) / 1000.;
31
32   printf("%s%d\t%.1f\t\t%.2f\t\t%.2f\n",
33          test, iterations, msecs, msecs / iterations, ((double)bytes * iterations) / (1000*msecs));
34
35   return ((double)bytes * iterations) / (1000*msecs);
36 }
37
38 void
39 init_array (double times[3][3][4])
40 {
41   int i, j, k;
42   
43   for (i=0; i<3; i++)
44     for (j=0; j<3; j++)
45       for (k=0; k<4; k++)
46         times[i][j][k] = -1;
47 }
48
49 void
50 dump_array (double times[3][3][4])
51 {
52   int i, j;
53   
54   printf("        3\t4\t4a\n");
55   for (i=0; i<3; i++)
56     {
57       for (j=0; j<4; j++)
58         {
59           if (j == 0)
60             switch (i)
61               {
62               case 0:
63                 printf("3  ");
64                 break;
65               case 1:
66                 printf("4  ");
67                 break;
68               case 2:
69                 printf("4a ");
70                 break;
71               }
72           else
73             printf("   ");
74
75           printf("%6.2f  %6.2f   %6.2f",
76                  times[i][0][j], times[i][1][j], times[i][2][j]);
77
78           switch (j)
79             {
80             case PIXOPS_INTERP_NEAREST:
81               printf ("  NEAREST\n");
82               break;
83             case PIXOPS_INTERP_TILES:
84               printf ("  TILES\n");
85               break;
86             case PIXOPS_INTERP_BILINEAR:
87               printf ("  BILINEAR\n");
88               break;
89             case PIXOPS_INTERP_HYPER:
90               printf ("  HYPER\n");
91               break;
92             }
93         }
94     }
95   printf("\n");
96 }
97
98 #define ITERS 10
99
100 int main (int argc, char **argv)
101 {
102   int src_width, src_height, dest_width, dest_height;
103   char *src_buf, *dest_buf;
104   int src_index, dest_index;
105   int i;
106   double scale_times[3][3][4];
107   double composite_times[3][3][4];
108   double composite_color_times[3][3][4];
109
110   if (argc == 5)
111     {
112       src_width = atoi(argv[1]);
113       src_height = atoi(argv[2]);
114       dest_width = atoi(argv[3]);
115       dest_height = atoi(argv[4]);
116     }
117   else if (argc == 1)
118     {
119       src_width = 343;
120       src_height = 343;
121       dest_width = 711;
122       dest_height = 711;
123     }
124   else
125     {
126       fprintf (stderr, "Usage: scale [src_width src_height dest_width dest_height]\n");
127       exit(1);
128     }
129
130
131   printf ("Scaling from (%d, %d) to (%d, %d)\n\n", src_width, src_height, dest_width, dest_height);
132
133   init_array (scale_times);
134   init_array (composite_times);
135   init_array (composite_color_times);
136
137   for (src_index = 0; src_index < 3; src_index++)
138     for (dest_index = 0; dest_index < 3; dest_index++)
139       {
140         int src_channels = (src_index == 0) ? 3 : 4;
141         int src_has_alpha = (src_index == 2);
142         int dest_channels = (dest_index == 0) ? 3 : 4;
143         int dest_has_alpha = (dest_index == 2);
144         
145         int src_rowstride = (src_channels*src_width + 3) & ~3;
146         int dest_rowstride = (dest_channels *dest_width + 3) & ~3;
147
148         int filter_level;
149
150         src_buf = g_malloc(src_rowstride * src_height);
151         memset (src_buf, 0x80, src_rowstride * src_height);
152         
153         dest_buf = g_malloc(dest_rowstride * dest_height);
154         memset (dest_buf, 0x80, dest_rowstride * dest_height);
155
156         for (filter_level = PIXOPS_INTERP_NEAREST ; filter_level <= PIXOPS_INTERP_HYPER; filter_level++)
157           {
158             printf ("src_channels = %d (%s); dest_channels = %d (%s); filter_level=",
159                     src_channels, src_has_alpha ? "alpha" : "no alpha",
160                     dest_channels, dest_has_alpha ? "alpha" : "no alpha");
161             switch (filter_level)
162               {
163               case PIXOPS_INTERP_NEAREST:
164                 printf ("PIXOPS_INTERP_NEAREST\n");
165                 break;
166               case PIXOPS_INTERP_TILES:
167                 printf ("PIXOPS_INTERP_TILES\n");
168                 break;
169               case PIXOPS_INTERP_BILINEAR:
170                 printf ("PIXOPS_INTERP_BILINEAR\n");
171                 break;
172               case PIXOPS_INTERP_HYPER:
173                 printf ("PIXOPS_INTERP_HYPER\n");
174                 break;
175               }
176
177             printf("\t\t\titers\ttotal\t\tmsecs/iter\tMpixels/sec\t\n");
178
179
180             if (!(src_has_alpha && !dest_has_alpha))
181               {
182                 start_timing ();
183                 for (i = 0; i < ITERS; i++)
184                   {
185                     pixops_scale (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
186                                   src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
187                                   (double)dest_width / src_width, (double)dest_height / src_height,
188                                   filter_level);
189                   }
190                 scale_times[src_index][dest_index][filter_level] =
191                   stop_timing ("   scale\t\t", ITERS, dest_height * dest_width);
192               }
193
194             start_timing ();
195             for (i = 0; i < ITERS; i++)
196               {
197                 pixops_composite (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
198                               src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
199                               (double)dest_width / src_width, (double)dest_height / src_height,
200                               filter_level, 255);
201               }
202             composite_times[src_index][dest_index][filter_level] =
203               stop_timing ("   composite\t\t", ITERS, dest_height * dest_width);
204
205             start_timing ();
206             for (i = 0; i < ITERS; i++)
207               {
208                 pixops_composite_color (dest_buf, 0, 0, dest_width, dest_height, dest_rowstride, dest_channels, dest_has_alpha,
209                                         src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,
210                                         (double)dest_width / src_width, (double)dest_height / src_height,
211                                         filter_level, 255, 0, 0, 16, 0xaaaaaa, 0x555555);
212               }
213             composite_color_times[src_index][dest_index][filter_level] =
214               stop_timing ("   composite color\t", ITERS, dest_height * dest_width);
215
216             printf ("\n");
217           }
218         printf ("\n");
219
220         g_free (src_buf);
221         g_free (dest_buf);
222       }
223
224   printf ("SCALE\n=====\n\n");
225   dump_array (scale_times);
226
227   printf ("COMPOSITE\n=========\n\n");
228   dump_array (composite_times);
229
230   printf ("COMPOSITE_COLOR\n===============\n\n");
231   dump_array (composite_color_times);
232   return 0;
233 }