forked from nayuki/Nayuki-web-published-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
srgb-transform-test.c
93 lines (82 loc) · 3.03 KB
/
srgb-transform-test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* sRGB transform test (C)
*
* Copyright (c) 2017 Project Nayuki. (MIT License)
* https://www.nayuki.io/page/srgb-transform-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "srgb-transform.h"
static const double DELTA = 3e-7;
static void test_forward_inverse(void) {
int trials = 1000000;
for (int i = 0; i < trials; i++) {
double xd = (double)rand() / RAND_MAX;
float xf = (float)xd;
double yd = srgb_to_linear_double(xd);
float yf = srgb_to_linear_float(xf);
double zd = linear_to_srgb_double(xd);
float zf = linear_to_srgb_float(xf);
assert(fabs(xd - linear_to_srgb_double(yd)) < DELTA);
assert(fabs(xf - linear_to_srgb_float(yf)) < DELTA);
assert(fabs(xd - srgb_to_linear_double(zd)) < DELTA);
assert(fabs(xf - srgb_to_linear_float(zf)) < DELTA);
}
}
static void test_monotonicity(void) {
int trials = 1000000;
for (int i = 0; i < trials; i++) {
double xd = (double)rand() / RAND_MAX * 2 - 0.5;
double yd = (double)rand() / RAND_MAX * 2 - 0.5;
if (yd < xd) {
double temp = xd;
xd = yd;
yd = temp;
}
float xf = (float)xd;
float yf = (float)yd;
if (yd - xd > DELTA) {
assert(srgb_to_linear_double(xd) <= srgb_to_linear_double(yd));
assert(linear_to_srgb_double(xd) <= linear_to_srgb_double(yd));
assert(linear_to_srgb_8bit(xd) <= linear_to_srgb_8bit(yd));
}
if (yf - xf > DELTA) {
assert(srgb_to_linear_float(xf) <= srgb_to_linear_float(yf));
assert(linear_to_srgb_float(xf) <= linear_to_srgb_float(yf));
}
}
}
static void test_8Bit(void) {
for (int i = 0; i < (1 << 8); i++) {
assert(linear_to_srgb_8bit(SRGB_8BIT_TO_LINEAR_DOUBLE[i]) == i);
assert(linear_to_srgb_8bit(SRGB_8BIT_TO_LINEAR_FLOAT [i]) == i);
assert(fabs(linear_to_srgb_double(SRGB_8BIT_TO_LINEAR_DOUBLE[i]) * 255.0 - i) < 1.0);
}
}
int main(void) {
srand(time(NULL));
test_forward_inverse();
test_monotonicity();
test_8Bit();
printf("Test passed\n");
return EXIT_SUCCESS;
}