-
Notifications
You must be signed in to change notification settings - Fork 1
/
cg-hdr.mm
146 lines (105 loc) · 11.3 KB
/
cg-hdr.mm
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// clang++ cg-hdr.mm -framework CoreGraphics -framework CoreFoundation -framework ImageIO && ./a.out
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/CGImageSource.h>
#include <Cocoa/Cocoa.h>
#include <stdio.h>
#include <stdlib.h>
const int kBlock = 64;
const int kSteps = 65;
const int kWidth = kSteps * kBlock;
const int kHeight = kBlock;
const int kColors = 4;
const int kBytesPerColor = 4;
#define CHECK(x) \
do { \
if (!(x)) { \
fprintf(stderr, "Failed: '%s' at %s:%d\n", #x, __FILE__, __LINE__); \
exit(1); \
} \
} while (0)
CGImageRef LoadImage(const char* filename) {
printf("Loading: %s\n", filename);
CGDataProviderRef provider = CGDataProviderCreateWithFilename(filename);
CHECK(provider);
CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, nullptr);
CHECK(source);
// NSDictionary* options = @{(id)kCGImageSourceDecodeToHDR: @(YES)};
NSDictionary* options = nullptr;
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)options);
CHECK(image);
CFShow(CGImageGetColorSpace(image));
return image;
}
void DrawStuff(CFStringRef src_space, const char* src_space_name, CFStringRef dst_space, const char* dst_space_name, CGImageRef image) {
float* pixels = new float[kColors*kWidth*kHeight];
memset(pixels, 0, kBytesPerColor*kColors*kWidth*kHeight);
CGContextRef ctx = CGBitmapContextCreate(
pixels, kWidth, kHeight, 8*kBytesPerColor, kBytesPerColor*kColors*kWidth,
CGColorSpaceCreateWithName(dst_space), kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Host|kCGBitmapFloatComponents);
CHECK(ctx);
if (image) {
CGContextDrawImage(ctx, CGRectMake(0, 0, kWidth, kHeight), image);
} else {
static bool once = true;
if (once) {
printf("src = np.array([");
}
for (int i = 0; i < kSteps; ++i) {
float value = i/(kSteps - 1.f);
CGColorSpaceRef space = CGColorSpaceCreateWithName(src_space);
CGFloat components[4] = {value, value, value, 1};
CGColorRef color = CGColorCreate(space, components);
CGContextSetFillColorWithColor(ctx, color);
CFRelease(color);
if (once) {
printf("%f, ", value);
}
CGContextFillRect(ctx, CGRectMake(i*kBlock, 0, kBlock, kBlock));
}
if (once) {
printf("])\n");
printf("\n");
}
once = false;
}
CFRelease(ctx);
printf("%s_to_%s = np.array([", src_space_name, dst_space_name);
for (int i = 0; i < kSteps; ++i) {
int x = kBlock * i + kBlock/2;
int y = kBlock/2;
float* pixel = pixels + kColors*(kWidth*y + x);
printf("%f, ", pixel[2]);
}
printf("])\n");
printf("\n\n");
}
/*
Sonoma output:
src = np.array([0.000000, 0.015625, 0.031250, 0.046875, 0.062500, 0.078125, 0.093750, 0.109375, 0.125000, 0.140625, 0.156250, 0.171875, 0.187500, 0.203125, 0.218750, 0.234375, 0.250000, 0.265625, 0.281250, 0.296875, 0.312500, 0.328125, 0.343750, 0.359375, 0.375000, 0.390625, 0.406250, 0.421875, 0.437500, 0.453125, 0.468750, 0.484375, 0.500000, 0.515625, 0.531250, 0.546875, 0.562500, 0.578125, 0.593750, 0.609375, 0.625000, 0.640625, 0.656250, 0.671875, 0.687500, 0.703125, 0.718750, 0.734375, 0.750000, 0.765625, 0.781250, 0.796875, 0.812500, 0.828125, 0.843750, 0.859375, 0.875000, 0.890625, 0.906250, 0.921875, 0.937500, 0.953125, 0.968750, 0.984375, 1.000000, ])
LinearSRGB_to_PQ = np.array([0.000001, 0.216937, 0.265014, 0.295800, 0.318788, 0.337252, 0.352736, 0.366101, 0.377870, 0.388401, 0.397932, 0.406642, 0.414671, 0.422122, 0.429063, 0.435577, 0.441701, 0.447487, 0.452968, 0.458181, 0.463146, 0.467886, 0.472426, 0.476779, 0.480964, 0.484984, 0.488861, 0.492606, 0.496220, 0.499716, 0.503103, 0.506391, 0.509571, 0.512667, 0.515677, 0.518598, 0.521450, 0.524226, 0.526935, 0.529576, 0.532158, 0.534675, 0.537136, 0.539545, 0.541897, 0.544202, 0.546458, 0.548670, 0.550838, 0.552960, 0.555043, 0.557090, 0.559097, 0.561067, 0.563006, 0.564908, 0.566777, 0.568615, 0.570426, 0.572209, 0.573953, 0.575675, 0.577374, 0.579045, 0.580692, ])
LinearSRGB_to_HLG = np.array([0.000000, 0.111453, 0.157619, 0.193043, 0.222907, 0.249218, 0.273004, 0.294878, 0.315238, 0.334360, 0.352447, 0.369649, 0.386086, 0.401851, 0.417021, 0.431657, 0.445814, 0.459534, 0.472857, 0.485814, 0.498435, 0.510542, 0.521886, 0.532552, 0.542618, 0.552148, 0.561195, 0.569806, 0.578022, 0.585877, 0.593401, 0.600622, 0.607562, 0.614243, 0.620683, 0.626900, 0.632907, 0.638719, 0.644349, 0.649806, 0.655102, 0.660246, 0.665245, 0.670109, 0.674844, 0.679457, 0.683954, 0.688340, 0.692622, 0.696803, 0.700889, 0.704883, 0.708791, 0.712614, 0.716358, 0.720025, 0.723618, 0.727141, 0.730595, 0.733984, 0.737310, 0.740575, 0.743782, 0.746932, 0.750028, ])
ExtendedLinearSRGB_to_PQ = np.array([0.000001, 0.173905, 0.215967, 0.243309, 0.263920, 0.280588, 0.294633, 0.306810, 0.317575, 0.327234, 0.336001, 0.344038, 0.351458, 0.358353, 0.364794, 0.370845, 0.376544, 0.381940, 0.387059, 0.391926, 0.396574, 0.401021, 0.405275, 0.409361, 0.413294, 0.417077, 0.420726, 0.424256, 0.427665, 0.430967, 0.434163, 0.437267, 0.440281, 0.443207, 0.446062, 0.448838, 0.451535, 0.454172, 0.456745, 0.459251, 0.461700, 0.464097, 0.466439, 0.468729, 0.470971, 0.473172, 0.475319, 0.477429, 0.479497, 0.481523, 0.483514, 0.485467, 0.487394, 0.489277, 0.491128, 0.492944, 0.494737, 0.496503, 0.498232, 0.499938, 0.501615, 0.503264, 0.504893, 0.506498, 0.508079, ])
ExtendedLinearSRGB_to_HLG = np.array([0.000000, 0.062500, 0.088388, 0.108253, 0.125000, 0.139754, 0.153093, 0.165359, 0.176777, 0.187500, 0.197642, 0.207289, 0.216506, 0.225347, 0.233854, 0.242061, 0.250000, 0.257694, 0.265165, 0.272431, 0.279509, 0.286411, 0.293151, 0.299739, 0.306186, 0.312500, 0.318689, 0.324760, 0.330719, 0.336573, 0.342327, 0.347985, 0.353553, 0.359035, 0.364434, 0.369755, 0.375000, 0.380173, 0.385276, 0.390312, 0.395285, 0.400195, 0.405046, 0.409840, 0.414578, 0.419263, 0.423896, 0.428478, 0.433013, 0.437500, 0.441942, 0.446339, 0.450694, 0.455007, 0.459279, 0.463512, 0.467707, 0.471865, 0.475986, 0.480072, 0.484123, 0.488141, 0.492126, 0.496078, 0.500000, ])
PQ_to_LinearSRGB = np.array([0.000000, 0.000026, 0.000106, 0.000256, 0.000496, 0.000851, 0.001351, 0.002029, 0.002926, 0.004086, 0.005565, 0.007424, 0.009736, 0.012584, 0.016065, 0.020291, 0.025390, 0.031510, 0.038822, 0.047525, 0.057837, 0.070024, 0.084382, 0.101248, 0.121022, 0.144146, 0.171141, 0.202600, 0.239196, 0.281715, 0.331038, 0.388220, 0.453990, 0.522653, 0.590660, 0.656317, 0.718097, 0.774720, 0.825284, 0.869061, 0.905783, 0.935518, 0.958607, 0.975566, 0.987200, 0.994432, 0.998255, 0.999750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, ])
HLG_to_LinearSRGB = np.array([0.000000, 0.000347, 0.001122, 0.002228, 0.003625, 0.005287, 0.007197, 0.009342, 0.011710, 0.014292, 0.017080, 0.020069, 0.023252, 0.026623, 0.030180, 0.033916, 0.037829, 0.041915, 0.046171, 0.050593, 0.055180, 0.059928, 0.064835, 0.069899, 0.075117, 0.080489, 0.086010, 0.091681, 0.097499, 0.103463, 0.109571, 0.115821, 0.122212, 0.128931, 0.136191, 0.144034, 0.152506, 0.161655, 0.171533, 0.182195, 0.193703, 0.206122, 0.219520, 0.233974, 0.249565, 0.266379, 0.284511, 0.304061, 0.325138, 0.347860, 0.372351, 0.398748, 0.427197, 0.457856, 0.490892, 0.526489, 0.564843, 0.606165, 0.650682, 0.698639, 0.750301, 0.805950, 0.865893, 0.930458, 1.000000, ])
PQ_to_ExtendedLinearSRGB = np.array([0.000000, 0.000054, 0.000215, 0.000519, 0.001006, 0.001728, 0.002743, 0.004119, 0.005939, 0.008295, 0.011296, 0.015070, 0.019763, 0.025545, 0.032612, 0.041190, 0.051542, 0.063966, 0.078810, 0.096473, 0.117410, 0.142148, 0.171292, 0.205537, 0.245669, 0.292616, 0.347416, 0.411268, 0.485558, 0.571870, 0.672023, 0.788086, 0.922453, 1.077887, 1.257546, 1.465027, 1.704521, 1.980764, 2.299392, 2.666658, 3.089845, 3.577472, 4.139257, 4.786333, 5.531724, 6.390413, 7.379795, 8.519630, 9.833629, 11.348959, 13.096447, 15.112729, 17.440111, 20.129364, 23.236395, 26.830481, 30.989279, 35.805759, 41.389713, 47.867046, 55.389706, 64.135353, 74.314400, 86.168777, 100.000008, ])
HLG_to_ExtendedLinearSRGB = np.array([0.000000, 0.000977, 0.003906, 0.008789, 0.015625, 0.024414, 0.035156, 0.047852, 0.062500, 0.079102, 0.097656, 0.118164, 0.140625, 0.165039, 0.191406, 0.219727, 0.250000, 0.282227, 0.316406, 0.352539, 0.390625, 0.430664, 0.472656, 0.516602, 0.562500, 0.610352, 0.660156, 0.711914, 0.765625, 0.821289, 0.878906, 0.938477, 1.000000, 1.065312, 1.136587, 1.214369, 1.299253, 1.391887, 1.492979, 1.603301, 1.723696, 1.855083, 1.998466, 2.154941, 2.325702, 2.512053, 2.715420, 2.937353, 3.179551, 3.443861, 3.732304, 4.047083, 4.390601, 4.765484, 5.174595, 5.621058, 6.108286, 6.639997, 7.220255, 7.853494, 8.544549, 9.298697, 10.121701, 11.019851, 12.000001, ])
PQ_to_HLG = np.array([0.000000, 0.011021, 0.019679, 0.028387, 0.037412, 0.046866, 0.056815, 0.067309, 0.078392, 0.090101, 0.102476, 0.115552, 0.129370, 0.143970, 0.159392, 0.175681, 0.192883, 0.211044, 0.230216, 0.250455, 0.271813, 0.294353, 0.318139, 0.343240, 0.369720, 0.397666, 0.427151, 0.458261, 0.491090, 0.524623, 0.556311, 0.586397, 0.615176, 0.642874, 0.669667, 0.695688, 0.721054, 0.745854, 0.770175, 0.794074, 0.817605, 0.840823, 0.863767, 0.886471, 0.908970, 0.931291, 0.953463, 0.975502, 0.997439, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, ])
HLG_to_PQ = np.array([0.000001, 0.023891, 0.051903, 0.078140, 0.102319, 0.124634, 0.145322, 0.164601, 0.182651, 0.199620, 0.215633, 0.230799, 0.245200, 0.258916, 0.272008, 0.284530, 0.296533, 0.308059, 0.319142, 0.329820, 0.340120, 0.350067, 0.359684, 0.368992, 0.378021, 0.386768, 0.395263, 0.403516, 0.411542, 0.419350, 0.426960, 0.434369, 0.441602, 0.448847, 0.456320, 0.464007, 0.471906, 0.480007, 0.488304, 0.496801, 0.505478, 0.514336, 0.523368, 0.532563, 0.541913, 0.551421, 0.561067, 0.570853, 0.580765, 0.590802, 0.600959, 0.611226, 0.621596, 0.632056, 0.642606, 0.653243, 0.663961, 0.674751, 0.685605, 0.696521, 0.707489, 0.718507, 0.729579, 0.740688, 0.751831, ])
*/
int main(int argc, char* argv[]) {
// CGImageRef srgb_staircase = LoadImage("staircase-srgb.avif");
// CGImageRef hlg_staircase = LoadImage("staircase-hlg.avif");
// CGImageRef pq_staircase = LoadImage("staircase-pq.avif");
DrawStuff(kCGColorSpaceLinearSRGB, "LinearSRGB", kCGColorSpaceITUR_2100_PQ, "PQ", nullptr);
DrawStuff(kCGColorSpaceLinearSRGB, "LinearSRGB", kCGColorSpaceITUR_2100_HLG, "HLG", nullptr);
DrawStuff(kCGColorSpaceExtendedLinearSRGB, "ExtendedLinearSRGB", kCGColorSpaceITUR_2100_PQ, "PQ", nullptr);
DrawStuff(kCGColorSpaceExtendedLinearSRGB, "ExtendedLinearSRGB", kCGColorSpaceITUR_2100_HLG, "HLG", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_PQ, "PQ", kCGColorSpaceLinearSRGB, "LinearSRGB", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_HLG, "HLG", kCGColorSpaceLinearSRGB, "LinearSRGB", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_PQ, "PQ", kCGColorSpaceExtendedLinearSRGB, "ExtendedLinearSRGB", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_HLG, "HLG", kCGColorSpaceExtendedLinearSRGB, "ExtendedLinearSRGB", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_PQ, "PQ", kCGColorSpaceITUR_2100_HLG, "HLG", nullptr);
DrawStuff(kCGColorSpaceITUR_2100_HLG, "HLG", kCGColorSpaceITUR_2100_PQ, "PQ", nullptr);
return 0;
}