/src/mozilla-central/gfx/tests/gtest/TestQcms.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* vim:set ts=2 sw=2 sts=2 et: */ |
2 | | /* Any copyright is dedicated to the Public Domain. |
3 | | * http://creativecommons.org/publicdomain/zero/1.0/ |
4 | | */ |
5 | | |
6 | | #include "gtest/gtest.h" |
7 | | #include "gmock/gmock.h" |
8 | | |
9 | | #include "mozilla/ArrayUtils.h" |
10 | | #include "qcms.h" |
11 | | #include "transform_util.h" |
12 | | |
13 | | const size_t allGBSize = 1 * 256 * 256 * 4; |
14 | 0 | static unsigned char* createAllGB() { |
15 | 0 | unsigned char* buff = (unsigned char*)malloc(allGBSize); |
16 | 0 | int pos = 0; |
17 | 0 | for (int r = 0; r < 1; r++) { // Skip all R values for speed |
18 | 0 | for (int g = 0; g < 256; g++) { |
19 | 0 | for (int b = 0; b < 256; b++) { |
20 | 0 | buff[pos * 4 + 0] = r; |
21 | 0 | buff[pos * 4 + 1] = g; |
22 | 0 | buff[pos * 4 + 2] = b; |
23 | 0 | buff[pos * 4 + 3] = 0x80; |
24 | 0 | pos++; |
25 | 0 | } |
26 | 0 | } |
27 | 0 | } |
28 | 0 |
|
29 | 0 | return buff; |
30 | 0 | } |
31 | | |
32 | 0 | TEST(GfxQcms, Identity) { |
33 | 0 | // XXX: This means that we can't have qcms v2 unit test |
34 | 0 | // without changing the qcms API. |
35 | 0 | qcms_enable_iccv4(); |
36 | 0 |
|
37 | 0 | qcms_profile* input_profile = qcms_profile_sRGB(); |
38 | 0 | qcms_profile* output_profile = qcms_profile_sRGB(); |
39 | 0 |
|
40 | 0 | EXPECT_FALSE(qcms_profile_is_bogus(input_profile)); |
41 | 0 | EXPECT_FALSE(qcms_profile_is_bogus(output_profile)); |
42 | 0 |
|
43 | 0 | const qcms_intent intent = QCMS_INTENT_DEFAULT; |
44 | 0 | qcms_data_type input_type = QCMS_DATA_RGBA_8; |
45 | 0 | qcms_data_type output_type = QCMS_DATA_RGBA_8; |
46 | 0 |
|
47 | 0 | qcms_transform* transform = qcms_transform_create(input_profile, input_type, |
48 | 0 | output_profile, output_type, |
49 | 0 | intent); |
50 | 0 |
|
51 | 0 | unsigned char *data_in = createAllGB();; |
52 | 0 | unsigned char *data_out = (unsigned char*)malloc(allGBSize); |
53 | 0 | qcms_transform_data(transform, data_in, data_out, allGBSize / 4); |
54 | 0 |
|
55 | 0 | qcms_profile_release(input_profile); |
56 | 0 | qcms_profile_release(output_profile); |
57 | 0 | qcms_transform_release(transform); |
58 | 0 |
|
59 | 0 | free(data_in); |
60 | 0 | free(data_out); |
61 | 0 | } |
62 | | |
63 | 0 | TEST(GfxQcms, LutInverseCrash) { |
64 | 0 | uint16_t lutTable1[] = { |
65 | 0 | 0x0000, 0x0000, 0x0000, 0x8000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
66 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
67 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
68 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
69 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
70 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
71 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
72 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
73 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
74 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
75 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
76 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
77 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
78 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
79 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
80 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
81 | 0 | }; |
82 | 0 | uint16_t lutTable2[] = { |
83 | 0 | 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
84 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
85 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
86 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
87 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
88 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
89 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
90 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
91 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
92 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
93 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
94 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
95 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
96 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
97 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
98 | 0 | 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, |
99 | 0 | }; |
100 | 0 |
|
101 | 0 | // Crash/Assert test |
102 | 0 | lut_inverse_interp16((uint16_t)5, lutTable1, (int)mozilla::ArrayLength(lutTable1)); |
103 | 0 | lut_inverse_interp16((uint16_t)5, lutTable2, (int)mozilla::ArrayLength(lutTable2)); |
104 | 0 | } |
105 | | |
106 | 0 | TEST(GfxQcms, LutInverse) { |
107 | 0 | // mimic sRGB_v4_ICC mBA Output |
108 | 0 | // |
109 | 0 | // XXXX |
110 | 0 | // X |
111 | 0 | // X |
112 | 0 | // XXXX |
113 | 0 | uint16_t value; |
114 | 0 | uint16_t lutTable[256]; |
115 | 0 |
|
116 | 0 | for (int i = 0; i < 20; i++) { |
117 | 0 | lutTable[i] = 0; |
118 | 0 | } |
119 | 0 |
|
120 | 0 | for (int i = 20; i < 200; i++) { |
121 | 0 | lutTable[i] = (i - 20) * 0xFFFF / (200 - 20); |
122 | 0 | } |
123 | 0 |
|
124 | 0 | for (int i = 200; i < (int)mozilla::ArrayLength(lutTable); i++) { |
125 | 0 | lutTable[i] = 0xFFFF; |
126 | 0 | } |
127 | 0 |
|
128 | 0 | for (uint16_t i = 0; i < 65535; i++) { |
129 | 0 | lut_inverse_interp16(i, lutTable, (int)mozilla::ArrayLength(lutTable)); |
130 | 0 | } |
131 | 0 |
|
132 | 0 | // Lookup the interesting points |
133 | 0 |
|
134 | 0 | value = lut_inverse_interp16(0, lutTable, (int)mozilla::ArrayLength(lutTable)); |
135 | 0 | EXPECT_LE(value, 20 * 256); |
136 | 0 |
|
137 | 0 | value = lut_inverse_interp16(1, lutTable, (int)mozilla::ArrayLength(lutTable)); |
138 | 0 | EXPECT_GT(value, 20 * 256); |
139 | 0 |
|
140 | 0 | value = lut_inverse_interp16(65535, lutTable, (int)mozilla::ArrayLength(lutTable)); |
141 | 0 | EXPECT_LT(value, 201 * 256); |
142 | 0 | } |
143 | | |
144 | 0 | TEST(GfxQcms, LutInverseNonMonotonic) { |
145 | 0 | // Make sure we behave sanely for non monotic functions |
146 | 0 | // X X X |
147 | 0 | // X X X |
148 | 0 | // X X X |
149 | 0 | uint16_t lutTable[256]; |
150 | 0 |
|
151 | 0 | for (int i = 0; i < 100; i++) { |
152 | 0 | lutTable[i] = (i - 0) * 0xFFFF / (100 - 0); |
153 | 0 | } |
154 | 0 |
|
155 | 0 | for (int i = 100; i < 200; i++) { |
156 | 0 | lutTable[i] = (i - 100) * 0xFFFF / (200 - 100); |
157 | 0 | } |
158 | 0 |
|
159 | 0 | for (int i = 200; i < 256; i++) { |
160 | 0 | lutTable[i] = (i - 200) * 0xFFFF / (256 - 200); |
161 | 0 | } |
162 | 0 |
|
163 | 0 | for (uint16_t i = 0; i < 65535; i++) { |
164 | 0 | lut_inverse_interp16(i, lutTable, (int)mozilla::ArrayLength(lutTable)); |
165 | 0 | } |
166 | 0 |
|
167 | 0 | // Make sure we don't crash, hang or let sanitizers do their magic |
168 | 0 | } |