Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit a01d98b

Browse files
committed
[[ Bug 13208 ]] Reimplement OSX colorspace handling and add support for PNG cHRM chunk
1 parent 0049294 commit a01d98b

5 files changed

Lines changed: 335 additions & 93 deletions

File tree

docs/notes/bugfix-13208.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Image file color profiles don't seem to be handled correctly

engine/engine.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@
538538
E8252264174E2BF500055329 /* libskia.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E8AF4895174D5563000B2F9E /* libskia.a */; };
539539
E85130F4180D9969004D1DB4 /* image_rep_densitymapped.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E85130F3180D9969004D1DB4 /* image_rep_densitymapped.cpp */; };
540540
E85130F5180D9969004D1DB4 /* image_rep_densitymapped.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E85130F3180D9969004D1DB4 /* image_rep_densitymapped.cpp */; };
541+
E861167119D45AF50047E1BC /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E861167019D45AF50047E1BC /* color.cpp */; };
542+
E861167219D45AF50047E1BC /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E861167019D45AF50047E1BC /* color.cpp */; };
541543
E8687A941987F5A80093C756 /* imageloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8687A931987F5A80093C756 /* imageloader.cpp */; };
542544
E87FAFEC1924F25000ED338B /* region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87FAFEB1924F24300ED338B /* region.cpp */; };
543545
E88869AC180D63FC0026BFDA /* stackview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8988A8917FDD5B700F640F4 /* stackview.cpp */; };
@@ -1559,6 +1561,8 @@
15591561
BE4D6171189A5495002DA467 /* AttachmentProvider.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; path = AttachmentProvider.java; sourceTree = "<group>"; };
15601562
E82206E0184F810A00117D10 /* resolution.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = resolution.cpp; path = src/resolution.cpp; sourceTree = "<group>"; };
15611563
E85130F3180D9969004D1DB4 /* image_rep_densitymapped.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = image_rep_densitymapped.cpp; path = src/image_rep_densitymapped.cpp; sourceTree = "<group>"; };
1564+
E861167019D45AF50047E1BC /* color.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = color.cpp; path = src/color.cpp; sourceTree = "<group>"; };
1565+
E861167319D45D810047E1BC /* color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = color.h; path = src/color.h; sourceTree = "<group>"; };
15621566
E8687A921987F24A0093C756 /* imageloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imageloader.h; path = src/imageloader.h; sourceTree = "<group>"; };
15631567
E8687A931987F5A80093C756 /* imageloader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imageloader.cpp; path = src/imageloader.cpp; sourceTree = "<group>"; };
15641568
E86A04F6142A49EF005ECD82 /* srvsession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srvsession.cpp; path = src/srvsession.cpp; sourceTree = "<group>"; };
@@ -2528,6 +2532,8 @@
25282532
4DAB7B360FE120060009F91E /* bitmapeffect.h */,
25292533
4D00CD75103305D4003D3C0D /* bitmapeffectblur.cpp */,
25302534
4D00CD76103305D4003D3C0D /* bitmapeffectblur.h */,
2535+
E861167019D45AF50047E1BC /* color.cpp */,
2536+
E861167319D45D810047E1BC /* color.h */,
25312537
4D587E740B8096FD00200116 /* combiners.cpp */,
25322538
4D587E1A0B8096E600200116 /* context.h */,
25332539
4D6A00EE10C578C600FA48D2 /* customprinter.cpp */,
@@ -3455,6 +3461,7 @@
34553461
4D1F9D19171C682E0091C6CB /* srvcgi.cpp in Sources */,
34563462
4D1F9D1A171C682E0091C6CB /* srvdebug.cpp in Sources */,
34573463
4D1F9D1C171C682E0091C6CB /* srvmain.cpp in Sources */,
3464+
E861167219D45AF50047E1BC /* color.cpp in Sources */,
34583465
4D1F9D1D171C682E0091C6CB /* srvscript.cpp in Sources */,
34593466
4D1F9D1E171C682E0091C6CB /* srvspec.cpp in Sources */,
34603467
4D1F9D1F171C682E0091C6CB /* srvstack.cpp in Sources */,
@@ -3835,6 +3842,7 @@
38353842
4D83871E1678B2C9003BEC7C /* ibmp.cpp in Sources */,
38363843
4D83871F1678B2C9003BEC7C /* image_rep_encoded.cpp in Sources */,
38373844
4D8387201678B2C9003BEC7C /* image_rep_mutable.cpp in Sources */,
3845+
E861167119D45AF50047E1BC /* color.cpp in Sources */,
38383846
4D8387211678B2C9003BEC7C /* imagebitmap.cpp in Sources */,
38393847
4D8387221678B2C9003BEC7C /* irle.cpp in Sources */,
38403848
E8DDE5DF16C2B1A7007367E4 /* image_rep_resampled.cpp in Sources */,

engine/src/color.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* Copyright (C) 2003-2013 Runtime Revolution Ltd.
2+
3+
This file is part of LiveCode.
4+
5+
LiveCode is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License v3 as published by the Free
7+
Software Foundation.
8+
9+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
16+
17+
// IM-2014-09-24: [[ Bug 13208 ]] Shared code to convert from Linear RGB color space to CIE 1931 XYZ
18+
19+
#include "core.h"
20+
#include "graphics.h"
21+
#include "color.h"
22+
23+
////////////////////////////////////////////////////////////////////////////////
24+
25+
MCColorVector3 MCColorVector3ScalarMultiply(const MCColorVector3 &p_vector, MCGFloat p_scalar)
26+
{
27+
return MCColorVector3Make(p_vector.x * p_scalar, p_vector.y * p_scalar, p_vector.z * p_scalar);
28+
}
29+
30+
void MCColorMatrix3x3Set(MCColorMatrix3x3 &x_matrix,
31+
MCGFloat a, MCGFloat b, MCGFloat c,
32+
MCGFloat d, MCGFloat e, MCGFloat f,
33+
MCGFloat g, MCGFloat h, MCGFloat i)
34+
{
35+
x_matrix.m[0][0] = a;
36+
x_matrix.m[1][0] = b;
37+
x_matrix.m[2][0] = c;
38+
x_matrix.m[0][1] = d;
39+
x_matrix.m[1][1] = e;
40+
x_matrix.m[2][1] = f;
41+
x_matrix.m[0][2] = g;
42+
x_matrix.m[1][2] = h;
43+
x_matrix.m[2][2] = i;
44+
}
45+
46+
void MCColorMatrix3x3Copy(const MCColorMatrix3x3 &p_matrix, MCColorMatrix3x3 &r_copy)
47+
{
48+
MCMemoryCopy(&r_copy, &p_matrix, sizeof(MCColorMatrix3x3));
49+
}
50+
51+
bool MCColorMatrix3x3Inverse(const MCColorMatrix3x3 &p_matrix, MCColorMatrix3x3 &r_inverse)
52+
{
53+
MCGFloat a, b, c;
54+
a = p_matrix.m[1][1] * p_matrix.m[2][2] - p_matrix.m[1][2] * p_matrix.m[2][1];
55+
b = p_matrix.m[1][2] * p_matrix.m[2][0] - p_matrix.m[1][0] * p_matrix.m[2][2];
56+
c = p_matrix.m[1][0] * p_matrix.m[2][1] - p_matrix.m[1][1] * p_matrix.m[2][0];
57+
58+
MCGFloat t_det;
59+
t_det = p_matrix.m[0][0] * a + p_matrix.m[0][1] * b + p_matrix.m[0][2] * c;
60+
61+
if (t_det == 0.0)
62+
return false;
63+
64+
MCGFloat t_inv_det;
65+
t_inv_det = 1.0 / t_det;
66+
67+
r_inverse.m[0][0] = t_inv_det * a;
68+
r_inverse.m[0][1] = t_inv_det * (p_matrix.m[2][1] * p_matrix.m[0][2] - p_matrix.m[2][2] * p_matrix.m[0][1]);
69+
r_inverse.m[0][2] = t_inv_det * (p_matrix.m[0][1] * p_matrix.m[1][2] - p_matrix.m[0][2] * p_matrix.m[1][1]);
70+
r_inverse.m[1][0] = t_inv_det * b;
71+
r_inverse.m[1][1] = t_inv_det * (p_matrix.m[2][2] * p_matrix.m[0][0] - p_matrix.m[2][0] * p_matrix.m[0][2]);
72+
r_inverse.m[1][2] = t_inv_det * (p_matrix.m[0][2] * p_matrix.m[1][0] - p_matrix.m[0][0] * p_matrix.m[1][2]);
73+
r_inverse.m[2][0] = t_inv_det * c;
74+
r_inverse.m[2][1] = t_inv_det * (p_matrix.m[2][0] * p_matrix.m[0][1] - p_matrix.m[2][1] * p_matrix.m[0][0]);
75+
r_inverse.m[2][2] = t_inv_det * (p_matrix.m[0][0] * p_matrix.m[1][1] - p_matrix.m[0][1] * p_matrix.m[1][0]);
76+
77+
return true;
78+
}
79+
80+
MCColorVector3 MCColorMatrix3x3MultiplyVector(const MCColorMatrix3x3 &p_matrix, const MCColorVector3 &p_vector)
81+
{
82+
return MCColorVector3Make(p_matrix.m[0][0] * p_vector.x + p_matrix.m[0][1] * p_vector.y + p_matrix.m[0][2] * p_vector.z,
83+
p_matrix.m[1][0] * p_vector.x + p_matrix.m[1][1] * p_vector.y + p_matrix.m[1][2] * p_vector.z,
84+
p_matrix.m[2][0] * p_vector.x + p_matrix.m[2][1] * p_vector.y + p_matrix.m[2][2] * p_vector.z);
85+
}
86+
87+
MCColorVector3 xy_to_xyz(const MCColorVector2 &p_xy)
88+
{
89+
return MCColorVector3Make(p_xy.x, p_xy.y, 1.0 - (p_xy.x + p_xy.y));
90+
}
91+
92+
bool MCColorTransformLinearRGBToXYZ(const MCColorVector2 &p_white, const MCColorVector2 &p_red, const MCColorVector2 &p_green, const MCColorVector2 &p_blue,
93+
MCColorVector3 &r_white, MCColorMatrix3x3 &r_matrix)
94+
{
95+
MCColorVector3 t_r, t_g, t_b, t_w;
96+
t_r = xy_to_xyz(p_red);
97+
t_g = xy_to_xyz(p_green);
98+
t_b = xy_to_xyz(p_blue);
99+
100+
t_w = xy_to_xyz(p_white);
101+
t_w = MCColorVector3ScalarMultiply(t_w, 1.0 / t_w.y);
102+
103+
MCColorMatrix3x3 t_matrix;
104+
MCColorMatrix3x3Set(t_matrix,
105+
t_r.x, t_r.y, t_r.z,
106+
t_g.x, t_g.y, t_g.z,
107+
t_b.x, t_b.y, t_b.z);
108+
109+
MCColorMatrix3x3 t_inverse;
110+
if (!MCColorMatrix3x3Inverse(t_matrix, t_inverse))
111+
return false;
112+
113+
MCColorVector3 t_scale;
114+
t_scale = MCColorMatrix3x3MultiplyVector(t_inverse, t_w);
115+
116+
t_matrix.m[0][0] *= t_scale.x;
117+
t_matrix.m[1][0] *= t_scale.x;
118+
t_matrix.m[2][0] *= t_scale.x;
119+
t_matrix.m[0][1] *= t_scale.y;
120+
t_matrix.m[1][1] *= t_scale.y;
121+
t_matrix.m[2][1] *= t_scale.y;
122+
t_matrix.m[0][2] *= t_scale.z;
123+
t_matrix.m[1][2] *= t_scale.z;
124+
t_matrix.m[2][2] *= t_scale.z;
125+
126+
// MCColorMatrix3x3Copy(t_matrix, r_matrix);
127+
r_matrix = t_matrix;
128+
r_white = t_w;
129+
130+
return true;
131+
}
132+
133+
////////////////////////////////////////////////////////////////////////////////

engine/src/color.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* Copyright (C) 2003-2013 Runtime Revolution Ltd.
2+
3+
This file is part of LiveCode.
4+
5+
LiveCode is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License v3 as published by the Free
7+
Software Foundation.
8+
9+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
16+
17+
////////////////////////////////////////////////////////////////////////////////
18+
19+
struct MCColorVector2
20+
{
21+
MCGFloat x;
22+
MCGFloat y;
23+
};
24+
25+
struct MCColorVector3
26+
{
27+
MCGFloat x;
28+
MCGFloat y;
29+
MCGFloat z;
30+
};
31+
32+
struct MCColorMatrix3x3
33+
{
34+
MCGFloat m[3][3];
35+
};
36+
37+
inline MCColorVector2 MCColorVector2Make(MCGFloat x, MCGFloat y)
38+
{
39+
MCColorVector2 t_vector;
40+
t_vector.x = x;
41+
t_vector.y = y;
42+
return t_vector;
43+
}
44+
45+
inline MCColorVector3 MCColorVector3Make(MCGFloat x, MCGFloat y, MCGFloat z)
46+
{
47+
MCColorVector3 t_vector;
48+
t_vector.x = x;
49+
t_vector.y = y;
50+
t_vector.z = z;
51+
return t_vector;
52+
}
53+
54+
inline void MCColorMatrix3x3GetElements(const MCColorMatrix3x3 &p_matrix, MCGFloat r_values[9])
55+
{
56+
r_values[0] = p_matrix.m[0][0];
57+
r_values[1] = p_matrix.m[1][0];
58+
r_values[2] = p_matrix.m[2][0];
59+
r_values[3] = p_matrix.m[0][1];
60+
r_values[4] = p_matrix.m[1][1];
61+
r_values[5] = p_matrix.m[2][1];
62+
r_values[6] = p_matrix.m[0][2];
63+
r_values[7] = p_matrix.m[1][2];
64+
r_values[8] = p_matrix.m[2][2];
65+
}
66+
67+
//////////
68+
69+
bool MCColorTransformLinearRGBToXYZ(const MCColorVector2 &p_white, const MCColorVector2 &p_red, const MCColorVector2 &p_green, const MCColorVector2 &p_blue,
70+
MCColorVector3 &r_white, MCColorMatrix3x3 &r_matrix);
71+
72+
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)