aboutsummaryrefslogblamecommitdiffstats
path: root/libglitter.h
blob: 27dfd0da8fd71d301a697136dbb45941e54fa1ef (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                         

                                                  
                                                                       



                                                 
                                                                       



                                                    
                                                                       



                                                    
                                                                       



                                                    
                                                                       



                                                   
                                                                       









                                                        
                                                                       





                                                        
                                                                                                  


                                                        

                                                  
   







                                                                                              


   







                                              







                                                                   




















                                     















                                                                     


                                                               











                                                                               
                                                              



                                                                         
                                                                                              


   






















                                                                                    

                                                                      

                                                                             























                                                                                              


                                                         



                                                       
                                                                                  



                                                                                 
                                                          




                                                                              

                                                                          

                                                                            
   

                                                                                  

   


                                                                 
   

                                                                                 
 







                                                         
                                                                                  



                                                                                 
                                                          




                                                                              

                                                                          

                                                                            
   

                                                                                     





                                                                 

                                                                                     





                                                                 

                                                                                     





                                                                 

                                                                                  

 





















                                                                                                                 

 
   



                                                                      
                                                                          














                                                                                                          
                                                                          











                                                                                                        

















                                                                            
                                                  



                                                                            
                                                                                                                     





                                                                    










                                                                                                                 
                                                      























                                                                                                

 

                                                     
                                                       
             
   

                                                        

                                                         
                                                     


                                                        
   
                                                                                  







                                                                                         
                                                                                           
                                                                                             


                                                                                         




                                                              


                                                                                                       

   

                                                                                            

                                  


                                                                                                 

 
   
                                                          
























                                                                              
                                                                                 
   

                                                                                                                

   

                                                                                      

                                  

                                                                                                              

 
      
                                           
/* See LICENSE file for copyright and license details. */
#ifndef LIBGLITTER_H
#define LIBGLITTER_H

#include <stddef.h>
#include <stdint.h>


/**
 * The application will use `double`-typed rasters
 */
#define LIBGLITTER_FEATURE_DOUBLE_TYPE     UINT64_C(0x0000000000000001)

/**
 * The application will use `float`-typed rasters
 */
#define LIBGLITTER_FEATURE_FLOAT_TYPE      UINT64_C(0x0000000000000002)

/**
 * The application will use `uint64_t`-typed rasters
 */
#define LIBGLITTER_FEATURE_UINT64_TYPE     UINT64_C(0x0000000000000004)

/**
 * The application will use `uint32_t`-typed rasters
 */
#define LIBGLITTER_FEATURE_UINT32_TYPE     UINT64_C(0x0000000000000008)

/**
 * The application will use `uint16_t`-typed rasters
 */
#define LIBGLITTER_FEATURE_UINT16_TYPE     UINT64_C(0x0000000000000010)

/**
 * The application will use `uint8_t`-typed rasters
 */
#define LIBGLITTER_FEATURE_UINT8_TYPE      UINT64_C(0x0000000000000020)

/**
 * The allocation will use at least one of the functions
 * `libglitter_compose_double`,
 * `libglitter_compose_float`,
 * `libglitter_compose_uint64`,
 * `libglitter_compose_uint32`,
 * `libglitter_compose_uint16`, and
 * `libglitter_compose_uint8`
 */
#define LIBGLITTER_FEATURE_COMPOSE         UINT64_C(0x0000000000000040)

/**
 * The allocation will use at least one of the functions
 * `libglitter_desaturate_double`, and
 * `libglitter_desaturate_float`
 */
#define LIBGLITTER_FEATURE_CU_DESATURATION UINT64_C(0x0000000000000080) /* CU = channel-uniform */

/**
 * The allocation will use at least one of the functions
 * `libglitter_per_channel_desaturate_double`, and
 * `libglitter_per_channel_desaturate_float`
 */
#define LIBGLITTER_FEATURE_PC_DESATURATION UINT64_C(0x0000000000000100) /* PC = per channel */

/**
 * The allocation will use at least one of the functions
 * `libglitter_colour_model_convert_rasters_double`, and
 * `libglitter_colour_model_convert_rasters_float`
 */
#define LIBGLITTER_FEATURE_COLOUR_MODEL    UINT64_C(0x0000000000000200)


/**
 * The CIE xyY values of the D65 illuminant
 */
#define LIBGLITTER_ILLUMINANT_D65\
	0.312726871026564878786047074755,\
	0.329023206641284038376227272238, 1.0\


/**
 * Rendering context for an input raster's specifications
 * 
 * Render context's are thread-safe, however updating them are not
 */
typedef struct libglitter_render_context LIBGLITTER_RENDER_CONTEXT;


/**
 * Output primary colour
 */
enum libglitter_colour {
	/**
	 * Red primary colour
	 */
	LIBGLITTER_CHANNEL_RED = 0,

	/**
	 * Green primary colour
	 */
	LIBGLITTER_CHANNEL_GREEN = 1,

	/**
	 * Blue primary colour
	 */
	LIBGLITTER_CHANNEL_BLUE = 2
};


/**
 * Attempt to enable hardware acceleration
 * 
 * Currently this function doesn't do anything but call the
 * callback function and return 0; it is provided for application
 * to use know and get hardware acceleration when it is implemented
 * 
 * @param   features  Set of features to enable hardware acceleration
 *                    for, unrecognised bits are silently ignored.
 *                    Recognised bit values are:
 *                    - LIBGLITTER_FEATURE_DOUBLE_TYPE,
 *                    - LIBGLITTER_FEATURE_FLOAT_TYPE,
 *                    - LIBGLITTER_FEATURE_UINT64_TYPE,
 *                    - LIBGLITTER_FEATURE_UINT32_TYPE,
 *                    - LIBGLITTER_FEATURE_UINT16_TYPE,
 *                    - LIBGLITTER_FEATURE_UINT8_TYPE,
 *                    - LIBGLITTER_FEATURE_COMPOSE,
 *                    - LIBGLITTER_FEATURE_CU_DESATURATION,
 *                    - LIBGLITTER_FEATURE_PC_DESATURATION, and
 *                    - LIBGLITTER_FEATURE_COLOUR_MODEL.
 * @param   async     Whether the function shall return immediately
 *                    rather than when complete
 * @param   callback  Callback function that is called at function
 *                    completion, the first argument will be either
 *                    1 on success with hardware acceleration enabled,
 *                    0 on success without hardware acceleration enabled,
 *                    or -1 on failure; the second argument will be 0
 *                    on success or an error code on failure; the third
 *                    argument will be `userdata`. This argument may
 *                    also be `NULL` if no callback function shall be
 *                    called
 * @param   userdata  User-specific data to pass into `callback`, may be `NULL`
 * @param   unused    Reserved for future use, shall be `NULL`
 * @return            1 on success with hardware acceleration enabled,
 *                    0 on success without hardware acceleration enabled,
 *                    or -1 on failure
 */
int libglitter_enable_acceleration(uint64_t, int, void (*)(int, int, void *), void *, void *);


/**
 * Create a render context for an input raster's specifications
 * 
 * Render context's are thread-safe
 * 
 * @param  noutputs     The number of output buffers
 * @param  rowsize      The number of cells per row in the input raster
 * @param  widthmul     The horizontal number of cells per pixel in the input raster
 * @param  heightmul    The vertical number of cells per pixel in the input raster
 * @param  cellmap      Subpixel map of size `heightmul * widthmul` that maps a
 *                      cell for a pixel in the input raster to an output raster
 *                      (the output raster's index); this is row-major map, and
 *                      each valid value must appear at least once
 * @param  ncellvalues  For each `i` in [0, `noutputs`), `ncellvalues[i]`
 *                      shall be the number of times the value `i` occurs
 *                      in `cellmap`
 * @return              A render context that can be deallocate using
 *                      `libglitter_free_render_context` or updated with
 *                      `libglitter_update_render_context`; `NULL` on failure
 *
 * @throws  ENOMEM  Couldn't not allocate enough memory
 * 
 * If `noutputs` is 3 and either `widthmul` or `heightmul` is 3 and
 * the other one is 1, `ncellvalues` will not be used as it is preknown
 * that all its values are 1; in the future this could also happen for
 * other situations where `noutputs == widthmul * heightmul`
 * 
 * The returned object will contain references to `cellmap` and `ncellvalues`
 */
LIBGLITTER_RENDER_CONTEXT *libglitter_create_render_context(size_t, size_t, size_t, size_t,
                                                            const uint8_t *, const uint8_t *);

/**
 * Update a render context (created by `libglitter_create_render_context`)
 * for a new input raster buffer
 * 
 * Updating a render context is not thread-safe
 * 
 * @param  this     The render context to refresh
 * @param  rowsize  The number of cells per row in the input raster
 */
void libglitter_update_render_context(LIBGLITTER_RENDER_CONTEXT *, size_t);

/**
 * Deallocates a render context (created by `libglitter_create_render_context`)
 * 
 * @param  this  The render context to deallocate
 */
void libglitter_free_render_context(LIBGLITTER_RENDER_CONTEXT *);


/**
 * Create one raster per monitor colour from a raster of
 * subpixels (which may be further divided in the raster)
 * 
 * Note that this function does not regard the colour
 * model's transfer function: it does not directly give
 * you appropriate sRGB values
 * 
 * @param  outputs          Array of output rasters, one for each subpixel colour.
 *                          The function may change the offset for each raster,
 *                          as such, the given pointer shall not be used anywhere
 *                          else during the execution of the function and the
 *                          inner pointers shall be considered undefined after
 *                          the execution of the function.
 * @param  input            Input raster; cells are adjacent
 * @param  output_rowsize   The number of cells in a row in each output raster
 * @param  output_cellsize  The number of values stored in each output raster,
 *                          between each cell, plus 1 (that is, the number of
 *                          values per cell)
 * @param  width            The horizontal number of pixels in the rasters
 * @param  height           The vertical number of pixels in the rasters
 * @param  render_ctx       Rendering context created for the input raster's
 *                          specification
 */
void libglitter_compose_double(double **, const double *restrict, size_t, size_t,
                               size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);

/**
 * This value is identical to `libglitter_compose_double`,
 * apart from it parameter types, see `libglitter_compose_double`
 * for details about this function
 */
void libglitter_compose_float(float **, const float *restrict, size_t, size_t,
                              size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);

/**
 * Create one raster per monitor colour from a raster of
 * subpixels (which may be further divided in the raster)
 * 
 * Note that this function does not regard the colour
 * model's transfer function: it does not directly give
 * you appropriate sRGB values
 * 
 * @param  outputs          Array of output rasters, one for each subpixel colour.
 *                          The function may change the offset for each raster,
 *                          as such, the given pointer shall not be used anywhere
 *                          else during the execution of the function and the
 *                          inner pointers shall be considered undefined after
 *                          the execution of the function.
 * @param  input            Input raster; cells are adjacent
 * @param  output_rowsize   The number of cells in a row in each output raster
 * @param  output_cellsize  The number of values stored in each output raster,
 *                          between each cell, plus 1 (that is, the number of
 *                          values per cell)
 * @param  width            The horizontal number of pixels in the rasters
 * @param  height           The vertical number of pixels in the rasters
 * @param  render_ctx       Rendering context created for the input raster's
 *                          specification
 */
void libglitter_compose_uint64(uint64_t **, const uint64_t *restrict, size_t, size_t,
                               size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);

/**
 * This value is identical to `libglitter_compose_uint64`,
 * apart from it parameter types, see `libglitter_compose_uint64`
 * for details about this function
 */
void libglitter_compose_uint32(uint32_t **, const uint32_t *restrict, size_t, size_t,
                               size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);

/**
 * This value is identical to `libglitter_compose_uint64`,
 * apart from it parameter types, see `libglitter_compose_uint64`
 * for details about this function
 */
void libglitter_compose_uint16(uint16_t **, const uint16_t *restrict, size_t, size_t,
                               size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);

/**
 * This value is identical to `libglitter_compose_uint64`,
 * apart from it parameter types, see `libglitter_compose_uint64`
 * for details about this function
 */
void libglitter_compose_uint8(uint8_t **, const uint8_t *restrict, size_t, size_t,
                              size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *);


/**
 * Reorders a set of three rasters
 * 
 * When the function `libglitter_create_render_context` is called,
 * the parameter named `cellmap` contains the values 0, 1, and 2,
 * representing different channels: indices in the raster array.
 * The values are not necessarily 0 for red, 1 for green, and 2 for blue,
 * but this function lets the user reorder the rasters so that before
 * calling this function the rasters may be in this order, but when
 * call a `libglitter_compose_*` function after calling this function,
 * that function will write to the correct rasters
 * 
 * @param  rasters  The array of the three rasters, on input the rasters
 *                  shall be in the order (0) red, (1) green, (2) blue;
 *                  the function will reorder them
 * @param  colour1  The colour of the channel value 0 represents in `cellmap`
 * @param  colour2  The colour of the channel value 1 represents in `cellmap`
 * @param  colour3  The colour of the channel value 2 represents in `cellmap`
 *
 * The values `colour1`, `colour2`, `colour3` must be valid but distinct
 */
void libglitter_reorder_rasters(void **, enum libglitter_colour, enum libglitter_colour, enum libglitter_colour);


/**
 * Splits a `uint64_t` raster into one `uint16_t` raster per channel
 * 
 * @param  rasters   Output array for the rasters, they will be in the
 *                   order (0) red, (1) green, (2) blue
 * @param  alphap    Output parameter for the alpha mask raster, or `NULL`
 * @param  raster    The raster that is being split
 * @param  red       The value `0xFFFF` shifted such that value
 *                   expresses pure red (closest primary colour)
 * @param  green     The value `0xFFFF` shifted such that value
 *                   expresses pure green (closest primary colour)
 * @param  blue      The value `0xFFFF` shifted such that value
 *                   expresses pure blue (closest primary colour)
 */
void libglitter_split_uint64_raster(uint16_t *[3], uint16_t **, uint64_t *, uint64_t, uint64_t, uint64_t);

/**
 * Splits a `uint32_t` raster into one `uint8_t` raster per channel
 * 
 * @param  rasters   Output array for the rasters, they will be in the
 *                   order (0) red, (1) green, (2) blue
 * @param  alphap    Output parameter for the alpha mask raster, or `NULL`
 * @param  raster    The raster that is being split
 * @param  red       The value `0xFF` shifted such that value
 *                   expresses pure red (closest primary colour)
 * @param  green     The value `0xFF` shifted such that value
 *                   expresses pure green (closest primary colour)
 * @param  blue      The value `0xFF` shifted such that value
 *                   expresses pure blue (closest primary colour)
 */
void libglitter_split_uint32_raster(uint8_t *[3], uint8_t **, uint32_t *, uint32_t, uint32_t, uint32_t);


/**
 * Transform rasters from fully using subpixel rendering to
 * balance between subpixel rendering and greyscale antialiasing
 * 
 * @param  rasters     Array of rasters, one for each subpixel colour.
 *                     The function may change the offset for each raster,
 *                     as such, the given pointer shall not be used anywhere
 *                     else during the execution of the function and the
 *                     inner pointers shall be considered undefined after
 *                     the execution of the function
 * @param  nrasters    The number of rasters
 * @param  rowsize     The number of cells in a row in each raster
 * @param  cellsize    The number of values stored in each raster,
 *                     between each cell, plus 1 (that is, the number of
 *                     values per cell)
 * @param  width       The horizontal number of pixels in the rasters
 * @param  height      The vertical number of pixels in the rasters
 * @param  saturation  The subpixel rendering saturation, 1 for regular
 *                     subpixel rendering, 0 for greyscale, values
 *                     in between for a compromise
 * @param  primary_ys  The CIE Y value (in e.g. CIE xyY or CIE XYZ) for
 *                     each subpixel colour; or `NULL` for the sRGB values
 *                     (this is only allowed if there are exactly 3 rasters)
 */
void libglitter_desaturate_double(double **, size_t, size_t, size_t, size_t, size_t, double, const double *restrict);

/**
 * This value is identical to `libglitter_desaturate_double`,
 * apart from it parameter types, see `libglitter_desaturate_double`
 * for details about this function
 */
void libglitter_desaturate_float(float **, size_t, size_t, size_t, size_t, size_t, float, const float *restrict);

/**
 * Transform rasters from fully using subpixel rendering to
 * balance between subpixel rendering and greyscale antialiasing
 * 
 * @param  rasters      Array of rasters, one for each subpixel colour.
 *                      The function may change the offset for each raster,
 *                      as such, the given pointer shall not be used anywhere
 *                      else during the execution of the function and the
 *                      inner pointers shall be considered undefined after
 *                      the execution of the function.
 * @param  nrasters     The number of rasters
 * @param  rowsize      The number of cells in a row in each raster
 * @param  cellsize     The number of values stored in each raster,
 *                      between each cell, plus 1 (that is, the number of
 *                      values per cell)
 * @param  width        The horizontal number of pixels in the rasters
 * @param  height       The vertical number of pixels in the rasters
 * @param  saturations  The subpixel rendering saturation for each raster,
 *                      1 for regular subpixel rendering, 0 for greyscale,
 *                      values in between for a compromise
 * @param  primary_ys   The CIE Y value (in e.g. CIE xyY or CIE XYZ) for
 *                      each subpixel colour; or `NULL` for the sRGB values
 *                      (this is only allowed if there are exactly 3 rasters)
 */
void libglitter_per_channel_desaturate_double(double **, size_t, size_t, size_t, size_t, size_t,
                                              const double *restrict, const double *restrict);

/**
 * This value is identical to `libglitter_per_channel_desaturate_double`,
 * apart from it parameter types, see `libglitter_per_channel_desaturate_double`
 * for details about this function
 */
void libglitter_per_channel_desaturate_float(float **, size_t, size_t, size_t, size_t, size_t,
                                             const float *restrict, const float *restrict);


/**
 * Get the matrix each pixel shall be multiplied with
 * to convert it from the output's colour model to sRGB
 * or CIE XYZ
 * 
 * This is useful when the output does not use sRGB, or
 * CIE XYZ, but the application does. If the application
 * uses some other colour model, this function can output
 * the conversion matrix for the CIE XYZ colour model,
 * which can that be right-hand multiplied to get the
 * conversion matrix for some other colour; but be aware
 * that the output matrix is in column-major order, not
 * row-major order
 * 
 * @param  matrix   Output buffer for the conversion matrix, in column-major order
 * @param  c1x      The CIE x value (as in CIE xyY) of the output's first primary colour
 * @param  c1y      The CIE y value (as in CIE xyY) of the output's first primary colour
 * @param  c2x      The CIE x value (as in CIE xyY) of the output's second primary colour
 * @param  c2y      The CIE y value (as in CIE xyY) of the output's second primary colour
 * @param  c3x      The CIE x value (as in CIE xyY) of the output's third primary colour
 * @param  c3y      The CIE y value (as in CIE xyY) of the output's third primary colour
 * @param  white_x  The CIE x value (as in CIE xyY) of the output's white point
 * @param  white_y  The CIE y value (as in CIE xyY) of the output's white point
 * @param  white_Y  The CIE Y value (as in CIE xyY) of the output's white point, normally 1
 * @param  xyz      Whether the output conversion matrix should be to CIE XYZ rather the sRGB
 * @param  c1Yp     Output parameter for the first primary colour CIE Y value, or `NULL`
 * @param  c2Yp     Output parameter for the second primary colour CIE Y value, or `NULL`
 * @param  c3Yp     Output parameter for the third primary colour CIE Y value, or `NULL`
 * 
 * `LIBGLITTER_ILLUMINANT_D65` can be input in place of
 * `white_x, white_y, white_Y` (it expands to three arguments)
 * if the output's whitepoint is the D65 illuminant
 */
void libglitter_get_colour_model_conversion_matrix_double(double[3][3], double, double, double, double,
                                                          double, double, double, double, double, int,
                                                          double *, double *, double *);

/**
 * This value is identical to `libglitter_get_colour_model_conversion_matrix_double`,
 * apart from it parameter types, see `libglitter_get_colour_model_conversion_matrix_double`
 * for details about this function
 */
void libglitter_get_colour_model_conversion_matrix_float(float[3][3], float, float, float, float,
                                                         float, float, float, float, float, int,
                                                         float *, float *, float *);


/**
 * Convert set of rasters from one colour model to another
 * 
 * @param  n                The number of input rasters
 * @param  m                The number of output rasters
 * @param  outputs          Array of output rasters. The function may change
 *                          the offset for each raster, as such, the given
 *                          pointer shall not be used anywhere else during
 *                          the execution of the function and the inner
 *                          pointers shall be considered undefined after the
 *                          execution of the function.
 * @param  inputs           Array of input rasters. The function may change
 *                          the offset for each raster, as such, the given
 *                          pointer shall not be used anywhere else during
 *                          the execution of the function and the inner
 *                          pointers shall be considered undefined after the
 *                          execution of the function.
 * @param  output_rowsize   The number of cells in a row in each output raster
 * @param  output_cellsize  The number of values stored in each output raster,
 *                          between each cell, plus 1 (that is, the number of
 *                          values per cell)
 * @param  input_rowsize    The number of cells in a row in each input raster
 * @param  input_cellsize   The number of values stored in each input raster,
 *                          between each cell, plus 1 (that is, the number of
 *                          values per cell)
 * @param  width            The horizontal number of pixels in the rasters
 * @param  height           The vertical number of pixels in the rasters
 * @param  matrix           Colour model conversion matrix, in column-major order
 */
void libglitter_colour_model_convert_rasters_double(size_t n, size_t m, double **, const double **, size_t,
                                                    size_t, size_t, size_t, size_t, size_t, const double[m][n]);

/**
 * This value is identical to `libglitter_colour_model_convert_rasters_double`,
 * apart from it parameter types, see `libglitter_colour_model_convert_rasters_double`
 * for details about this function
 */
void libglitter_colour_model_convert_rasters_float(size_t n, size_t m, float **, const float **, size_t,
                                                   size_t, size_t, size_t, size_t, size_t, const float[m][n]);


#endif
/* TODO add `restrict` where appropriate */