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