libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

cms_interface.h (10260B)


      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 #if defined(__cplusplus) || defined(c_plusplus)
     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 #if defined(__cplusplus) || defined(c_plusplus)
    250 }
    251 #endif
    252 
    253 #endif /* JXL_CMS_INTERFACE_H_ */
    254 
    255 /** @} */