summaryrefslogtreecommitdiff
path: root/icc/icc.h
diff options
context:
space:
mode:
Diffstat (limited to 'icc/icc.h')
-rw-r--r--icc/icc.h429
1 files changed, 284 insertions, 145 deletions
diff --git a/icc/icc.h b/icc/icc.h
index 7c3a65b..ba66581 100644
--- a/icc/icc.h
+++ b/icc/icc.h
@@ -8,7 +8,7 @@
* Date: 1999/11/29
* Version: 2.15
*
- * Copyright 1997 - 2012 Graeme W. Gill
+ * Copyright 1997 - 2013 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
* see the License.txt file in this directory for licensing details.
@@ -30,8 +30,8 @@
/* Version of icclib release */
-#define ICCLIB_VERSION 0x020016
-#define ICCLIB_VERSION_STR "2.16"
+#define ICCLIB_VERSION 0x020017
+#define ICCLIB_VERSION_STR "2.17"
#undef ENABLE_V4 /* V4 is not fully implemented */
@@ -778,8 +778,20 @@ struct _icmLut {
/* inspace' -> outspace' transfer function */
double *clutmin, double *clutmax, /* Maximum range of outspace' values */
/* (NULL = default) */
- void (*outfunc)(void *cbntx, double *out, double *in));
+ void (*outfunc)(void *cbntx, double *out, double *in),
/* Output transfer function, outspace'->outspace (NULL = deflt) */
+ int *apxls_gmin, int *apxls_gmax /* If not NULL, the grid indexes not to be affected */
+ /* by ICM_CLUT_SET_APXLS, defaulting to 0..>clutPoints-1 */
+ );
+
+ /* Helper function to fine tune a single value interpolation */
+ /* Return 0 on success, 1 if input clipping occured, 2 if output clipping occured */
+ /* To guarantee the optimal function, an icmLuLut needs to be create. */
+ /* The default will be to assume simplex interpolation will be used. */
+ int (*tune_value) (
+ struct _icmLut *p, /* Pointer to Lut object */
+ double *out, /* Target value */
+ double *in); /* Input value */
}; typedef struct _icmLut icmLut;
@@ -792,27 +804,29 @@ struct _icmLut {
/* If ICM_CLUT_SET_FILTER is set, the per grid node filtering radius */
/* is returned in clutfunc out[-1], out[-2] etc for each table */
int icmSetMultiLutTables(
- int ntables, /* Number of tables to be set, 1..n */
- struct _icmLut **p, /* Pointer to Lut object */
- int flags, /* Setting flags */
- void *cbctx, /* Opaque callback context pointer value */
- icColorSpaceSignature insig, /* Input color space */
- icColorSpaceSignature outsig, /* Output color space */
+ int ntables, /* Number of tables to be set, 1..n */
+ struct _icmLut **p, /* Pointer to Lut object */
+ int flags, /* Setting flags */
+ void *cbctx, /* Opaque callback context pointer value */
+ icColorSpaceSignature insig, /* Input color space */
+ icColorSpaceSignature outsig, /* Output color space */
void (*infunc)(void *cbctx, double *out, double *in),
/* Input transfer function, inspace->inspace' (NULL = default) */
/* Will be called ntables times each input grid value */
- double *inmin, double *inmax, /* Maximum range of inspace' values */
- /* (NULL = default) */
+ double *inmin, double *inmax, /* Maximum range of inspace' values */
+ /* (NULL = default) */
void (*clutfunc)(void *cbntx, double *out, double *in),
/* inspace' -> outspace[ntables]' transfer function */
/* will be called once for each input' grid value, and */
/* ntables output values should be written consecutively */
/* to out[]. */
- double *clutmin, double *clutmax, /* Maximum range of outspace' values */
- /* (NULL = default) */
- void (*outfunc)(void *cbntx, double *out, double *in)
+ double *clutmin, double *clutmax, /* Maximum range of outspace' values */
+ /* (NULL = default) */
+ void (*outfunc)(void *cbntx, double *out, double *in),
/* Output transfer function, outspace'->outspace (NULL = deflt) */
/* Will be called ntables times on each output value */
+ int *apxls_gmin, int *apxls_gmax /* If not NULL, the grid indexes not to be affected */
+ /* by ICM_CLUT_SET_APXLS, defaulting to 0..>clutPoints-1 */
);
/* - - - - - - - - - - - - - - - - - - - - - */
@@ -1487,6 +1501,8 @@ struct _icc {
int errc; /* Error code */
int warnc; /* Warning code */
+ int allowclutPoints256; /* Non standard - allow 256 res cLUT */
+
/* Private: ? */
icmAlloc *al; /* Heap allocator */
int del_al; /* NZ if heap allocator should be deleted */
@@ -1652,135 +1668,9 @@ extern ICCLIB_API unsigned int icmCSSig2nchan(icColorSpaceSignature sig);
/* 1 if it is a colorant based colorspace, and 2 if it is not a colorant based space */
extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, char *cvals[]);
-
-/* Simple macro to transfer an array to an XYZ number */
-#define icmAry2XYZ(xyz, ary) ((xyz).X = (ary)[0], (xyz).Y = (ary)[1], (xyz).Z = (ary)[2])
-
-/* And the reverse */
-#define icmXYZ2Ary(ary, xyz) ((ary)[0] = (xyz).X, (ary)[1] = (xyz).Y, (ary)[2] = (xyz).Z)
-
-/* Simple macro to transfer an XYZ number to an XYZ number */
-#define icmXYZ2XYZ(d_xyz, s_xyz) ((d_xyz).X = (s_xyz).X, (d_xyz).Y = (s_xyz).Y, \
- (d_xyz).Z = (s_xyz).Z)
-
-/* Simple macro to transfer an 3array to 3array */
-/* Hmm. Same as icmCpy3 */
-#define icmAry2Ary(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \
- (d_ary)[2] = (s_ary)[2])
-
-/* CIE Y (range 0 .. 1) to perceptual CIE 1976 L* (range 0 .. 100) */
-double icmY2L(double val);
-
-/* Perceptual CIE 1976 L* (range 0 .. 100) to CIE Y (range 0 .. 1) */
-double icmL2Y(double val);
-
-/* CIE XYZ to perceptual Lab */
-extern ICCLIB_API void icmXYZ2Lab(icmXYZNumber *w, double *out, double *in);
-
-/* Perceptual Lab to CIE XYZ */
-extern ICCLIB_API void icmLab2XYZ(icmXYZNumber *w, double *out, double *in);
-
-/* LCh to Lab */
-extern ICCLIB_API void icmLCh2Lab(double *out, double *in);
-
-/* Lab to LCh */
-extern ICCLIB_API void icmLab2LCh(double *out, double *in);
-
-/* XYZ to Yxy */
-extern ICCLIB_API void icmXYZ2Yxy(double *out, double *in);
-
-/* Yxy to XYZ */
-extern ICCLIB_API void icmYxy2XYZ(double *out, double *in);
-
-/* CIE XYZ to perceptual Luv */
-extern ICCLIB_API void icmXYZ2Luv(icmXYZNumber *w, double *out, double *in);
-
-/* Perceptual Luv to CIE XYZ */
-extern ICCLIB_API void icmLuv2XYZ(icmXYZNumber *w, double *out, double *in);
-
-
-/* NOTE :- none of the following seven have been protected */
-/* against arithmmetic issues (ie. for black) */
-
-/* CIE XYZ to perceptual CIE 1976 UCS diagram Yu'v'*/
-/* (Yu'v' is a better chromaticity space than Yxy) */
-extern ICCLIB_API void icmXYZ21976UCS(double *out, double *in);
-
-/* Perceptual CIE 1976 UCS diagram Yu'v' to CIE XYZ */
-extern ICCLIB_API void icm1976UCS2XYZ(double *out, double *in);
-
-/* CIE XYZ to perceptual CIE 1960 UCS */
-/* (This was obsoleted by the 1976UCS, but is still used */
-/* in computing color temperatures.) */
-extern ICCLIB_API void icmXYZ21960UCS(double *out, double *in);
-
-/* Perceptual CIE 1960 UCS to CIE XYZ */
-extern ICCLIB_API void icm1960UCS2XYZ(double *out, double *in);
-
-/* CIE XYZ to perceptual CIE 1964 WUV (U*V*W*) */
-/* (This is obsolete but still used in computing CRI) */
-extern ICCLIB_API void icmXYZ21964WUV(icmXYZNumber *w, double *out, double *in);
-
-/* Perceptual CIE 1964 WUV (U*V*W*) to CIE XYZ */
-extern ICCLIB_API void icm1964WUV2XYZ(icmXYZNumber *w, double *out, double *in);
-
-/* CIE CIE1960 UCS to perceptual CIE 1964 WUV (U*V*W*) */
-extern ICCLIB_API void icm1960UCS21964WUV(icmXYZNumber *w, double *out, double *in);
-
-
-/* The standard D50 illuminant value */
-extern icmXYZNumber icmD50;
-extern icmXYZNumber icmD50_100; /* Scaled to 100 */
-double icmD50_ary3[3]; /* As an array */
-double icmD50_100_ary3[3]; /* Scaled to 100 as an array */
-
-/* The standard D65 illuminant value */
-extern icmXYZNumber icmD65;
-extern icmXYZNumber icmD65_100; /* Scaled to 100 */
-double icmD65_ary3[3]; /* As an array */
-double icmD65_100_ary3[3]; /* Scaled to 100 as an array */
-
-/* The default black value */
-extern icmXYZNumber icmBlack;
-
-
-/* Initialise a pseudo-hilbert grid counter, return total usable count. */
-extern ICCLIB_API unsigned psh_init(psh *p, int di, unsigned int res, int co[]);
-
-/* Reset the counter */
-extern ICCLIB_API void psh_reset(psh *p);
-
-/* Increment pseudo-hilbert coordinates */
-/* Return non-zero if count rolls over to 0 */
-extern ICCLIB_API int psh_inc(psh *p, int co[]);
-
-
-/* RGB primaries to device to RGB->XYZ transform matrix */
-/* Return non-zero if matrix would be singular */
-int icmRGBprim2matrix(
- icmXYZNumber white, /* White point */
- icmXYZNumber red, /* Red colorant */
- icmXYZNumber green, /* Green colorant */
- icmXYZNumber blue, /* Blue colorant */
- double mat[3][3] /* Destination matrix */
-);
-
-/* Chromatic Adaption transform utility */
-/* Return a 3x3 chromatic adaption matrix */
-/* Use icmMulBy3x3(dst, mat, src) */
-
-#define ICM_CAM_BRADFORD 0x0001 /* Use Bradford sharpened response space */
-#define ICM_CAM_MULMATRIX 0x0002 /* Transform the given matrix */
-
-void icmChromAdaptMatrix(
- int flags, /* Flags as defined below */
- icmXYZNumber d_wp, /* Destination white point */
- icmXYZNumber s_wp, /* Source white point */
- double mat[3][3] /* Destination matrix */
-);
-
/* - - - - - - - - - - - - - - */
-/* Set a 3 vector */
+
+/* Set a 3 vector to the same value */
#define icmSet3(d_ary, s_val) ((d_ary)[0] = (s_val), (d_ary)[1] = (s_val), \
(d_ary)[2] = (s_val))
@@ -1801,6 +1691,16 @@ void icmSub3(double out[3], double in1[3], double in2[3]);
#define ICMSUB3(o, i, j) ((o)[0] = (i)[0] - (j)[0], (o)[1] = (i)[1] - (j)[1], (o)[2] = (i)[2] - (j)[2])
+/* Divide two 3 vectors, out = in1/in2 */
+void icmDiv3(double out[3], double in1[3], double in2[3]);
+
+#define ICMDIV3(o, i, j) ((o)[0] = (i)[0]/(j)[0], (o)[1] = (i)[1]/(j)[1], (o)[2] = (i)[2]/(j)[2])
+
+/* Multiply two 3 vectors, out = in1 * in2 */
+void icmMul3(double out[3], double in1[3], double in2[3]);
+
+#define ICMMUL3(o, i, j) ((o)[0] = (i)[0] * (j)[0], (o)[1] = (i)[1] * (j)[1], (o)[2] = (i)[2] * (j)[2])
+
/* Compute the dot product of two 3 vectors */
double icmDot3(double in1[3], double in2[3]);
@@ -1822,10 +1722,13 @@ double icmNorm3(double in[3]);
/* Scale a 3 vector by the given ratio */
void icmScale3(double out[3], double in[3], double rat);
+#define ICMSCALE3(o, i, j) ((o)[0] = (i)[0] * (j), (o)[1] = (i)[1] * (j), (o)[2] = (i)[2] * (j))
+
/* Compute a blend between in0 and in1 */
void icmBlend3(double out[3], double in0[3], double in1[3], double bf);
-#define ICMSCALE3(o, i, j) ((o)[0] = (i)[0] * (j), (o)[1] = (i)[1] * (j), (o)[2] = (i)[2] * (j))
+/* Clip a vector to the range 0.0 .. 1.0 */
+void icmClip3(double out[3], double in[3]);
/* Normalise a 3 vector to the given length. Return nz if not normalisable */
int icmNormalize3(double out[3], double in[3], double len);
@@ -1922,9 +1825,128 @@ double icmPlaneDist3(double eq[4], double p[3]);
/* - - - - - - - - - - - - - - - - - - - - - - - */
+/* Given 2 2D points, compute a plane equation. */
+/* The normal will be right handed given the order of the points */
+/* The plane equation will be the 2 normal components and the constant. */
+/* Return nz if any points are cooincident or co-linear */
+int icmPlaneEqn2(double eq[3], double p0[2], double p1[2]);
+
+/* Given a 2D point and a plane equation, return the signed */
+/* distance from the plane */
+double icmPlaneDist2(double eq[3], double p[2]);
+
+/* Given two infinite 2D lines define by two pairs of points, compute the intersection. */
+/* Return nz if there is no intersection (lines are parallel) */
+int icmLineIntersect2(double res[2], double p1[2], double p2[2], double p3[2], double p4[2]);
+
/* Multiply 2 array by 2x2 transform matrix */
void icmMulBy2x2(double out[2], double mat[2][2], double in[2]);
+/* - - - - - - - - - - - - - - */
+
+/* Simple macro to transfer an array to an XYZ number */
+#define icmAry2XYZ(xyz, ary) ((xyz).X = (ary)[0], (xyz).Y = (ary)[1], (xyz).Z = (ary)[2])
+
+/* And the reverse */
+#define icmXYZ2Ary(ary, xyz) ((ary)[0] = (xyz).X, (ary)[1] = (xyz).Y, (ary)[2] = (xyz).Z)
+
+/* Simple macro to transfer an XYZ number to an XYZ number */
+#define icmXYZ2XYZ(d_xyz, s_xyz) ((d_xyz).X = (s_xyz).X, (d_xyz).Y = (s_xyz).Y, \
+ (d_xyz).Z = (s_xyz).Z)
+
+/* Simple macro to transfer an 3array to 3array */
+/* Hmm. Same as icmCpy3 */
+#define icmAry2Ary(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \
+ (d_ary)[2] = (s_ary)[2])
+
+/* CIE Y (range 0 .. 1) to perceptual CIE 1976 L* (range 0 .. 100) */
+double icmY2L(double val);
+
+/* Perceptual CIE 1976 L* (range 0 .. 100) to CIE Y (range 0 .. 1) */
+double icmL2Y(double val);
+
+/* CIE XYZ to perceptual Lab */
+extern ICCLIB_API void icmXYZ2Lab(icmXYZNumber *w, double *out, double *in);
+
+/* Perceptual Lab to CIE XYZ */
+extern ICCLIB_API void icmLab2XYZ(icmXYZNumber *w, double *out, double *in);
+
+/* LCh to Lab */
+extern ICCLIB_API void icmLCh2Lab(double *out, double *in);
+
+/* Lab to LCh */
+extern ICCLIB_API void icmLab2LCh(double *out, double *in);
+
+/* XYZ to Yxy */
+extern ICCLIB_API void icmXYZ2Yxy(double *out, double *in);
+
+/* Yxy to XYZ */
+extern ICCLIB_API void icmYxy2XYZ(double *out, double *in);
+
+/* CIE XYZ to perceptual Luv */
+extern ICCLIB_API void icmXYZ2Luv(icmXYZNumber *w, double *out, double *in);
+
+/* Perceptual Luv to CIE XYZ */
+extern ICCLIB_API void icmLuv2XYZ(icmXYZNumber *w, double *out, double *in);
+
+
+/* CIE XYZ to perceptual CIE 1976 UCS diagram Yu'v'*/
+/* (Yu'v' is a better chromaticity space than Yxy) */
+extern ICCLIB_API void icmXYZ21976UCS(double *out, double *in);
+
+/* Perceptual CIE 1976 UCS diagram Yu'v' to CIE XYZ */
+extern ICCLIB_API void icm1976UCS2XYZ(double *out, double *in);
+
+
+/* CIE XYZ to perceptual CIE 1960 UCS */
+/* (This was obsoleted by the 1976UCS, but is still used */
+/* in computing color temperatures.) */
+extern ICCLIB_API void icmXYZ21960UCS(double *out, double *in);
+
+/* Perceptual CIE 1960 UCS to CIE XYZ */
+extern ICCLIB_API void icm1960UCS2XYZ(double *out, double *in);
+
+
+/* CIE XYZ to perceptual CIE 1964 WUV (U*V*W*) */
+/* (This is obsolete but still used in computing CRI) */
+extern ICCLIB_API void icmXYZ21964WUV(icmXYZNumber *w, double *out, double *in);
+
+/* Perceptual CIE 1964 WUV (U*V*W*) to CIE XYZ */
+extern ICCLIB_API void icm1964WUV2XYZ(icmXYZNumber *w, double *out, double *in);
+
+/* CIE CIE1960 UCS to perceptual CIE 1964 WUV (U*V*W*) */
+extern ICCLIB_API void icm1960UCS21964WUV(icmXYZNumber *w, double *out, double *in);
+
+
+/* NOTE :- that these values are for the 1931 standard observer */
+
+/* The standard D50 illuminant value */
+extern icmXYZNumber icmD50;
+extern icmXYZNumber icmD50_100; /* Scaled to 100 */
+extern double icmD50_ary3[3]; /* As an array */
+extern double icmD50_100_ary3[3]; /* Scaled to 100 as an array */
+
+/* The standard D65 illuminant value */
+extern icmXYZNumber icmD65;
+extern icmXYZNumber icmD65_100; /* Scaled to 100 */
+extern double icmD65_ary3[3]; /* As an array */
+extern double icmD65_100_ary3[3]; /* Scaled to 100 as an array */
+
+
+/* The default black value */
+extern icmXYZNumber icmBlack;
+
+
+/* Initialise a pseudo-hilbert grid counter, return total usable count. */
+extern ICCLIB_API unsigned psh_init(psh *p, int di, unsigned int res, int co[]);
+
+/* Reset the counter */
+extern ICCLIB_API void psh_reset(psh *p);
+
+/* Increment pseudo-hilbert coordinates */
+/* Return non-zero if count rolls over to 0 */
+extern ICCLIB_API int psh_inc(psh *p, int co[]);
+
/* - - - - - - - - - - - - - - - - - - - - - - - */
/* Return the normal Delta E given two Lab values */
@@ -1956,6 +1978,7 @@ extern ICCLIB_API double icmCIE2Ksq(double *in0, double *in1);
/* Return the CIEDE2000 Delta E color difference measure for two XYZ values */
extern ICCLIB_API double icmXYZCIE2K(icmXYZNumber *w, double *in0, double *in1);
+
/* - - - - - - - - - - - - - - - - - - - - - - - */
/* Clip Lab, while maintaining hue angle. */
/* Return nz if clipping occured */
@@ -1966,6 +1989,122 @@ int icmClipLab(double out[3], double in[3]);
int icmClipXYZ(double out[3], double in[3]);
/* - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* RGB primaries to device to RGB->XYZ transform matrix */
+/* Return non-zero if matrix would be singular */
+int icmRGBprim2matrix(
+ icmXYZNumber white, /* White point */
+ icmXYZNumber red, /* Red colorant */
+ icmXYZNumber green, /* Green colorant */
+ icmXYZNumber blue, /* Blue colorant */
+ double mat[3][3] /* Destination matrix[RGB[XYZ] */
+);
+
+/* Chromatic Adaption transform utility */
+/* Return a 3x3 chromatic adaption matrix */
+/* Use icmMulBy3x3(dst, mat, src) */
+
+#define ICM_CAM_BRADFORD 0x0001 /* Use Bradford sharpened response space */
+#define ICM_CAM_MULMATRIX 0x0002 /* Transform the given matrix */
+ /* NOTE that to transform primaries they */
+ /* must be mat[XYZ][RGB] format! */
+
+void icmChromAdaptMatrix(
+ int flags, /* Flags as defined below */
+ icmXYZNumber d_wp, /* Destination white point */
+ icmXYZNumber s_wp, /* Source white point */
+ double mat[3][3] /* Destination matrix */
+);
+
+/* Pre-round RGB device primary values to ensure that */
+/* the sum of the quantized primaries is the same as */
+/* the quantized sum. */
+void quantizeRGBprimsS15Fixed16(
+ double mat[3][3] /* matrix[RGB][XYZ] */
+);
+
+/* - - - - - - - - - - - - - - */
+/* Video functions */
+
+/* Convert Lut table index/value to YCbCr */
+void icmLut2YCbCr(double *out, double *in);
+
+/* Convert YCbCr to Lut table index/value */
+void icmYCbCr2Lut(double *out, double *in);
+
+
+/* Convert Rec601 RGB' into YPbPr, (== "full range YCbCr") */
+/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
+void icmRec601_RGBd_2_YPbPr(double out[3], double in[3]);
+
+/* Convert Rec601 YPbPr to RGB' (== "full range YCbCr") */
+/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
+void icmRec601_YPbPr_2_RGBd(double out[3], double in[3]);
+
+
+/* Convert Rec709 1150/60/2:1 RGB' into YPbPr, or "full range YCbCr" */
+/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
+void icmRec709_RGBd_2_YPbPr(double out[3], double in[3]);
+
+/* Convert Rec709 1150/60/2:1 YPbPr to RGB' (== "full range YCbCr") */
+/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
+void icmRec709_YPbPr_2_RGBd(double out[3], double in[3]);
+
+/* Convert Rec709 1250/50/2:1 RGB' into YPbPr, or "full range YCbCr" */
+/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
+void icmRec709_50_RGBd_2_YPbPr(double out[3], double in[3]);
+
+/* Convert Rec709 1250/50/2:1 YPbPr to RGB' (== "full range YCbCr") */
+/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
+void icmRec709_50_YPbPr_2_RGBd(double out[3], double in[3]);
+
+
+/* Convert Rec2020 RGB' into Non-constant liminance YPbPr, or "full range YCbCr" */
+/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
+void icmRec2020_NCL_RGBd_2_YPbPr(double out[3], double in[3]);
+
+/* Convert Rec2020 Non-constant liminance YPbPr into RGB' (== "full range YCbCr") */
+/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
+void icmRec2020_NCL_YPbPr_2_RGBd(double out[3], double in[3]);
+
+/* Convert Rec2020 RGB' into Constant liminance YPbPr, or "full range YCbCr" */
+/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
+void icmRec2020_CL_RGBd_2_YPbPr(double out[3], double in[3]);
+
+/* Convert Rec2020 Constant liminance YPbPr into RGB' (== "full range YCbCr") */
+/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
+void icmRec2020_CL_YPbPr_2_RGBd(double out[3], double in[3]);
+
+
+/* Convert Rec601/709/2020 YPbPr to YCbCr range. */
+/* input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, */
+/* output 16/255 .. 235/255, 16/255 .. 240/255, 16/255 .. 240/255 */
+void icmRecXXX_YPbPr_2_YCbCr(double out[3], double in[3]);
+
+/* Convert Rec601/709/2020 YCbCr to YPbPr range. */
+/* input 16/255 .. 235/255, 16/255 .. 240/255, 16/255 .. 240/255 */
+/* output 0..1, -0.5 .. 0.5, -0.5 .. 0.5, */
+void icmRecXXX_YCbCr_2_YPbPr(double out[3], double in[3]);
+
+
+/* Convert full range RGB to Video range 16..235 RGB */
+void icmRGB_2_VidRGB(double out[3], double in[3]);
+
+/* Convert Video range 16..235 RGB to full range RGB */
+void icmVidRGB_2_RGB(double out[3], double in[3]);
+
+/* ---------------------------------------------------------- */
+/* PS 3.14-2009, Digital Imaging and Communications in Medicine */
+/* (DICOM) Part 14: Grayscale Standard Display Function */
+
+/* JND index value 1..1023 to L 0.05 .. 3993.404 cd/m^2 */
+double icmDICOM_fwd(double jnd);
+
+/* L 0.05 .. 3993.404 cd/m^2 to JND index value 1..1023 */
+double icmDICOM_bwd(double L);
+
+
+/* ---------------------------------------------------------- */
/* Print an int vector to a string. */
/* Returned static buffer is re-used every 5 calls. */
char *icmPiv(int di, int *p);
@@ -1981,8 +2120,8 @@ char *icmPfv(int di, float *p);
/* Print an 0..1 range XYZ as a D50 Lab string */
/* Returned static buffer is re-used every 5 calls. */
char *icmPLab(double *p);
+/* - - - - - - - - - - - - - - - - - - - - - - - */
-/* ---------------------------------------------------------- */
#ifdef __cplusplus
}