| OLD | NEW | 
|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the Chromium LICENSE file. | 3 // found in the Chromium LICENSE file. | 
| 4 | 4 | 
| 5 #include "qcms.h" | 5 #include "qcms.h" | 
| 6 #include "qcmsint.h" | 6 #include "qcms_test_util.h" | 
| 7 #include "qcmstypes.h" |  | 
| 8 #include "timing.h" | 7 #include "timing.h" | 
| 9 | 8 | 
| 10 #include <math.h> | 9 #include <math.h> | 
| 11 #include <stdio.h> | 10 #include <stdio.h> | 
| 12 #include <stdlib.h> | 11 #include <stdlib.h> | 
| 13 #include <string.h> | 12 #include <string.h> | 
| 14 | 13 | 
| 15 // External qcms tetra clut interpolators. | 14 // External qcms tetra clut interpolators. | 
| 16 | 15 | 
| 17 extern void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, | 16 extern void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, | 
| 18                                                 unsigned char *src, | 17                                                 unsigned char *src, | 
| 19                                                 unsigned char *dest, | 18                                                 unsigned char *dest, | 
| 20                                                 size_t length, | 19                                                 size_t length, | 
| 21                                                 qcms_format_type output_format); | 20                                                 qcms_format_type output_format); | 
| 22 | 21 | 
| 23 extern void qcms_transform_data_tetra_clut_rgba_sse2(qcms_transform *transform, | 22 extern void qcms_transform_data_tetra_clut_rgba_sse2(qcms_transform *transform, | 
| 24                                                      unsigned char *src, | 23                                                      unsigned char *src, | 
| 25                                                      unsigned char *dest, | 24                                                      unsigned char *dest, | 
| 26                                                      size_t length, | 25                                                      size_t length, | 
| 27                                                      qcms_format_type output_for
     mat); | 26                                                      qcms_format_type output_for
     mat); | 
| 28 | 27 | 
| 29 #define PIXEL_SIZE 4 |  | 
| 30 |  | 
| 31 static void generate_source(unsigned char *src, size_t length) |  | 
| 32 { |  | 
| 33     size_t bytes = length * PIXEL_SIZE; |  | 
| 34     size_t i; |  | 
| 35 |  | 
| 36     for (i = 0; i < bytes; ++i) { |  | 
| 37         *src++ = rand() & 255; |  | 
| 38     } |  | 
| 39 } |  | 
| 40 |  | 
| 41 static float *create_lut(size_t lutSize) | 28 static float *create_lut(size_t lutSize) | 
| 42 { | 29 { | 
| 43     float *lut = malloc(lutSize * sizeof(float)); | 30     float *lut = malloc(lutSize * sizeof(float)); | 
| 44     size_t i; | 31     size_t i; | 
| 45 | 32 | 
| 46     for (i = 0; i < lutSize; ++i) { | 33     for (i = 0; i < lutSize; ++i) { | 
| 47         lut[i] = (rand() & 255) * (1.0f / 255.0f); | 34         lut[i] = (rand() & 255) * (1.0f / 255.0f); | 
| 48     } | 35     } | 
| 49 | 36 | 
| 50     return lut; | 37     return lut; | 
| 51 } | 38 } | 
| 52 | 39 | 
| 53 static int diffs; | 40 static int diffs; | 
| 54 | 41 | 
| 55 static int validate(unsigned char *dst0, unsigned char *dst1, size_t length, int
      limit) | 42 static int validate(unsigned char *dst0, unsigned char *dst1, size_t length, int
      limit, const size_t pixel_size) | 
| 56 { | 43 { | 
| 57     size_t bytes = length * PIXEL_SIZE; | 44     size_t bytes = length * pixel_size; | 
| 58     size_t i; | 45     size_t i; | 
| 59 | 46 | 
| 60     // Compare dst0/dst0 byte-by-byte, allowing for minor differences due | 47     // Compare dst0/dst0 byte-by-byte, allowing for minor differences due | 
| 61     // to SSE rounding modes (controlled by the limit argument). | 48     // to SSE rounding modes (controlled by the limit argument). | 
| 62 | 49 | 
| 63     if (limit < 0) | 50     if (limit < 0) | 
| 64         limit = 255; // Ignore all differences. | 51         limit = 255; // Ignore all differences. | 
| 65 | 52 | 
| 66     for (diffs = 0, i = 0; i < bytes; ++i) { | 53     for (diffs = 0, i = 0; i < bytes; ++i) { | 
| 67         if (abs((int)dst0[i] - (int)dst1[i]) > limit) { | 54         if (abs((int)dst0[i] - (int)dst1[i]) > limit) { | 
| 68             ++diffs; | 55             ++diffs; | 
| 69         } | 56         } | 
| 70     } | 57     } | 
| 71 | 58 | 
| 72     return !diffs; | 59     return !diffs; | 
| 73 } | 60 } | 
| 74 | 61 | 
| 75 int main(int argc, const char **argv) | 62 static int qcms_test_tetra_clut_rgba(size_t width, | 
|  | 63         size_t height, | 
|  | 64         int iterations, | 
|  | 65         const char *in_profile, | 
|  | 66         const char *out_profile, | 
|  | 67         const int force_software) | 
| 76 { | 68 { | 
| 77     qcms_transform transform0, transform1; | 69     qcms_transform transform0, transform1; | 
| 78     qcms_format_type format = {2, 0}; | 70     qcms_format_type format = {2, 0}; | 
| 79     uint16_t samples = 33; | 71     uint16_t samples = 33; | 
| 80     size_t lutSize; | 72     size_t lutSize; | 
| 81     float *lut0, *lut1; | 73     float *lut0, *lut1; | 
| 82 | 74 | 
| 83     int iterations = 1; | 75     const size_t length = width * height; | 
| 84     size_t height = 2000; | 76     const size_t pixel_size = 4; | 
| 85     size_t width = 2000; |  | 
| 86     size_t length; |  | 
| 87 | 77 | 
| 88     double time0, time1; | 78     double time0, time1; | 
| 89     int i; | 79     int i; | 
| 90 | 80 | 
| 91     while (argc > 1) { |  | 
| 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])); |  | 
| 98         (--argc, ++argv); |  | 
| 99     } |  | 
| 100 |  | 
| 101     printf("Test qcms clut transforms for %d iterations\n", iterations); | 81     printf("Test qcms clut transforms for %d iterations\n", iterations); | 
| 102     printf("Test image size %u x %u pixels\n", (unsigned) width, (unsigned) heig
     ht); | 82     printf("Test image size %u x %u pixels\n", (unsigned) width, (unsigned) heig
     ht); | 
| 103     length = width * height; |  | 
| 104     fflush(stdout); | 83     fflush(stdout); | 
| 105 | 84 | 
| 106     srand(0); | 85     srand(0); | 
| 107     seconds(); | 86     seconds(); | 
| 108 | 87 | 
| 109     memset(&transform0, 0, sizeof(transform0)); | 88     memset(&transform0, 0, sizeof(transform0)); | 
| 110     memset(&transform1, 0, sizeof(transform1)); | 89     memset(&transform1, 0, sizeof(transform1)); | 
| 111 | 90 | 
| 112     transform0.grid_size = samples; | 91     transform0.grid_size = samples; | 
| 113     transform1.grid_size = samples; | 92     transform1.grid_size = samples; | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 128     transform1.g_clut = &lut1[1]; | 107     transform1.g_clut = &lut1[1]; | 
| 129     transform1.b_clut = &lut1[2]; | 108     transform1.b_clut = &lut1[2]; | 
| 130 | 109 | 
| 131     // Re-generate and use different data sources during the iteration loop | 110     // Re-generate and use different data sources during the iteration loop | 
| 132     // to avoid compiler / cache optimizations that may affect performance. | 111     // to avoid compiler / cache optimizations that may affect performance. | 
| 133 | 112 | 
| 134     time0 = 0.0; | 113     time0 = 0.0; | 
| 135     time1 = 0.0; | 114     time1 = 0.0; | 
| 136 | 115 | 
| 137     for (i = 0; i < iterations; ++i) { | 116     for (i = 0; i < iterations; ++i) { | 
| 138         unsigned char *src0 = (unsigned char *)calloc(length, PIXEL_SIZE); | 117         unsigned char *src0 = (unsigned char *)calloc(length, pixel_size); | 
| 139         unsigned char *src1 = (unsigned char *)calloc(length, PIXEL_SIZE); | 118         unsigned char *src1 = (unsigned char *)calloc(length, pixel_size); | 
| 140         unsigned char *dst0 = (unsigned char *)calloc(length, PIXEL_SIZE); | 119         unsigned char *dst0 = (unsigned char *)calloc(length, pixel_size); | 
| 141         unsigned char *dst1 = (unsigned char *)calloc(length, PIXEL_SIZE); | 120         unsigned char *dst1 = (unsigned char *)calloc(length, pixel_size); | 
| 142 | 121 | 
| 143         generate_source(src0, length); | 122         generate_source_uint8_t(src0, length, pixel_size); | 
| 144         memcpy(src1, src0, length * PIXEL_SIZE); | 123         memcpy(src1, src0, length * pixel_size); | 
| 145 | 124 | 
| 146 #define TRANSFORM_TEST0 qcms_transform_data_tetra_clut_rgba | 125 #define TRANSFORM_TEST0 qcms_transform_data_tetra_clut_rgba | 
| 147 #define TRANSFORM_TEST1 qcms_transform_data_tetra_clut_rgba_sse2 | 126 #define TRANSFORM_TEST1 qcms_transform_data_tetra_clut_rgba_sse2 | 
| 148 | 127 | 
| 149         TIME(TRANSFORM_TEST0(&transform0, src0, dst0, length, format), &time0); | 128         TIME(TRANSFORM_TEST0(&transform0, src0, dst0, length, format), &time0); | 
| 150         TIME(TRANSFORM_TEST1(&transform1, src1, dst1, length, format), &time1); | 129         TIME(TRANSFORM_TEST1(&transform1, src1, dst1, length, format), &time1); | 
| 151 | 130 | 
| 152         if (!validate(dst0, dst1, length, 0)) { | 131         if (!validate(dst0, dst1, length, 0, pixel_size)) { | 
| 153             fprintf(stderr, "Invalid transform output: %d diffs\n", diffs); | 132             fprintf(stderr, "Invalid transform output: %d diffs\n", diffs); | 
| 154         } | 133         } | 
| 155 | 134 | 
| 156         free(src0); | 135         free(src0); | 
| 157         free(src1); | 136         free(src1); | 
| 158         free(dst0); | 137         free(dst0); | 
| 159         free(dst1); | 138         free(dst1); | 
| 160     } | 139     } | 
| 161 | 140 | 
| 162 #define STRINGIZE(s) #s | 141 #define STRINGIZE(s) #s | 
| 163 #define STRING(s) STRINGIZE(s) | 142 #define STRING(s) STRINGIZE(s) | 
| 164 | 143 | 
| 165     printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST0) "\n", | 144     printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST0) "\n", | 
| 166            time0, time0 / iterations); | 145             time0, time0 / iterations); | 
| 167     printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST1) "\n", | 146     printf("%.6lf (avg %.6lf) seconds " STRING(TRANSFORM_TEST1) "\n", | 
| 168            time1, time1 / iterations); | 147             time1, time1 / iterations); | 
| 169     printf("%.6lf speedup after %d iterations\n\n", | 148     printf("%.6lf speedup after %d iterations\n\n", | 
| 170            time0 / time1, iterations); | 149             time0 / time1, iterations); | 
| 171 | 150 | 
| 172     free(lut0); | 151     free(lut0); | 
| 173     free(lut1); | 152     free(lut1); | 
| 174 | 153 | 
| 175     return EXIT_SUCCESS; | 154     return diffs; | 
| 176 } | 155 } | 
|  | 156 | 
|  | 157 struct qcms_test_case qcms_test_tetra_clut_rgba_info = { | 
|  | 158         "qcms_test_tetra_clut_rgba", | 
|  | 159         qcms_test_tetra_clut_rgba, | 
|  | 160         QCMS_TEST_DISABLED | 
|  | 161 }; | 
| OLD | NEW | 
|---|