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