Coverage Report

Created: 2018-09-25 14:53

/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
}