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