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