]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/rasterbench.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / rasterbench.c
1 /*
2 * "$Id: rasterbench.c 6649 2007-07-11 21:46:42Z mike $"
3 *
4 * Raster benchmark program for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * main() - Benchmark the raster read/write functions.
20 * compute_median() - Compute the median time for a test.
21 * read_test() - Benchmark the raster read functions.
22 * write_test() - Benchmark the raster write functions.
23 */
24
25 /*
26 * Include necessary headers...
27 */
28
29 #include "raster.h"
30 #include <stdlib.h>
31 #include <sys/time.h>
32 #include <signal.h>
33 #include <unistd.h>
34 #include <sys/wait.h>
35
36
37 /*
38 * Constants...
39 */
40
41 #define TEST_WIDTH 1024
42 #define TEST_HEIGHT 1024
43 #define TEST_PAGES 16
44 #define TEST_PASSES 20
45
46
47 /*
48 * Local functions...
49 */
50
51 static double compute_median(double *secs);
52 static double get_time(void);
53 static void read_test(int fd);
54 static int run_read_test(void);
55 static void write_test(int fd);
56
57
58 /*
59 * 'main()' - Benchmark the raster read/write functions.
60 */
61
62 int /* O - Exit status */
63 main(void)
64 {
65 int i; /* Looping var */
66 int ras_fd, /* File descriptor for read process */
67 status; /* Exit status of read process */
68 double start_secs, /* Start time */
69 write_secs, /* Write time */
70 read_secs, /* Read time */
71 pass_secs[TEST_PASSES]; /* Total test times */
72
73
74 /*
75 * Ignore SIGPIPE...
76 */
77
78 signal(SIGPIPE, SIG_IGN);
79
80 /*
81 * Run the tests several times to get a good average...
82 */
83
84 printf("Test read/write speed of %d pages, %dx%d pixels...\n\n",
85 TEST_PAGES, TEST_WIDTH, TEST_HEIGHT);
86 for (i = 0; i < TEST_PASSES; i ++)
87 {
88 printf("PASS %2d: ", i + 1);
89 fflush(stdout);
90
91 ras_fd = run_read_test();
92 start_secs = get_time();
93
94 write_test(ras_fd);
95
96 write_secs = get_time();
97 printf(" %.3f write,", write_secs - start_secs);
98 fflush(stdout);
99
100 close(ras_fd);
101 wait(&status);
102
103 read_secs = get_time();
104 pass_secs[i] = read_secs - start_secs;
105 printf(" %.3f read, %.3f total\n", read_secs - write_secs, pass_secs[i]);
106 }
107
108 printf("\nMedian Total Time: %.3f seconds per document\n",
109 compute_median(pass_secs));
110
111 return (0);
112 }
113
114
115 /*
116 * 'compute_median()' - Compute the median time for a test.
117 */
118
119 static double /* O - Median time in seconds */
120 compute_median(double *secs) /* I - Array of time samples */
121 {
122 int i, j; /* Looping vars */
123 double temp; /* Swap variable */
124
125
126 /*
127 * Sort the array into ascending order using a quicky bubble sort...
128 */
129
130 for (i = 0; i < (TEST_PASSES - 1); i ++)
131 for (j = i + 1; j < TEST_PASSES; j ++)
132 if (secs[i] > secs[j])
133 {
134 temp = secs[i];
135 secs[i] = secs[j];
136 secs[j] = temp;
137 }
138
139 /*
140 * Return the average of the middle two samples...
141 */
142
143 return (0.5 * (secs[TEST_PASSES / 2 - 1] + secs[TEST_PASSES / 2]));
144 }
145
146
147 /*
148 * 'get_time()' - Get the current time in seconds.
149 */
150
151 static double /* O - Time in seconds */
152 get_time(void)
153 {
154 struct timeval curtime; /* Current time */
155
156
157 gettimeofday(&curtime, NULL);
158 return (curtime.tv_sec + 0.000001 * curtime.tv_usec);
159 }
160
161
162 /*
163 * 'read_test()' - Benchmark the raster read functions.
164 */
165
166 static void
167 read_test(int fd) /* I - File descriptor to read from */
168 {
169 int y; /* Looping var */
170 cups_raster_t *r; /* Raster stream */
171 cups_page_header_t header; /* Page header */
172 unsigned char buffer[8 * TEST_WIDTH];
173 /* Read buffer */
174
175
176 /*
177 * Test read speed...
178 */
179
180 if ((r = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL)
181 {
182 perror("Unable to create raster input stream");
183 return;
184 }
185
186 while (cupsRasterReadHeader(r, &header))
187 {
188 for (y = 0; y < header.cupsHeight; y ++)
189 cupsRasterReadPixels(r, buffer, header.cupsBytesPerLine);
190 }
191
192 cupsRasterClose(r);
193 }
194
195
196 /*
197 * 'run_read_test()' - Run the read test as a child process via pipes.
198 */
199
200 static int /* O - Standard input of child */
201 run_read_test(void)
202 {
203 int ras_pipes[2]; /* Raster data pipes */
204 int pid; /* Child process ID */
205
206
207 if (pipe(ras_pipes))
208 return (-1);
209
210 if ((pid = fork()) < 0)
211 {
212 /*
213 * Fork error - return -1 on error...
214 */
215
216 close(ras_pipes[0]);
217 close(ras_pipes[1]);
218
219 return (-1);
220 }
221 else if (pid == 0)
222 {
223 /*
224 * Child comes here - read data from the input pipe...
225 */
226
227 close(ras_pipes[1]);
228 read_test(ras_pipes[0]);
229 exit(0);
230 }
231 else
232 {
233 /*
234 * Parent comes here - return the output pipe...
235 */
236
237 close(ras_pipes[0]);
238 return (ras_pipes[1]);
239 }
240 }
241
242
243 /*
244 * 'write_test()' - Benchmark the raster write functions.
245 */
246
247 static void
248 write_test(int fd) /* I - File descriptor to write to */
249 {
250 int page, x, y; /* Looping vars */
251 int count; /* Number of bytes to set */
252 cups_raster_t *r; /* Raster stream */
253 cups_page_header_t header; /* Page header */
254 unsigned char data[32][8 * TEST_WIDTH];
255 /* Raster data to write */
256
257
258 /*
259 * Create a combination of random data and repeated data to simulate
260 * text with some whitespace.
261 */
262
263 srand(time(NULL));
264
265 memset(data, 0, sizeof(data));
266
267 for (y = 0; y < 28; y ++)
268 {
269 for (x = rand() & 127, count = (rand() & 15) + 1;
270 x < sizeof(data[0]);
271 x ++, count --)
272 {
273 if (count <= 0)
274 {
275 x += (rand() & 15) + 1;
276 count = (rand() & 15) + 1;
277
278 if (x >= sizeof(data[0]))
279 break;
280 }
281
282 data[y][x] = rand();
283 }
284 }
285
286 /*
287 * Test write speed...
288 */
289
290 if ((r = cupsRasterOpen(fd, CUPS_RASTER_WRITE)) == NULL)
291 {
292 perror("Unable to create raster output stream");
293 return;
294 }
295
296 for (page = 0; page < TEST_PAGES; page ++)
297 {
298 memset(&header, 0, sizeof(header));
299 header.cupsWidth = TEST_WIDTH;
300 header.cupsHeight = TEST_HEIGHT;
301 header.cupsBytesPerLine = TEST_WIDTH;
302
303 if (page & 1)
304 {
305 header.cupsBytesPerLine *= 4;
306 header.cupsColorSpace = CUPS_CSPACE_CMYK;
307 header.cupsColorOrder = CUPS_ORDER_CHUNKED;
308 }
309 else
310 {
311 header.cupsColorSpace = CUPS_CSPACE_K;
312 header.cupsColorOrder = CUPS_ORDER_BANDED;
313 }
314
315 if (page & 2)
316 {
317 header.cupsBytesPerLine *= 2;
318 header.cupsBitsPerColor = 16;
319 header.cupsBitsPerPixel = (page & 1) ? 64 : 16;
320 }
321 else
322 {
323 header.cupsBitsPerColor = 8;
324 header.cupsBitsPerPixel = (page & 1) ? 32 : 8;
325 }
326
327 cupsRasterWriteHeader(r, &header);
328
329 for (y = 0; y < TEST_HEIGHT; y ++)
330 cupsRasterWritePixels(r, data[y & 31], header.cupsBytesPerLine);
331 }
332
333 cupsRasterClose(r);
334 }
335
336
337 /*
338 * End of "$Id: rasterbench.c 6649 2007-07-11 21:46:42Z mike $".
339 */