1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the Chromium LICENSE file.
15 // External qcms tetra clut interpolators.
17 extern void qcms_transform_data_tetra_clut_rgba(qcms_transform
*transform
,
21 qcms_format_type output_format
);
23 extern void qcms_transform_data_tetra_clut_rgba_sse2(qcms_transform
*transform
,
27 qcms_format_type output_format
);
31 static void generate_source(unsigned char *src
, size_t length
)
33 size_t bytes
= length
* PIXEL_SIZE
;
36 for (i
= 0; i
< bytes
; ++i
) {
37 *src
++ = rand() & 255;
41 static float *create_lut(size_t lutSize
)
43 float *lut
= malloc(lutSize
* sizeof(float));
46 for (i
= 0; i
< lutSize
; ++i
) {
47 lut
[i
] = (rand() & 255) * (1.0f
/ 255.0f
);
55 static int validate(unsigned char *dst0
, unsigned char *dst1
, size_t length
, int limit
)
57 size_t bytes
= length
* PIXEL_SIZE
;
60 // Compare dst0/dst0 byte-by-byte, allowing for minor differences due
61 // to SSE rounding modes (controlled by the limit argument).
64 limit
= 255; // Ignore all differences.
66 for (diffs
= 0, i
= 0; i
< bytes
; ++i
) {
67 if (abs((int)dst0
[i
] - (int)dst1
[i
]) > limit
) {
75 int main(int argc
, const char **argv
)
77 qcms_transform transform0
, transform1
;
78 qcms_format_type format
= {2, 0};
79 uint16_t samples
= 33;
92 if (strcmp(argv
[1], "-i") == 0)
93 iterations
= abs(atoi(argv
[2]));
94 else if (strcmp(argv
[1], "-w") == 0)
95 width
= (size_t) abs(atoi(argv
[2]));
96 else if (strcmp(argv
[1], "-h") == 0)
97 height
= (size_t) abs(atoi(argv
[2]));
101 printf("Test qcms clut transforms for %d iterations\n", iterations
);
102 printf("Test image size %u x %u pixels\n", (unsigned) width
, (unsigned) height
);
103 length
= width
* height
;
109 transform0
.grid_size
= samples
;
110 transform1
.grid_size
= samples
;
112 lutSize
= 3 * samples
* samples
* samples
;
113 lut0
= create_lut(lutSize
);
114 lut1
= (float *)malloc(lutSize
* sizeof(float));
115 memcpy(lut1
, lut0
, lutSize
* sizeof(float));
117 transform0
.r_clut
= &lut0
[0];
118 transform0
.g_clut
= &lut0
[1];
119 transform0
.b_clut
= &lut0
[2];
121 transform1
.r_clut
= &lut1
[0];
122 transform1
.g_clut
= &lut1
[1];
123 transform1
.b_clut
= &lut1
[2];
125 // Re-generate and use different data sources during the iteration loop
126 // to avoid compiler / cache optimizations that may affect performance.
131 for (i
= 0; i
< iterations
; ++i
) {
132 unsigned char *src0
= (unsigned char *)calloc(length
, PIXEL_SIZE
);
133 unsigned char *src1
= (unsigned char *)calloc(length
, PIXEL_SIZE
);
134 unsigned char *dst0
= (unsigned char *)calloc(length
, PIXEL_SIZE
);
135 unsigned char *dst1
= (unsigned char *)calloc(length
, PIXEL_SIZE
);
137 generate_source(src0
, length
);
138 memcpy(src1
, src0
, length
* PIXEL_SIZE
);
140 #define TRANSFORM_TEST0 qcms_transform_data_tetra_clut_rgba
141 #define TRANSFORM_TEST1 qcms_transform_data_tetra_clut_rgba_sse2
143 TIME(TRANSFORM_TEST0(&transform0
, src0
, dst0
, length
, format
), &time0
);
144 TIME(TRANSFORM_TEST1(&transform1
, src1
, dst1
, length
, format
), &time1
);
146 if (!validate(dst0
, dst1
, length
, 0)) {
147 fprintf(stderr
, "Invalid transform output: %d diffs\n", diffs
);
156 #define STRINGIZE(s) #s
157 #define STRING(s) STRINGIZE(s)
159 printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST0
) "\n",
160 time0
, time0
/ iterations
);
161 printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST1
) "\n",
162 time1
, time1
/ iterations
);
163 printf("%.6lf speedup after %d iterations\n\n",
164 time0
/ time1
, iterations
);