#include "src/skcms_public.h"
#include "src/skcms_internals.h"
#include "src/skcms_Transform.h"
#include <assert.h>
#include <float.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#if defined(__ARM_NEON)
#include <arm_neon.h>
#elif defined(__SSE__)
#include <immintrin.h>
#if defined(__clang__)
#include <smmintrin.h>
#include <avxintrin.h>
#include <avx2intrin.h>
#include <avx512fintrin.h>
#include <avx512dqintrin.h>
#endif
#endif
usingnamespaceskcms_private;
static bool sAllowRuntimeCPUDetection = …;
void skcms_DisableRuntimeCPUDetection() { … }
static float log2f_(float x) { … }
static float logf_(float x) { … }
static float exp2f_(float x) { … }
float powf_(float x, float y) { … }
static float expf_(float x) { … }
static float fmaxf_(float x, float y) { … }
static float fminf_(float x, float y) { … }
static bool isfinitef_(float x) { … }
static float minus_1_ulp(float x) { … }
struct TF_PQish { … };
struct TF_HLGish { … };
static float TFKind_marker(skcms_TFType kind) { … }
static skcms_TFType classify(const skcms_TransferFunction& tf, TF_PQish* pq = nullptr
, TF_HLGish* hlg = nullptr) { … }
skcms_TFType skcms_TransferFunction_getType(const skcms_TransferFunction* tf) { … }
bool skcms_TransferFunction_isSRGBish(const skcms_TransferFunction* tf) { … }
bool skcms_TransferFunction_isPQish(const skcms_TransferFunction* tf) { … }
bool skcms_TransferFunction_isHLGish(const skcms_TransferFunction* tf) { … }
bool skcms_TransferFunction_makePQish(skcms_TransferFunction* tf,
float A, float B, float C,
float D, float E, float F) { … }
bool skcms_TransferFunction_makeScaledHLGish(skcms_TransferFunction* tf,
float K, float R, float G,
float a, float b, float c) { … }
float skcms_TransferFunction_eval(const skcms_TransferFunction* tf, float x) { … }
static float eval_curve(const skcms_Curve* curve, float x) { … }
float skcms_MaxRoundtripError(const skcms_Curve* curve, const skcms_TransferFunction* inv_tf) { … }
bool skcms_AreApproximateInverses(const skcms_Curve* curve, const skcms_TransferFunction* inv_tf) { … }
enum { … };
static uint16_t read_big_u16(const uint8_t* ptr) { … }
static uint32_t read_big_u32(const uint8_t* ptr) { … }
static int32_t read_big_i32(const uint8_t* ptr) { … }
static float read_big_fixed(const uint8_t* ptr) { … }
header_Layout;
tag_Layout;
static const tag_Layout* get_tag_table(const skcms_ICCProfile* profile) { … }
sf32_Layout;
bool skcms_GetCHAD(const skcms_ICCProfile* profile, skcms_Matrix3x3* m) { … }
XYZ_Layout;
static bool read_tag_xyz(const skcms_ICCTag* tag, float* x, float* y, float* z) { … }
bool skcms_GetWTPT(const skcms_ICCProfile* profile, float xyz[3]) { … }
static int data_color_space_channel_count(uint32_t data_color_space) { … }
int skcms_GetInputChannelCount(const skcms_ICCProfile* profile) { … }
static bool read_to_XYZD50(const skcms_ICCTag* rXYZ, const skcms_ICCTag* gXYZ,
const skcms_ICCTag* bXYZ, skcms_Matrix3x3* toXYZ) { … }
para_Layout;
static bool read_curve_para(const uint8_t* buf, uint32_t size,
skcms_Curve* curve, uint32_t* curve_size) { … }
curv_Layout;
static bool read_curve_curv(const uint8_t* buf, uint32_t size,
skcms_Curve* curve, uint32_t* curve_size) { … }
static bool read_curve(const uint8_t* buf, uint32_t size,
skcms_Curve* curve, uint32_t* curve_size) { … }
mft_CommonLayout;
mft1_Layout;
mft2_Layout;
static bool read_mft_common(const mft_CommonLayout* mftTag, skcms_A2B* a2b) { … }
static bool read_mft_common(const mft_CommonLayout* mftTag, skcms_B2A* b2a) { … }
template <typename A2B_or_B2A>
static bool init_tables(const uint8_t* table_base, uint64_t max_tables_len, uint32_t byte_width,
uint32_t input_table_entries, uint32_t output_table_entries,
A2B_or_B2A* out) { … }
template <typename A2B_or_B2A>
static bool read_tag_mft1(const skcms_ICCTag* tag, A2B_or_B2A* out) { … }
template <typename A2B_or_B2A>
static bool read_tag_mft2(const skcms_ICCTag* tag, A2B_or_B2A* out) { … }
static bool read_curves(const uint8_t* buf, uint32_t size, uint32_t curve_offset,
uint32_t num_curves, skcms_Curve* curves) { … }
mAB_or_mBA_Layout;
CLUT_Layout;
static bool read_tag_mab(const skcms_ICCTag* tag, skcms_A2B* a2b, bool pcs_is_xyz) { … }
static bool read_tag_mba(const skcms_ICCTag* tag, skcms_B2A* b2a, bool pcs_is_xyz) { … }
static int fit_linear(const skcms_Curve* curve, int N, float tol,
float* c, float* d, float* f = nullptr) { … }
static void canonicalize_identity(skcms_Curve* curve) { … }
static bool read_a2b(const skcms_ICCTag* tag, skcms_A2B* a2b, bool pcs_is_xyz) { … }
static bool read_b2a(const skcms_ICCTag* tag, skcms_B2A* b2a, bool pcs_is_xyz) { … }
CICP_Layout;
static bool read_cicp(const skcms_ICCTag* tag, skcms_CICP* cicp) { … }
void skcms_GetTagByIndex(const skcms_ICCProfile* profile, uint32_t idx, skcms_ICCTag* tag) { … }
bool skcms_GetTagBySignature(const skcms_ICCProfile* profile, uint32_t sig, skcms_ICCTag* tag) { … }
static bool usable_as_src(const skcms_ICCProfile* profile) { … }
bool skcms_ParseWithA2BPriority(const void* buf, size_t len,
const int priority[], const int priorities,
skcms_ICCProfile* profile) { … }
const skcms_ICCProfile* skcms_sRGB_profile() { … }
const skcms_ICCProfile* skcms_XYZD50_profile() { … }
const skcms_TransferFunction* skcms_sRGB_TransferFunction() { … }
const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction() { … }
const skcms_TransferFunction* skcms_Identity_TransferFunction() { … }
const uint8_t skcms_252_random_bytes[] = …;
bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A, const skcms_ICCProfile* B) { … }
bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile* profile,
const skcms_TransferFunction* inv_tf) { … }
static bool is_zero_to_one(float x) { … }
skcms_Vector3;
static skcms_Vector3 mv_mul(const skcms_Matrix3x3* m, const skcms_Vector3* v) { … }
bool skcms_AdaptToXYZD50(float wx, float wy,
skcms_Matrix3x3* toXYZD50) { … }
bool skcms_PrimariesToXYZD50(float rx, float ry,
float gx, float gy,
float bx, float by,
float wx, float wy,
skcms_Matrix3x3* toXYZD50) { … }
bool skcms_Matrix3x3_invert(const skcms_Matrix3x3* src, skcms_Matrix3x3* dst) { … }
skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3* A, const skcms_Matrix3x3* B) { … }
#if defined(__clang__)
[[clang::no_sanitize("float-divide-by-zero")]]
#endif
bool skcms_TransferFunction_invert(const skcms_TransferFunction* src, skcms_TransferFunction* dst) { … }
static float rg_nonlinear(float x,
const skcms_Curve* curve,
const skcms_TransferFunction* tf,
float dfdP[3]) { … }
static bool gauss_newton_step(const skcms_Curve* curve,
skcms_TransferFunction* tf,
float x0, float dx, int N) { … }
static float max_roundtrip_error_checked(const skcms_Curve* curve,
const skcms_TransferFunction* tf_inv) { … }
static bool fit_nonlinear(const skcms_Curve* curve, int L, int N, skcms_TransferFunction* tf) { … }
bool skcms_ApproximateCurve(const skcms_Curve* curve,
skcms_TransferFunction* approx,
float* max_error) { … }
enum class CpuType { … };
static CpuType cpu_type() { … }
static bool tf_is_gamma(const skcms_TransferFunction& tf) { … }
struct OpAndArg { … };
static OpAndArg select_curve_op(const skcms_Curve* curve, int channel) { … }
static int select_curve_ops(const skcms_Curve* curves, int numChannels, OpAndArg* ops) { … }
static size_t bytes_per_pixel(skcms_PixelFormat fmt) { … }
static bool prep_for_destination(const skcms_ICCProfile* profile,
skcms_Matrix3x3* fromXYZD50,
skcms_TransferFunction* invR,
skcms_TransferFunction* invG,
skcms_TransferFunction* invB) { … }
bool skcms_Transform(const void* src,
skcms_PixelFormat srcFmt,
skcms_AlphaFormat srcAlpha,
const skcms_ICCProfile* srcProfile,
void* dst,
skcms_PixelFormat dstFmt,
skcms_AlphaFormat dstAlpha,
const skcms_ICCProfile* dstProfile,
size_t nz) { … }
static void assert_usable_as_destination(const skcms_ICCProfile* profile) { … }
bool skcms_MakeUsableAsDestination(skcms_ICCProfile* profile) { … }
bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile) { … }