summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/include/jxl/cms_interface.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/jpeg-xl/lib/include/jxl/cms_interface.h')
-rw-r--r--third_party/jpeg-xl/lib/include/jxl/cms_interface.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/third_party/jpeg-xl/lib/include/jxl/cms_interface.h b/third_party/jpeg-xl/lib/include/jxl/cms_interface.h
new file mode 100644
index 0000000000..684281e641
--- /dev/null
+++ b/third_party/jpeg-xl/lib/include/jxl/cms_interface.h
@@ -0,0 +1,232 @@
+/* Copyright (c) the JPEG XL Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+/** @addtogroup libjxl_common
+ * @{
+ * @file cms_interface.h
+ * @brief Interface to allow the injection of different color management systems
+ * (CMSes, also called color management modules, or CMMs) in JPEG XL.
+ *
+ * A CMS is needed by the JPEG XL encoder and decoder to perform colorspace
+ * conversions. This defines an interface that can be implemented for different
+ * CMSes and then passed to the library.
+ */
+
+#ifndef JXL_CMS_INTERFACE_H_
+#define JXL_CMS_INTERFACE_H_
+
+#include <jxl/color_encoding.h>
+#include <jxl/types.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/** Represents an input or output colorspace to a color transform, as a
+ * serialized ICC profile. */
+typedef struct {
+ /** The serialized ICC profile. This is guaranteed to be present and valid. */
+ struct {
+ const uint8_t* data;
+ size_t size;
+ } icc;
+
+ /** Structured representation of the colorspace, if applicable. If all fields
+ * are different from their "unknown" value, then this is equivalent to the
+ * ICC representation of the colorspace. If some are "unknown", those that are
+ * not are still valid and can still be used on their own if they are useful.
+ */
+ JxlColorEncoding color_encoding;
+
+ /** Number of components per pixel. This can be deduced from the other
+ * representations of the colorspace but is provided for convenience and
+ * validation. */
+ size_t num_channels;
+} JxlColorProfile;
+
+/** Allocates and returns the data needed for @p num_threads parallel transforms
+ * from the @p input colorspace to @p output, with up to @p pixels_per_thread
+ * pixels to transform per call to JxlCmsInterface::run. @p init_data comes
+ * directly from the JxlCmsInterface instance. Since @c run only receives the
+ * data returned by @c init, a reference to @p init_data should be kept there
+ * if access to it is desired in @c run. Likewise for JxlCmsInterface::destroy.
+ *
+ * The ICC data in @p input and @p output is guaranteed to outlive the @c init /
+ * @c run / @c destroy cycle.
+ *
+ * @param init_data JxlCmsInterface::init_data passed as-is.
+ * @param num_threads the maximum number of threads from which
+ * JxlCmsInterface::run will be called.
+ * @param pixels_per_thread the maximum number of pixels that each call to
+ * JxlCmsInterface::run will have to transform.
+ * @param input_profile the input colorspace for the transform.
+ * @param output_profile the colorspace to which JxlCmsInterface::run should
+ * convert the input data.
+ * @param intensity_target for colorspaces where luminance is relative
+ * (essentially: not PQ), indicates the luminance at which (1, 1, 1) will
+ * be displayed. This is useful for conversions between PQ and a relative
+ * luminance colorspace, in either direction: @p intensity_target cd/m²
+ * in PQ should map to and from (1, 1, 1) in the relative one.\n
+ * It is also used for conversions to and from HLG, as it is
+ * scene-referred while other colorspaces are assumed to be
+ * display-referred. That is, conversions from HLG should apply the OOTF
+ * for a peak display luminance of @p intensity_target, and conversions
+ * to HLG should undo it. The OOTF is a gamma function applied to the
+ * luminance channel (https://www.itu.int/rec/R-REC-BT.2100-2-201807-I
+ * page 7), with the gamma value computed as
+ * <tt>1.2 * 1.111^log2(intensity_target / 1000)</tt> (footnote 2 page 8
+ * of the same document).
+ * @return The data needed for the transform, or @c NULL in case of failure.
+ * This will be passed to the other functions as @c user_data.
+ */
+typedef void* (*jpegxl_cms_init_func)(void* init_data, size_t num_threads,
+ size_t pixels_per_thread,
+ const JxlColorProfile* input_profile,
+ const JxlColorProfile* output_profile,
+ float intensity_target);
+
+/** Returns a buffer that can be used by callers of the interface to store the
+ * input of the conversion or read its result, if they pass it as the input or
+ * output of the @c run function.
+ * @param user_data the data returned by @c init.
+ * @param thread the index of the thread for which to return a buffer.
+ * @return A buffer that can be used by the caller for passing to @c run.
+ */
+typedef float* (*jpegxl_cms_get_buffer_func)(void* user_data, size_t thread);
+
+/** Executes one transform and returns true on success or false on error. It
+ * must be possible to call this from different threads with different values
+ * for @p thread, all between 0 (inclusive) and the value of @p num_threads
+ * passed to @c init (exclusive). It is allowed to implement this by locking
+ * such that the transforms are essentially performed sequentially, if such a
+ * performance profile is acceptable. @p user_data is the data returned by
+ * @c init.
+ * The buffers each contain @p num_pixels × @c num_channels interleaved floating
+ * point (0..1) samples where @c num_channels is the number of color channels of
+ * their respective color profiles. It is guaranteed that the only case in which
+ * they might overlap is if the output has fewer channels than the input, in
+ * which case the pointers may be identical.
+ * For CMYK data, 0 represents the maximum amount of ink while 1 represents no
+ * ink.
+ * @param user_data the data returned by @c init.
+ * @param thread the index of the thread from which the function is being
+ * called.
+ * @param input_buffer the buffer containing the pixel data to be transformed.
+ * @param output_buffer the buffer receiving the transformed pixel data.
+ * @param num_pixels the number of pixels to transform from @p input to
+ * @p output.
+ * @return JXL_TRUE on success, JXL_FALSE on failure.
+ */
+typedef JXL_BOOL (*jpegxl_cms_run_func)(void* user_data, size_t thread,
+ const float* input_buffer,
+ float* output_buffer,
+ size_t num_pixels);
+
+/** Performs the necessary clean-up and frees the memory allocated for user
+ * data.
+ */
+typedef void (*jpegxl_cms_destroy_func)(void*);
+
+/**
+ * Interface for performing colorspace transforms. The @c init function can be
+ * called several times to instantiate several transforms, including before
+ * other transforms have been destroyed.
+ *
+ * The call sequence for a given colorspace transform could look like the
+ * following:
+ * @dot
+ * digraph calls {
+ * newrank = true
+ * node [shape = box, fontname = monospace]
+ * init [label = "user_data <- init(\l\
+ * init_data = data,\l\
+ * num_threads = 3,\l\
+ * pixels_per_thread = 20,\l\
+ * input = (sRGB, 3 channels),\l\
+ * output = (Display-P3, 3 channels),\l\
+ * intensity_target = 255\l\
+ * )\l"]
+ * subgraph cluster_0 {
+ * color = lightgrey
+ * label = "thread 1"
+ * labeljust = "c"
+ * run_1_1 [label = "run(\l\
+ * user_data,\l\
+ * thread = 1,\l\
+ * input = in[0],\l\
+ * output = out[0],\l\
+ * num_pixels = 20\l\
+ * )\l"]
+ * run_1_2 [label = "run(\l\
+ * user_data,\l\
+ * thread = 1,\l\
+ * input = in[3],\l\
+ * output = out[3],\l\
+ * num_pixels = 20\l\
+ * )\l"]
+ * }
+ * subgraph cluster_1 {
+ * color = lightgrey
+ * label = "thread 2"
+ * labeljust = "l"
+ * run_2_1 [label = "run(\l\
+ * user_data,\l\
+ * thread = 2,\l\
+ * input = in[1],\l\
+ * output = out[1],\l\
+ * num_pixels = 20\l\
+ * )\l"]
+ * run_2_2 [label = "run(\l\
+ * user_data,\l\
+ * thread = 2,\l\
+ * input = in[4],\l\
+ * output = out[4],\l\
+ * num_pixels = 13\l\
+ * )\l"]
+ * }
+ * subgraph cluster_3 {
+ * color = lightgrey
+ * label = "thread 3"
+ * labeljust = "c"
+ * run_3_1 [label = "run(\l\
+ * user_data,\l\
+ * thread = 3,\l\
+ * input = in[2],\l\
+ * output = out[2],\l\
+ * num_pixels = 20\l\
+ * )\l"]
+ * }
+ * init -> {run_1_1; run_2_1; run_3_1; rank = same}
+ * run_1_1 -> run_1_2
+ * run_2_1 -> run_2_2
+ * {run_1_2; run_2_2, run_3_1} -> "destroy(user_data)"
+ * }
+ * @enddot
+ */
+typedef struct {
+ /** CMS-specific data that will be passed to @ref init. */
+ void* init_data;
+ /** Prepares a colorspace transform as described in the documentation of @ref
+ * jpegxl_cms_init_func. */
+ jpegxl_cms_init_func init;
+ /** Returns a buffer that can be used as input to @c run. */
+ jpegxl_cms_get_buffer_func get_src_buf;
+ /** Returns a buffer that can be used as output from @c run. */
+ jpegxl_cms_get_buffer_func get_dst_buf;
+ /** Executes the transform on a batch of pixels, per @ref jpegxl_cms_run_func.
+ */
+ jpegxl_cms_run_func run;
+ /** Cleans up the transform. */
+ jpegxl_cms_destroy_func destroy;
+} JxlCmsInterface;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* JXL_CMS_INTERFACE_H_ */
+
+/** @} */