tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cms_interface.h (10202B)


      1 /* Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 *
      3 * Use of this source code is governed by a BSD-style
      4 * license that can be found in the LICENSE file.
      5 */
      6 
      7 /** @addtogroup libjxl_color
      8 * @{
      9 * @file cms_interface.h
     10 * @brief Interface to allow the injection of different color management systems
     11 * (CMSes, also called color management modules, or CMMs) in JPEG XL.
     12 *
     13 * A CMS is needed by the JPEG XL encoder and decoder to perform colorspace
     14 * conversions. This defines an interface that can be implemented for different
     15 * CMSes and then passed to the library.
     16 */
     17 
     18 #ifndef JXL_CMS_INTERFACE_H_
     19 #define JXL_CMS_INTERFACE_H_
     20 
     21 #include <jxl/color_encoding.h>
     22 #include <jxl/types.h>
     23 #include <stddef.h>
     24 #include <stdint.h>
     25 
     26 #ifdef __cplusplus
     27 extern "C" {
     28 #endif
     29 
     30 /** Parses an ICC profile and populates @p c and @p cmyk with the data.
     31 *
     32 * @param user_data @ref JxlCmsInterface::set_fields_data passed as-is.
     33 * @param icc_data the ICC data to parse.
     34 * @param icc_size how many bytes of icc_data are valid.
     35 * @param c a @ref JxlColorEncoding to populate if applicable.
     36 * @param cmyk a boolean to set to whether the colorspace is a CMYK colorspace.
     37 * @return Whether the relevant fields in @p c were successfully populated.
     38 */
     39 typedef JXL_BOOL (*jpegxl_cms_set_fields_from_icc_func)(void* user_data,
     40                                                        const uint8_t* icc_data,
     41                                                        size_t icc_size,
     42                                                        JxlColorEncoding* c,
     43                                                        JXL_BOOL* cmyk);
     44 
     45 /** Represents an input or output colorspace to a color transform, as a
     46 * serialized ICC profile. */
     47 typedef struct {
     48  /** The serialized ICC profile. This is guaranteed to be present and valid. */
     49  struct {
     50    const uint8_t* data;
     51    size_t size;
     52  } icc;
     53 
     54  /** Structured representation of the colorspace, if applicable. If all fields
     55   * are different from their "unknown" value, then this is equivalent to the
     56   * ICC representation of the colorspace. If some are "unknown", those that are
     57   * not are still valid and can still be used on their own if they are useful.
     58   */
     59  JxlColorEncoding color_encoding;
     60 
     61  /** Number of components per pixel. This can be deduced from the other
     62   * representations of the colorspace but is provided for convenience and
     63   * validation. */
     64  size_t num_channels;
     65 } JxlColorProfile;
     66 
     67 /** Allocates and returns the data needed for @p num_threads parallel transforms
     68 * from the @p input colorspace to @p output, with up to @p pixels_per_thread
     69 * pixels to transform per call to @ref JxlCmsInterface::run. @p init_data comes
     70 * directly from the @ref JxlCmsInterface instance. Since @c run only receives
     71 * the data returned by @c init, a reference to @p init_data should be kept
     72 * there if access to it is desired in @c run. Likewise for @ref
     73 * JxlCmsInterface::destroy.
     74 *
     75 * The ICC data in @p input and @p output is guaranteed to outlive the @c init /
     76 * @c run / @c destroy cycle.
     77 *
     78 * @param init_data @ref JxlCmsInterface::init_data passed as-is.
     79 * @param num_threads the maximum number of threads from which
     80 *        @ref JxlCmsInterface::run will be called.
     81 * @param pixels_per_thread the maximum number of pixels that each call to
     82 *        @ref JxlCmsInterface::run will have to transform.
     83 * @param input_profile the input colorspace for the transform.
     84 * @param output_profile the colorspace to which @ref JxlCmsInterface::run
     85 * should convert the input data.
     86 * @param intensity_target for colorspaces where luminance is relative
     87 *        (essentially: not PQ), indicates the luminance at which (1, 1, 1) will
     88 *        be displayed. This is useful for conversions between PQ and a relative
     89 *        luminance colorspace, in either direction: @p intensity_target cd/m²
     90 *        in PQ should map to and from (1, 1, 1) in the relative one.\n
     91 *        It is also used for conversions to and from HLG, as it is
     92 *        scene-referred while other colorspaces are assumed to be
     93 *        display-referred. That is, conversions from HLG should apply the OOTF
     94 *        for a peak display luminance of @p intensity_target, and conversions
     95 *        to HLG should undo it. The OOTF is a gamma function applied to the
     96 *        luminance channel (https://www.itu.int/rec/R-REC-BT.2100-2-201807-I
     97 *        page 7), with the gamma value computed as
     98 *        <tt>1.2 * 1.111^log2(intensity_target / 1000)</tt> (footnote 2 page 8
     99 *        of the same document).
    100 * @return The data needed for the transform, or @c NULL in case of failure.
    101 *         This will be passed to the other functions as @c user_data.
    102 */
    103 typedef void* (*jpegxl_cms_init_func)(void* init_data, size_t num_threads,
    104                                      size_t pixels_per_thread,
    105                                      const JxlColorProfile* input_profile,
    106                                      const JxlColorProfile* output_profile,
    107                                      float intensity_target);
    108 
    109 /** Returns a buffer that can be used by callers of the interface to store the
    110 * input of the conversion or read its result, if they pass it as the input or
    111 * output of the @c run function.
    112 * @param user_data the data returned by @c init.
    113 * @param thread the index of the thread for which to return a buffer.
    114 * @return A buffer that can be used by the caller for passing to @c run.
    115 */
    116 typedef float* (*jpegxl_cms_get_buffer_func)(void* user_data, size_t thread);
    117 
    118 /** Executes one transform and returns true on success or false on error. It
    119 * must be possible to call this from different threads with different values
    120 * for @p thread, all between 0 (inclusive) and the value of @p num_threads
    121 * passed to @c init (exclusive). It is allowed to implement this by locking
    122 * such that the transforms are essentially performed sequentially, if such a
    123 * performance profile is acceptable. @p user_data is the data returned by
    124 * @c init.
    125 * The buffers each contain @p num_pixels × @c num_channels interleaved floating
    126 * point (0..1) samples where @c num_channels is the number of color channels of
    127 * their respective color profiles. It is guaranteed that the only case in which
    128 * they might overlap is if the output has fewer channels than the input, in
    129 * which case the pointers may be identical.
    130 * For CMYK data, 0 represents the maximum amount of ink while 1 represents no
    131 * ink.
    132 * @param user_data the data returned by @c init.
    133 * @param thread the index of the thread from which the function is being
    134 *        called.
    135 * @param input_buffer the buffer containing the pixel data to be transformed.
    136 * @param output_buffer the buffer receiving the transformed pixel data.
    137 * @param num_pixels the number of pixels to transform from @p input to
    138 * @p output.
    139 * @return ::JXL_TRUE on success, ::JXL_FALSE on failure.
    140 */
    141 typedef JXL_BOOL (*jpegxl_cms_run_func)(void* user_data, size_t thread,
    142                                        const float* input_buffer,
    143                                        float* output_buffer,
    144                                        size_t num_pixels);
    145 
    146 /** Performs the necessary clean-up and frees the memory allocated for user
    147 * data.
    148 */
    149 typedef void (*jpegxl_cms_destroy_func)(void*);
    150 
    151 /**
    152 * Interface for performing colorspace transforms. The @c init function can be
    153 * called several times to instantiate several transforms, including before
    154 * other transforms have been destroyed.
    155 *
    156 * The call sequence for a given colorspace transform could look like the
    157 * following:
    158 * @dot
    159 * digraph calls {
    160 *   newrank = true
    161 *   node [shape = box, fontname = monospace]
    162 *   init [label = "user_data <- init(\l\
    163 *     init_data = data,\l\
    164 *     num_threads = 3,\l\
    165 *     pixels_per_thread = 20,\l\
    166 *     input = (sRGB, 3 channels),\l\
    167 *     output = (Display-P3, 3 channels),\l\
    168 *     intensity_target = 255\l\
    169 *   )\l"]
    170 *   subgraph cluster_0 {
    171 *   color = lightgrey
    172 *   label = "thread 1"
    173 *   labeljust = "c"
    174 *   run_1_1 [label = "run(\l\
    175 *     user_data,\l\
    176 *     thread = 1,\l\
    177 *     input = in[0],\l\
    178 *     output = out[0],\l\
    179 *     num_pixels = 20\l\
    180 *   )\l"]
    181 *   run_1_2 [label = "run(\l\
    182 *     user_data,\l\
    183 *     thread = 1,\l\
    184 *     input = in[3],\l\
    185 *     output = out[3],\l\
    186 *     num_pixels = 20\l\
    187 *   )\l"]
    188 *   }
    189 *   subgraph cluster_1 {
    190 *   color = lightgrey
    191 *   label = "thread 2"
    192 *   labeljust = "l"
    193 *   run_2_1 [label = "run(\l\
    194 *     user_data,\l\
    195 *     thread = 2,\l\
    196 *     input = in[1],\l\
    197 *     output = out[1],\l\
    198 *     num_pixels = 20\l\
    199 *   )\l"]
    200 *   run_2_2 [label = "run(\l\
    201 *     user_data,\l\
    202 *     thread = 2,\l\
    203 *     input = in[4],\l\
    204 *     output = out[4],\l\
    205 *     num_pixels = 13\l\
    206 *   )\l"]
    207 *   }
    208 *   subgraph cluster_3 {
    209 *   color = lightgrey
    210 *   label = "thread 3"
    211 *   labeljust = "c"
    212 *   run_3_1 [label = "run(\l\
    213 *     user_data,\l\
    214 *     thread = 3,\l\
    215 *     input = in[2],\l\
    216 *     output = out[2],\l\
    217 *     num_pixels = 20\l\
    218 *   )\l"]
    219 *   }
    220 *   init -> {run_1_1; run_2_1; run_3_1; rank = same}
    221 *   run_1_1 -> run_1_2
    222 *   run_2_1 -> run_2_2
    223 *   {run_1_2; run_2_2, run_3_1} -> "destroy(user_data)"
    224 * }
    225 * @enddot
    226 */
    227 typedef struct {
    228  /** CMS-specific data that will be passed to @ref set_fields_from_icc. */
    229  void* set_fields_data;
    230  /** Populates a @ref JxlColorEncoding from an ICC profile. */
    231  jpegxl_cms_set_fields_from_icc_func set_fields_from_icc;
    232 
    233  /** CMS-specific data that will be passed to @ref init. */
    234  void* init_data;
    235  /** Prepares a colorspace transform as described in the documentation of @ref
    236   * jpegxl_cms_init_func. */
    237  jpegxl_cms_init_func init;
    238  /** Returns a buffer that can be used as input to @c run. */
    239  jpegxl_cms_get_buffer_func get_src_buf;
    240  /** Returns a buffer that can be used as output from @c run. */
    241  jpegxl_cms_get_buffer_func get_dst_buf;
    242  /** Executes the transform on a batch of pixels, per @ref jpegxl_cms_run_func.
    243   */
    244  jpegxl_cms_run_func run;
    245  /** Cleans up the transform. */
    246  jpegxl_cms_destroy_func destroy;
    247 } JxlCmsInterface;
    248 
    249 #ifdef __cplusplus
    250 }
    251 #endif
    252 
    253 #endif /* JXL_CMS_INTERFACE_H_ */
    254 
    255 /** @} */