/* Copyright (C) 2017-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4cs.ctr */ #ifndef DK4CS_H_INCLUDED /** Avoid multiple inclusions. */ #define DK4CS_H_INCLUDED 1 #line 9 "dk4cs.ctr" /** @file dk4cs.h Color spaces, especially for bitmap images. This module provides color space conversion functions. Note: You should not use this module for conversion from other color spaces to CMYK or vice versa. Conversion to CMYK should be done by professional programs, as the conversion depends on the production process, the used inks, and the used paper. Professional conversion programs use color profiles and let you choose a number of settings. This module uses just simple formulas. The following symbols are used in formulas below: Symbol | Meaning :----: | :-----: d | Bit depth (integer), number of bits per component (sample) M | Maximum component value (integer), 2^d-1 r | Red component for a pixel (integer), 0<=r<=M g | Green component for a pixel (integer), 0<=r<=M b | Blue component for a pixel (integer), 0<=b<=M e | Gray value for a pixel (integer), 0<=e<=M c | Cyan component for a pixel (integer), 0<=c<=M m | Magenta component for a pixel (integer), 0<=m<=M y | Yellow component for pixel (integer), 0<=y<=M k | Black or key component for a pixel (integer), 0<=k<=M maxrgb | Maximum value of r, g, and b (integer), 0<=maxrgb<=M mincmy | Minimum value of c, m, and y (integer), 0<=mincmy<=M r' | Normalized red component (floating point), 0.0<=r'<=1.0 g' | Normalized green component (floating point), 0.0<=g'<=1.0 b' | Normalized blue component (floating point), 0.0<=b'<=1.0 e' | Normalized gray component (floating point), 0.0<=e'<=1.0 c' | Normalized cyan component (floating point), 0.0<=c'<=1.0 m' | Normalized magenta component (floating point), 0.0<=m'<=1.0 y' | Normalized yellow component (floating point), 0.0<=y'<=1.0 k' | Normalized black component (floating point), 0.0<=k'<=1.0 maxrgb' | Normalized red component (floating point), 0.0<=maxrgb'<=1.0 mincmy' | Normalized red component (floating point), 0.0<=mincmy'<=1.0 ucr(x) | Undercolour removal function, maps [0,1] to [0,1] bg(x) | Black generation function, maps [0,1] to [0,1] To switch from default algorithms to other algorithms, open a conversion context, set up the conversion context, pass the context to the conversion functions and close the context when no longer needed. */ #ifndef DK4CONF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4conf.h" #else #include #endif #endif #ifndef DK4TYPES_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4types.h" #else #include #endif #endif #ifndef DK4ERROR_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4error.h" #else #include #endif #endif #ifndef DK4PX_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4px.h" #else #include #endif #endif /** Color spaces used by the images we want to process. */ enum { DK4_CS_GRAY = 0 , /**< Gray. */ DK4_CS_GRAY_ALPHA , /**< Gray, opacity. */ DK4_CS_RGB , /**< Red, green, blue. */ DK4_CS_RGB_ALPHA , /**< Red, green, blue, opacity. */ DK4_CS_CMYK , /**< Cyan, magentam, yellow, black (key). */ DK4_CS_MIN = DK4_CS_GRAY , /**< Minimum value. */ DK4_CS_MAX = DK4_CS_CMYK /**< Maximum value. */ }; /** Choose algorithm to convert RGB to CMYK. */ typedef enum { DK4_CS_CONV_RGB_TO_CMYK_NOT_PS_PDF = 0 , /**< Algorithm differing from PS/PDF standard. Most web pages about color conversion recommend the algorithm like this (default): @code c' = 1 - r' m' = 1 - g' y' = 1 - b' mincmy' = min{c',m',y'} if 1 = mincmy' then k' = 1 c' = m' = y' = 0 else k' = mincmy' c' = (c' - k') / (1 - k') m' = (m' - k') / (1 - k') y' = (y' - k') / (1 - k') endif @endcode Substitution results in: @code maxrgb' = max{r',g',b'} if 0 = maxrgb' then k' = 1 c' = m' = y' = 0 else c' = (maxrgb' - r') / maxrgb' m' = (maxrgb' - g') / maxrgb' y' = (maxrgb' - b') / maxrgb' k' = 1 - maxrgb' endif @endcode The result for pixel components is: @code maxrgb = max{r,g,b} if 0 = maxrgb then k = M c = m = y = 0 else c = (M * (maxrgb - r)) / maxrgb m = (M * (maxrgb - g)) / maxrgb y = (M * (maxrgb - b)) / maxrgb k = M - maxrgb endif @endcode */ DK4_CS_CONV_RGB_TO_CMYK_PS_PDF /**< Algorithm as described in the PS and PDF standards. @code c' = 1 - r' m' = 1 - g' y' = 1 - b' mincmy' = min{c',m',y'} c' = c' - ucr(mincmy') m' = m' - ucr(mincmy') y' = y' - ucr(mincmy') k' = bg(mincmy') @endcode Substitution and use of simplified functions ucr(x)=x and bg(x)=x results in: @code maxrgb' = max{r',g',b'} c' = maxrgb' - r' m' = maxrgb' - g' y' = maxrgb' - b' k' = 1 - maxrgb' @endcode The result for components values is: @code maxrgb = max{r,g,b} c = maxrgb - r m = maxrgb - g y = maxrgb - b k = M - maxrgb @endcode */ } dk4_cs_conv_rgb_to_cmyk_t; /** How to convert RGB to gray. */ typedef enum { /** Reproduce luminance (default). @code e' = 0.299 * r' + 0.587 * g' + 0.114 * b' e = (299 * r + 587 * g + 114 * b) / 1000 @endcode */ DK4_CS_CONV_RGB_TO_GRAY_ITU_BT601 = 0, /** Reproduce luminance. Same as above but reduced number of digits in the coefficients. @code e' = 0.3 * r' + 0.59 * g' + 0.11 * b' e = (30 * r + 59 * g + 11 * b) / 100 @endcode */ DK4_CS_CONV_RGB_TO_GRAY_LUMA , /** Reproduce luminance, use alternative coefficients. @code e' = 0.2126 * r' + 0.7152 * g' + 0.0722 * b' e = (2126 * r + 7152 * g + 722 * b) / 10000 @endcode */ DK4_CS_CONV_RGB_TO_GRAY_ITU_BT709 , /** Faster approximation for pixel values. @code e = (77 * r + 151 * g + 28 * b) >> 8 @endcode For normalized colors use @code e' = 0.299 * r' + 0.587 * g' + 0.114 * b' @endcode */ DK4_CS_CONV_RGB_TO_GRAY_FAST , /** Still faster - and more inaccurate - approximation for pixel values. @code e = ((r << 1) + ((g << 2) + g) + b) >> 3 @endcode is a fast implementation of @code e = (2 * r + 5 * g + b) / 8 @endcode For normalized colors use @code e' = 0.299 * r' + 0.587 * g' + 0.114 * b' @endcode */ DK4_CS_CONV_RGB_TO_GRAY_VERY_FAST , /** Use average. @code e' = (r' + g' + b') / 3 e = (r + g + b) / 3 @endcode */ DK4_CS_CONV_RGB_TO_GRAY_AVERAGE , /** Desaturation. Flatter than luminance, less contrast. @code e' = (max{r',g',b'} + min{r',g',b'}) / 2 e = (max{r,b,b} + min{r,g,b}) / 2 @endcode */ DK4_CS_CONV_RGB_TO_GRAY_DESATURATION , /** Minimum decomposition. Produces dark images. @code e' = min{r',g',b'} e = min{r,g,b} @endcode */ DK4_CS_CONV_RGB_TO_GRAY_MIN_DECOMPOSITION , /** Medium value decomposition (not minimum, not maximum). */ DK4_CS_CONV_RGB_TO_GRAY_MEDIUM_DECOMPOSITION , /** Maximum decomposition. Produces bright images. @code e' = max{r',g',b'} e = max{r,g,b} @endcode */ DK4_CS_CONV_RGB_TO_GRAY_MAX_DECOMPOSITION , /** Use just red channel. @code e' = r' e = r @endcode */ DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_RED , /** Use just green channel. @code e' = g' e = g @endcode */ DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_GREEN , /** Use just blue channel. @code e' = b' e = b @endcode */ DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_BLUE , /** Minimum value. */ DK4_CS_CONV_RGB_TO_GRAY_MIN = DK4_CS_CONV_RGB_TO_GRAY_ITU_BT601 , /** Maximum value. */ DK4_CS_CONV_RGB_TO_GRAY_MAX = DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_BLUE } dk4_cs_conv_rgb_to_gray_t; /** How to handle alpha channel. Only used when converting from a color space containing alpha data to a color space not containing alpha data. */ typedef enum { /** Mix against specified background. */ DK4_CS_CONV_ALPHA_MIX = 0, /** Ignore alpha value, just return foreground. */ DK4_CS_CONV_ALPHA_FOREGROUND } dk4_cs_conv_alpha_t; /** Conversion context containing setup details for conversions. */ typedef struct { dk4_cs_conv_rgb_to_cmyk_t rgb_to_cmyk; /**< RGB to CMYK. */ dk4_cs_conv_rgb_to_gray_t rgb_to_gray; /**< RGB to gray. */ dk4_cs_conv_alpha_t alpha; /**< Alpha channel handling. */ } dk4_cs_conv_ctx_t; #ifdef __cplusplus extern "C" { #endif /** Create new conversion context and initialize it. @param erp Error report, may be NULL. @return Valid pointer on success, NULL on error. Error codes: - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available. */ dk4_cs_conv_ctx_t * dk4cs_context_open( dk4_er_t *erp ); /** Initialize a conversion context. @param pctx Context to set up. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx is NULL. */ int dk4cs_context_init( dk4_cs_conv_ctx_t *pctx, dk4_er_t *erp ); /** Set RGB to CMYK handling in a conversion context. @param pctx Context to set up. @param rgb_to_cmyk Details for RGB to CMYK conversion. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx is NULL. */ int dk4cs_context_set_rgb_to_cmyk( dk4_cs_conv_ctx_t *pctx, dk4_cs_conv_rgb_to_cmyk_t rgb_to_cmyk, dk4_er_t *erp ); /** Set RGB to gray handling in a conversion context. @param pctx Context to set up. @param rgb_to_gray Details or RGB to gray conversion. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx is NULL. */ int dk4cs_context_set_rgb_to_gray( dk4_cs_conv_ctx_t *pctx, dk4_cs_conv_rgb_to_gray_t rgb_to_gray, dk4_er_t *erp ); /** Set alpha channel handling. @param pctx Context to set up. @param alpha Alpha channel handling method. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx is NULL. */ int dk4cs_context_set_alpha( dk4_cs_conv_ctx_t *pctx, dk4_cs_conv_alpha_t alpha, dk4_er_t *erp ); /** Destroy conversion context, release resources. @param pctx Conversion context to close. */ void dk4cs_context_close( dk4_cs_conv_ctx_t *pctx ); /** Convert pixel data from one color space into another, samples are dk4_px_t. @param dptr Address of destination array. @param dcs Destination color space. @param dsz Size of destination array (number of elements). @param sptr Address of source array. @param scs Source color space. @param ssz Source array size (number of elements). @param bptr Address of background array, may be NULL. @param bsz Size of background array (number of elements), may be 0. @param max Maximum value for a component. @param pctx Conversion context, may be NULL. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if anything is wrong with arguments, i.e.: * dptr or sptr is NULL, * dcs or scs is not a valid color space, * dsz or ssz is too small for the color space, * max is 0, * one of the sptr components is larger than max * a background is required but bptr is NULL, bsz is too small for the colro space or one of the background components is larger than max. */ void dk4cs_px_convert( dk4_px_t *dptr, int dcs, size_t dsz, dk4_px_t const *sptr, int scs, size_t ssz, dk4_px_t const *bptr, size_t bsz, dk4_px_t max, dk4_cs_conv_ctx_t const *pctx, dk4_er_t *erp ); /** Convert pixel data from one color space into another, samples are double. @param dptr Address of destination array, values in interval [0;1]. @param dcs Destination color space. @param dsz Size of destination array (number of elements). @param sptr Address of source array, values in interval [0;1]. @param scs Source color space. @param ssz Source array size (number of elements). @param bptr Address of background array, values in [0;1], may be NULL. @param bsz Size of background array (number of elements), may be 0. @param pctx Conversion context, may be NULL. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if anything is wrong with arguments, i.e.: * dptr or sptr is NULL, * dcs or scs is not a valid color space, * dsz or ssz is too small for the color space, * one of the sptr components is out of interval [0;1], * a background is required but bptr is NULL, bsz is too small for the colro space or one of the background components is out of interval [0;1]. */ void dk4cs_color_convert( double *dptr, int dcs, size_t dsz, double const *sptr, int scs, size_t ssz, double const *bptr, size_t bsz, dk4_cs_conv_ctx_t const *pctx, dk4_er_t *erp ); /** Mix pixel data foreground against background value. @param value Foreground value. @param alpha Foreground opacity. @param bg Background value. @param max Maximum for foreground, background, and alpha. @return Mixing result. */ dk4_px_t dk4cs_mix_alpha( dk4_px_t value, dk4_px_t alpha, dk4_px_t bg, dk4_px_t max ); /** Mix pixel data RGB to gray. @param r Red. @param g Green. @param b Blue. @param pctx Conversion context, may be NULL. @return Gray value for RGB pixel. */ dk4_px_t dk4cs_mix_rgb_to_gray( unsigned long r, unsigned long g, unsigned long b, dk4_cs_conv_ctx_t const *pctx ); /** Mix normalized color foreground against background using alpha value. @param v Foreground value, normalized. @param a Alpha value, normalized. @param b Background value, normalized. */ double dk4cs_color_mix_alpha( double v, double a, double b ); /** Mix normalized color RGB to gray @param r Normalized red component. @param g Normalized green component. @param b Normalized blue component. @param pctx Conversion context, may be NULL. @return Gray value. */ double dk4cs_color_mix_rgb_to_gray( double r, double g, double b, dk4_cs_conv_ctx_t const *pctx ); /** Retrieve number of components for a color space. @param cs Color space. @return Number of components in color space cs. */ size_t dk4cs_color_space_size(int cs); /** Check whether an integer number represents a valid color space. @param cs Number to check. @return 1 on success (cs is a color space), 0 otherwise. */ int dk4cs_check(int cs); /** Set RGB to CMYK conversion method from text. @param pctx Context to set up. @param txt Text containing the method name. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx or txt is NULL, - DK4_E_SYNTAX
if txt does not cotain a valid method name. */ int dk4cs_context_text_rgb_to_cmyk( dk4_cs_conv_ctx_t *pctx, dkChar const *txt, dk4_er_t *erp ); /** Set RGB to GRAY conversion method from text. @param pctx Context to set up. @param txt Text containing the method name. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx or txt is NULL, - DK4_E_SYNTAX
if txt does not cotain a valid method name. */ int dk4cs_context_text_rgb_to_gray( dk4_cs_conv_ctx_t *pctx, dkChar const *txt, dk4_er_t *erp ); /** Set alpha channel handling method. @param pctx Context to set up. @param txt Text containing the method name. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if pctx or txt is NULL, - DK4_E_SYNTAX
if txt does not cotain a valid method name. */ int dk4cs_context_text_alpha( dk4_cs_conv_ctx_t *pctx, dkChar const *txt, dk4_er_t *erp ); #ifdef __cplusplus } #endif /* vim: set ai sw=4 ts=4 : */ #endif