convert skcms to c++
The main thing we do here is add a 'c' to the skcms source path.
The rest is build system updates and little language tweaks.
I have had to explicitly set -ffp-contract=off in GCC. Switching
from C11 to C++11 changed the default -ffp-contract from "off" to
"fast", which generates FMAs in places we don't want them. This
behavior is rooted in this lovely piece of code:
/* ISO C restricts floating-point expression contraction to within
source-language expressions (-ffp-contract=on, currently an alias
for -ffp-contract=off). */
if (flag_iso
&& !c_dialect_cxx ()
&& (global_options_set.x_flag_fp_contract_mode
== (enum fp_contract_mode) 0)
&& flag_unsafe_math_optimizations == 0)
flag_fp_contract_mode = FP_CONTRACT_OFF;
Change-Id: Ica2d83b8dadce72fffe298b517bd34cdc609f49e
Reviewed-on: https://skia-review.googlesource.com/139167
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: Mike Klein <mtklein@chromium.org>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/build/android-arm-gcc b/build/android-arm-gcc
index 2dc13d2..1b1c452 100644
--- a/build/android-arm-gcc
+++ b/build/android-arm-gcc
@@ -5,7 +5,6 @@
cc = $ndk/toolchains/${target}-4.9/prebuilt/*/bin/${target}-gcc
cflags = -fdiagnostics-color -Wall -Wextra $
- -std=c11 $
-march=armv7-a -mfpu=neon -mthumb -mfloat-abi=softfp $
--sysroot $ndk/sysroot $
-I $ndk/sysroot/usr/include/$target
diff --git a/build/clang.xsan b/build/clang.xsan
index 014fec4..e28fb3a 100644
--- a/build/clang.xsan
+++ b/build/clang.xsan
@@ -1,4 +1,4 @@
mode = .xsan
extra_cflags = -fsanitize=address,integer,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,integer,undefined
+extra_ldflags = -fsanitize=address,integer,undefined -lc++
include build/clang
diff --git a/build/common b/build/common
index 8f28220..20baea5 100644
--- a/build/common
+++ b/build/common
@@ -10,8 +10,23 @@
-Wno-padded $
-Wno-reserved-id-macro $
-rule compile
- command = $disabled && touch $out || $cc -g $warnings -Os $cflags $extra_cflags $
+warnings_cc = $warnings $
+ -Wno-c++98-compat-pedantic $
+ -Wno-c99-extensions $
+ -Wno-gnu-anonymous-struct $
+ -Wno-narrowing $
+ -Wno-old-style-cast $
+
+
+rule compile_c
+ command = $disabled && touch $out || $cc -std=c11 -g -Os $warnings $cflags $extra_cflags $
+ -MD -MF $out.d -c $in -o $out
+ depfile = $out.d
+ deps = gcc
+ description = compile $out
+
+rule compile_cc
+ command = $disabled && touch $out || $cc -std=c++11 -g -Os $warnings_cc $cflags $extra_cflags $
-MD -MF $out.d -c $in -o $out
depfile = $out.d
deps = gcc
diff --git a/build/gcc b/build/gcc
index d60d469..2b6e1f9 100644
--- a/build/gcc
+++ b/build/gcc
@@ -1,5 +1,5 @@
cc = gcc
-cflags = -std=c11 -fdiagnostics-color -Wall -Wextra -fstack-usage
+cflags = -fdiagnostics-color -Wall -Wextra -ffp-contract=off -fstack-usage
out = out/gcc$mode
include build/local
diff --git a/build/gcc.xsan b/build/gcc.xsan
index 150ce07..a53f6ec 100644
--- a/build/gcc.xsan
+++ b/build/gcc.xsan
@@ -1,4 +1,4 @@
mode = .xsan
extra_cflags = -fsanitize=address,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,undefined
+extra_ldflags = -fsanitize=address,undefined -lstdc++
include build/gcc
diff --git a/build/msvs b/build/msvs
index 2d87d37..1c2f64e 100644
--- a/build/msvs
+++ b/build/msvs
@@ -8,7 +8,13 @@
command = cmd /c ""$in" > "$out""
description = run $in
-rule compile
+rule compile_c
+ command = $cl /c /showIncludes /nologo /Zi /WX /MT /Fo"$out" /Fd"$out.pdb" $
+ $cflags $extra_cflags $in
+ deps = msvc
+ description = compile $out
+
+rule compile_cc
command = $cl /c /showIncludes /nologo /Zi /WX /MT /Fo"$out" /Fd"$out.pdb" $
$cflags $extra_cflags $in
deps = msvc
diff --git a/build/targets b/build/targets
index 5e2c5f8..54ff8c9 100644
--- a/build/targets
+++ b/build/targets
@@ -1,30 +1,30 @@
-build $out/skcms.o: compile skcms.c
+build $out/skcms.o: compile_cc skcms.cc
-build $out/test_only.o: compile test_only.c
+build $out/test_only.o: compile_c test_only.c
-build $out/tests.o: compile tests.c
+build $out/tests.o: compile_c tests.c
build $out/tests$exe: link $out/skcms.o $out/tests.o $out/test_only.o
build $out/tests.ok: run $out/tests$exe
-build $out/bench.o: compile bench.c
+build $out/bench.o: compile_c bench.c
build $out/bench$exe: link $out/skcms.o $out/bench.o
-build $out/iccdump.o: compile iccdump.c
+build $out/iccdump.o: compile_c iccdump.c
build $out/iccdump$exe: link $out/skcms.o $out/iccdump.o $out/test_only.o
-build $out/fuzz/fuzz_main.o: compile fuzz/fuzz_main.c
+build $out/fuzz/fuzz_main.o: compile_c fuzz/fuzz_main.c
-build $out/fuzz/fuzz_iccprofile_atf.o: compile fuzz/fuzz_iccprofile_atf.c
-build $out/fuzz_iccprofile_atf$exe: link $out/fuzz/fuzz_iccprofile_atf.o $
- $out/fuzz/fuzz_main.o $
- $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_atf.o: compile_c fuzz/fuzz_iccprofile_atf.c
+build $out/fuzz_iccprofile_atf$exe: link $out/fuzz/fuzz_iccprofile_atf.o $
+ $out/fuzz/fuzz_main.o $
+ $out/skcms.o
-build $out/fuzz/fuzz_iccprofile_info.o: compile fuzz/fuzz_iccprofile_info.c
-build $out/fuzz_iccprofile_info$exe: link $out/fuzz/fuzz_iccprofile_info.o $
- $out/fuzz/fuzz_main.o $
- $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_info.o: compile_c fuzz/fuzz_iccprofile_info.c
+build $out/fuzz_iccprofile_info$exe: link $out/fuzz/fuzz_iccprofile_info.o $
+ $out/fuzz/fuzz_main.o $
+ $out/skcms.o
-build $out/fuzz/fuzz_iccprofile_transform.o: compile fuzz/fuzz_iccprofile_transform.c
-build $out/fuzz_iccprofile_transform$exe: link $out/fuzz/fuzz_iccprofile_transform.o $
- $out/fuzz/fuzz_main.o $
- $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_transform.o: compile_c fuzz/fuzz_iccprofile_transform.c
+build $out/fuzz_iccprofile_transform$exe: link $out/fuzz/fuzz_iccprofile_transform.o $
+ $out/fuzz/fuzz_main.o $
+ $out/skcms.o
diff --git a/skcms.c b/skcms.cc
similarity index 96%
rename from skcms.c
rename to skcms.cc
index 99b05cb..9c62fe4 100644
--- a/skcms.c
+++ b/skcms.cc
@@ -364,7 +364,7 @@
curve->parametric.g = read_big_u16(curvTag->parameters) * (1.0f / 256.0f);
}
} else {
- curve->table_8 = NULL;
+ curve->table_8 = nullptr;
curve->table_16 = curvTag->parameters;
curve->table_entries = value_count;
}
@@ -373,7 +373,7 @@
}
// Parses both curveType and parametricCurveType data. Ensures that at most 'size' bytes are read.
-// If curve_size is not NULL, writes the number of bytes used by the curve in (*curve_size).
+// If curve_size is not nullptr, writes the number of bytes used by the curve in (*curve_size).
static bool read_curve(const uint8_t* buf, uint32_t size,
skcms_Curve* curve, uint32_t* curve_size) {
if (!buf || size < 4 || !curve) {
@@ -469,18 +469,18 @@
a2b->input_curves[i].table_entries = input_table_entries;
if (byte_width == 1) {
a2b->input_curves[i].table_8 = table_base + i * byte_len_per_input_table;
- a2b->input_curves[i].table_16 = NULL;
+ a2b->input_curves[i].table_16 = nullptr;
} else {
- a2b->input_curves[i].table_8 = NULL;
+ a2b->input_curves[i].table_8 = nullptr;
a2b->input_curves[i].table_16 = table_base + i * byte_len_per_input_table;
}
}
if (byte_width == 1) {
a2b->grid_8 = table_base + byte_len_all_input_tables;
- a2b->grid_16 = NULL;
+ a2b->grid_16 = nullptr;
} else {
- a2b->grid_8 = NULL;
+ a2b->grid_8 = nullptr;
a2b->grid_16 = table_base + byte_len_all_input_tables;
}
@@ -489,9 +489,9 @@
a2b->output_curves[i].table_entries = output_table_entries;
if (byte_width == 1) {
a2b->output_curves[i].table_8 = output_table_base + i * byte_len_per_output_table;
- a2b->output_curves[i].table_16 = NULL;
+ a2b->output_curves[i].table_16 = nullptr;
} else {
- a2b->output_curves[i].table_8 = NULL;
+ a2b->output_curves[i].table_8 = nullptr;
a2b->output_curves[i].table_16 = output_table_base + i * byte_len_per_output_table;
}
}
@@ -674,9 +674,9 @@
if (clut->grid_byte_width[0] == 1) {
a2b->grid_8 = clut->data;
- a2b->grid_16 = NULL;
+ a2b->grid_16 = nullptr;
} else if (clut->grid_byte_width[0] == 2) {
- a2b->grid_8 = NULL;
+ a2b->grid_8 = nullptr;
a2b->grid_16 = clut->data;
} else {
return false;
@@ -770,16 +770,16 @@
// Detect and canonicalize identity tables.
skcms_Curve* curves[] = {
- a2b->input_channels > 0 ? a2b->input_curves + 0 : NULL,
- a2b->input_channels > 1 ? a2b->input_curves + 1 : NULL,
- a2b->input_channels > 2 ? a2b->input_curves + 2 : NULL,
- a2b->input_channels > 3 ? a2b->input_curves + 3 : NULL,
- a2b->matrix_channels > 0 ? a2b->matrix_curves + 0 : NULL,
- a2b->matrix_channels > 1 ? a2b->matrix_curves + 1 : NULL,
- a2b->matrix_channels > 2 ? a2b->matrix_curves + 2 : NULL,
- a2b->output_channels > 0 ? a2b->output_curves + 0 : NULL,
- a2b->output_channels > 1 ? a2b->output_curves + 1 : NULL,
- a2b->output_channels > 2 ? a2b->output_curves + 2 : NULL,
+ a2b->input_channels > 0 ? a2b->input_curves + 0 : nullptr,
+ a2b->input_channels > 1 ? a2b->input_curves + 1 : nullptr,
+ a2b->input_channels > 2 ? a2b->input_curves + 2 : nullptr,
+ a2b->input_channels > 3 ? a2b->input_curves + 3 : nullptr,
+ a2b->matrix_channels > 0 ? a2b->matrix_curves + 0 : nullptr,
+ a2b->matrix_channels > 1 ? a2b->matrix_curves + 1 : nullptr,
+ a2b->matrix_channels > 2 ? a2b->matrix_curves + 2 : nullptr,
+ a2b->output_channels > 0 ? a2b->output_curves + 0 : nullptr,
+ a2b->output_channels > 1 ? a2b->output_curves + 1 : nullptr,
+ a2b->output_channels > 2 ? a2b->output_curves + 2 : nullptr,
};
for (int i = 0; i < ARRAY_COUNT(curves); i++) {
@@ -793,9 +793,9 @@
&& c == 1.0f
&& f == 0.0f) {
curve->table_entries = 0;
- curve->table_8 = NULL;
- curve->table_16 = NULL;
- curve->parametric = (skcms_TransferFunction){1,1,0,0,0,0,0};
+ curve->table_8 = nullptr;
+ curve->table_16 = nullptr;
+ curve->parametric = skcms_TransferFunction{1,1,0,0,0,0,0};
}
}
}
@@ -896,7 +896,7 @@
skcms_ICCTag kTRC;
if (profile->data_color_space == skcms_Signature_Gray &&
skcms_GetTagBySignature(profile, skcms_Signature_kTRC, &kTRC)) {
- if (!read_curve(kTRC.buf, kTRC.size, &profile->trc[0], NULL)) {
+ if (!read_curve(kTRC.buf, kTRC.size, &profile->trc[0], nullptr)) {
// Malformed tag
return false;
}
@@ -915,9 +915,9 @@
if (skcms_GetTagBySignature(profile, skcms_Signature_rTRC, &rTRC) &&
skcms_GetTagBySignature(profile, skcms_Signature_gTRC, &gTRC) &&
skcms_GetTagBySignature(profile, skcms_Signature_bTRC, &bTRC)) {
- if (!read_curve(rTRC.buf, rTRC.size, &profile->trc[0], NULL) ||
- !read_curve(gTRC.buf, gTRC.size, &profile->trc[1], NULL) ||
- !read_curve(bTRC.buf, bTRC.size, &profile->trc[2], NULL)) {
+ if (!read_curve(rTRC.buf, rTRC.size, &profile->trc[0], nullptr) ||
+ !read_curve(gTRC.buf, gTRC.size, &profile->trc[1], nullptr) ||
+ !read_curve(bTRC.buf, bTRC.size, &profile->trc[2], nullptr)) {
// Malformed TRC tags
return false;
}
@@ -960,7 +960,7 @@
const skcms_ICCProfile* skcms_sRGB_profile() {
static const skcms_ICCProfile sRGB_profile = {
- NULL, // buffer, moot here
+ nullptr, // buffer, moot here
0, // size, moot here
skcms_Signature_RGB, // data_color_space
@@ -993,8 +993,8 @@
{{0, {1,1, 0,0,0,0,0}}},
},
{0,0,0,0},
- NULL,
- NULL,
+ nullptr,
+ nullptr,
0,
{
@@ -1022,7 +1022,7 @@
const skcms_ICCProfile* skcms_XYZD50_profile() {
// Just like sRGB above, but with identity transfer functions and toXYZD50 matrix.
static const skcms_ICCProfile XYZD50_profile = {
- NULL, // buffer, moot here
+ nullptr, // buffer, moot here
0, // size, moot here
skcms_Signature_RGB, // data_color_space
@@ -1053,8 +1053,8 @@
{{0, {1,1, 0,0,0,0,0}}},
},
{0,0,0,0},
- NULL,
- NULL,
+ nullptr,
+ nullptr,
0,
{
@@ -1871,8 +1871,8 @@
#define U16 U16x16
#define U8 U8x16
- #define F0 (F){0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}
- #define F1 (F){1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}
+ #define F0 F{0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}
+ #define F1 F{1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}
#elif defined(__AVX__)
#define N 8
@@ -1883,8 +1883,8 @@
#define U16 U16x8
#define U8 U8x8
- #define F0 (F){0,0,0,0, 0,0,0,0}
- #define F1 (F){1,1,1,1, 1,1,1,1}
+ #define F0 F{0,0,0,0, 0,0,0,0}
+ #define F1 F{1,1,1,1, 1,1,1,1}
#else
#define N 4
@@ -1895,8 +1895,8 @@
#define U16 U16x4
#define U8 U8x4
- #define F0 (F){0,0,0,0}
- #define F1 (F){1,1,1,1}
+ #define F0 F{0,0,0,0}
+ #define F1 F{1,1,1,1}
#endif
#define NS(id) id
@@ -1924,8 +1924,8 @@
#define I32 I32x8
#define U16 U16x8
#define U8 U8x8
- #define F0 (F){0,0,0,0, 0,0,0,0}
- #define F1 (F){1,1,1,1, 1,1,1,1}
+ #define F0 F{0,0,0,0, 0,0,0,0}
+ #define F1 F{1,1,1,1, 1,1,1,1}
#define NS(id) id ## _hsw
#define ATTR __attribute__((target("avx2,f16c")))
@@ -2024,7 +2024,8 @@
}
static bool hsw_ok() {
- InitOnceExecuteOnce(&check_hsw_ok_once, check_hsw_ok_InitOnce_wrapper, NULL, NULL);
+ InitOnceExecuteOnce(&check_hsw_ok_once, check_hsw_ok_InitOnce_wrapper,
+ nullptr, nullptr);
return hsw_ok_;
}
#else
@@ -2059,16 +2060,16 @@
if (curve->table_entries == 0) {
return is_identity_tf(&curve->parametric)
- ? (OpAndArg){ Op_noop, NULL }
- : (OpAndArg){ ops[channel].parametric, &curve->parametric };
+ ? OpAndArg{ Op_noop, nullptr }
+ : OpAndArg{ ops[channel].parametric, &curve->parametric };
} else if (curve->table_8) {
- return (OpAndArg){ ops[channel].table_8, curve };
+ return OpAndArg{ ops[channel].table_8, curve };
} else if (curve->table_16) {
- return (OpAndArg){ ops[channel].table_16, curve };
+ return OpAndArg{ ops[channel].table_16, curve };
}
assert(false);
- return (OpAndArg){Op_noop,NULL};
+ return OpAndArg{Op_noop,nullptr};
}
static size_t bytes_per_pixel(skcms_PixelFormat fmt) {
diff --git a/skcms.gni b/skcms.gni
index 2cfe2fb..a3def6e 100644
--- a/skcms.gni
+++ b/skcms.gni
@@ -4,7 +4,7 @@
# found in the LICENSE file.
skcms_sources = [
- "skcms.c",
+ "skcms.cc",
"skcms.h",
"skcms_internal.h",
"src/Transform_inl.h",
diff --git a/src/Transform_inl.h b/src/Transform_inl.h
index 6dc2a79..09183bf 100644
--- a/src/Transform_inl.h
+++ b/src/Transform_inl.h
@@ -72,12 +72,12 @@
#elif defined(__clang__)
#define CAST(T, v) __builtin_convertvector((v), T)
#elif N == 4
- #define CAST(T, v) (T){(v)[0],(v)[1],(v)[2],(v)[3]}
+ #define CAST(T, v) T{(v)[0],(v)[1],(v)[2],(v)[3]}
#elif N == 8
- #define CAST(T, v) (T){(v)[0],(v)[1],(v)[2],(v)[3], (v)[4],(v)[5],(v)[6],(v)[7]}
+ #define CAST(T, v) T{(v)[0],(v)[1],(v)[2],(v)[3], (v)[4],(v)[5],(v)[6],(v)[7]}
#elif N == 16
- #define CAST(T, v) (T){(v)[0],(v)[1],(v)[ 2],(v)[ 3], (v)[ 4],(v)[ 5],(v)[ 6],(v)[ 7], \
- (v)[8],(v)[9],(v)[10],(v)[11], (v)[12],(v)[13],(v)[14],(v)[15]}
+ #define CAST(T, v) T{(v)[0],(v)[1],(v)[ 2],(v)[ 3], (v)[ 4],(v)[ 5],(v)[ 6],(v)[ 7], \
+ (v)[8],(v)[9],(v)[10],(v)[11], (v)[12],(v)[13],(v)[14],(v)[15]}
#endif
// When we convert from float to fixed point, it's very common to want to round,
@@ -247,28 +247,28 @@
#define STORE_3(p, v) (p)[0] = v
#define STORE_4(p, v) (p)[0] = v
#elif N == 4 && !defined(USING_NEON)
- #define LOAD_3(T, p) (T){(p)[0], (p)[3], (p)[6], (p)[ 9]}
- #define LOAD_4(T, p) (T){(p)[0], (p)[4], (p)[8], (p)[12]};
+ #define LOAD_3(T, p) T{(p)[0], (p)[3], (p)[6], (p)[ 9]}
+ #define LOAD_4(T, p) T{(p)[0], (p)[4], (p)[8], (p)[12]};
#define STORE_3(p, v) (p)[0] = (v)[0]; (p)[3] = (v)[1]; (p)[6] = (v)[2]; (p)[ 9] = (v)[3]
#define STORE_4(p, v) (p)[0] = (v)[0]; (p)[4] = (v)[1]; (p)[8] = (v)[2]; (p)[12] = (v)[3]
#elif N == 8
- #define LOAD_3(T, p) (T){(p)[0], (p)[3], (p)[6], (p)[ 9], (p)[12], (p)[15], (p)[18], (p)[21]}
- #define LOAD_4(T, p) (T){(p)[0], (p)[4], (p)[8], (p)[12], (p)[16], (p)[20], (p)[24], (p)[28]}
+ #define LOAD_3(T, p) T{(p)[0], (p)[3], (p)[6], (p)[ 9], (p)[12], (p)[15], (p)[18], (p)[21]}
+ #define LOAD_4(T, p) T{(p)[0], (p)[4], (p)[8], (p)[12], (p)[16], (p)[20], (p)[24], (p)[28]}
#define STORE_3(p, v) (p)[ 0] = (v)[0]; (p)[ 3] = (v)[1]; (p)[ 6] = (v)[2]; (p)[ 9] = (v)[3]; \
(p)[12] = (v)[4]; (p)[15] = (v)[5]; (p)[18] = (v)[6]; (p)[21] = (v)[7]
#define STORE_4(p, v) (p)[ 0] = (v)[0]; (p)[ 4] = (v)[1]; (p)[ 8] = (v)[2]; (p)[12] = (v)[3]; \
(p)[16] = (v)[4]; (p)[20] = (v)[5]; (p)[24] = (v)[6]; (p)[28] = (v)[7]
#elif N == 16
// TODO: revisit with AVX-512 gathers and scatters?
- #define LOAD_3(T, p) (T){(p)[ 0], (p)[ 3], (p)[ 6], (p)[ 9], \
- (p)[12], (p)[15], (p)[18], (p)[21], \
- (p)[24], (p)[27], (p)[30], (p)[33], \
- (p)[36], (p)[39], (p)[42], (p)[45]}
+ #define LOAD_3(T, p) T{(p)[ 0], (p)[ 3], (p)[ 6], (p)[ 9], \
+ (p)[12], (p)[15], (p)[18], (p)[21], \
+ (p)[24], (p)[27], (p)[30], (p)[33], \
+ (p)[36], (p)[39], (p)[42], (p)[45]}
- #define LOAD_4(T, p) (T){(p)[ 0], (p)[ 4], (p)[ 8], (p)[12], \
- (p)[16], (p)[20], (p)[24], (p)[28], \
- (p)[32], (p)[36], (p)[40], (p)[44], \
- (p)[48], (p)[52], (p)[56], (p)[60]}
+ #define LOAD_4(T, p) T{(p)[ 0], (p)[ 4], (p)[ 8], (p)[12], \
+ (p)[16], (p)[20], (p)[24], (p)[28], \
+ (p)[32], (p)[36], (p)[40], (p)[44], \
+ (p)[48], (p)[52], (p)[56], (p)[60]}
#define STORE_3(p, v) \
(p)[ 0] = (v)[ 0]; (p)[ 3] = (v)[ 1]; (p)[ 6] = (v)[ 2]; (p)[ 9] = (v)[ 3]; \
@@ -389,11 +389,11 @@
#if N == 1
*v = load_48_64(p,ix);
#elif N == 4
- *v = (U64){
+ *v = U64{
load_48_64(p,ix[0]), load_48_64(p,ix[1]), load_48_64(p,ix[2]), load_48_64(p,ix[3]),
};
#elif N == 8 && !defined(__AVX2__)
- *v = (U64){
+ *v = U64{
load_48_64(p,ix[0]), load_48_64(p,ix[1]), load_48_64(p,ix[2]), load_48_64(p,ix[3]),
load_48_64(p,ix[4]), load_48_64(p,ix[5]), load_48_64(p,ix[6]), load_48_64(p,ix[7]),
};