1 /*
2 Copyright (C) 2017-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: dk4cs.ctr
12 */
13 
14 #ifndef DK4CS_H_INCLUDED
15 /** Avoid multiple inclusions. */
16 #define DK4CS_H_INCLUDED 1
17 
18 
19 /**	@file	dk4cs.h	Color spaces, especially for bitmap images.
20 
21 This module provides color space conversion functions.
22 
23 Note: You should not use this module for conversion from other color spaces
24 to CMYK or vice versa. Conversion to CMYK should be done by professional
25 programs, as the conversion depends on the production process, the used
26 inks, and the used paper. Professional conversion programs use color profiles
27 and let you choose a number of settings. This module uses just simple
28 formulas.
29 
30 The following symbols are used in formulas below:
31 
32 Symbol | Meaning
33 :----: | :-----:
34 d | Bit depth (integer), number of bits per component (sample)
35 M | Maximum component value (integer), 2^d-1
36 r | Red component for a pixel (integer), 0<=r<=M
37 g | Green component for a pixel (integer), 0<=r<=M
38 b | Blue component for a pixel (integer), 0<=b<=M
39 e | Gray value for a pixel (integer), 0<=e<=M
40 c | Cyan component for a pixel (integer), 0<=c<=M
41 m | Magenta component for a pixel (integer), 0<=m<=M
42 y | Yellow component for pixel (integer), 0<=y<=M
43 k | Black or key component for a pixel (integer), 0<=k<=M
44 maxrgb | Maximum value of r, g, and b (integer), 0<=maxrgb<=M
45 mincmy | Minimum value of c, m, and y (integer), 0<=mincmy<=M
46 r' | Normalized red component (floating point), 0.0<=r'<=1.0
47 g' | Normalized green component (floating point), 0.0<=g'<=1.0
48 b' | Normalized blue component (floating point), 0.0<=b'<=1.0
49 e' | Normalized gray component (floating point), 0.0<=e'<=1.0
50 c' | Normalized cyan component (floating point), 0.0<=c'<=1.0
51 m' | Normalized magenta component (floating point), 0.0<=m'<=1.0
52 y' | Normalized yellow component (floating point), 0.0<=y'<=1.0
53 k' | Normalized black component (floating point), 0.0<=k'<=1.0
54 maxrgb' | Normalized red component (floating point), 0.0<=maxrgb'<=1.0
55 mincmy' | Normalized red component (floating point), 0.0<=mincmy'<=1.0
56 ucr(x) | Undercolour removal function, maps [0,1] to [0,1]
57 bg(x) | Black generation function, maps [0,1] to [0,1]
58 
59 To switch from default algorithms to other algorithms, open a
60 conversion context, set up the conversion context, pass the context to
61 the conversion functions and close the context when no longer needed.
62 */
63 
64 #ifndef	DK4CONF_H_INCLUDED
65 #if	DK4_BUILDING_DKTOOLS4
66 #include "dk4conf.h"
67 #else
68 #include <dktools-4/dk4conf.h>
69 #endif
70 #endif
71 
72 #ifndef	DK4TYPES_H_INCLUDED
73 #if	DK4_BUILDING_DKTOOLS4
74 #include <libdk4base/dk4types.h>
75 #else
76 #include <dktools-4/dk4types.h>
77 #endif
78 #endif
79 
80 #ifndef	DK4ERROR_H_INCLUDED
81 #if	DK4_BUILDING_DKTOOLS4
82 #include <libdk4base/dk4error.h>
83 #else
84 #include <dktools-4/dk4error.h>
85 #endif
86 #endif
87 
88 #ifndef	DK4PX_H_INCLUDED
89 #if	DK4_BUILDING_DKTOOLS4
90 #include <libdk4bif/dk4px.h>
91 #else
92 #include <dktools-4/dk4px.h>
93 #endif
94 #endif
95 
96 
97 /**	Color spaces used by the images we want to process.
98 */
99 enum {
100 	DK4_CS_GRAY		= 0 ,		/**< Gray. */
101 	DK4_CS_GRAY_ALPHA ,			/**< Gray, opacity. */
102 	DK4_CS_RGB ,				/**< Red, green, blue. */
103 	DK4_CS_RGB_ALPHA ,			/**< Red, green, blue, opacity. */
104 	DK4_CS_CMYK ,				/**< Cyan, magentam, yellow, black (key). */
105 
106 	DK4_CS_MIN	= DK4_CS_GRAY ,	/**< Minimum value. */
107 	DK4_CS_MAX	= DK4_CS_CMYK	/**< Maximum value. */
108 };
109 
110 
111 /**	Choose algorithm to convert RGB to CMYK.
112 */
113 typedef enum {
114 
115 	DK4_CS_CONV_RGB_TO_CMYK_NOT_PS_PDF	= 0 ,
116 
117 	/**<	Algorithm differing from PS/PDF standard.
118 			Most web pages about color
119 			conversion recommend the algorithm
120 			like this (default):
121 			@code
122 			c' = 1 - r'
123 			m' = 1 - g'
124 			y' = 1 - b'
125 			mincmy' = min{c',m',y'}
126 			if 1 = mincmy'
127 			then
128 				k' = 1
129 				c' = m' = y' = 0
130 			else
131 				k' = mincmy'
132 				c' = (c' - k') / (1 - k')
133 				m' = (m' - k') / (1 - k')
134 				y' = (y' - k') / (1 - k')
135 			endif
136 			@endcode
137 			Substitution results in:
138 			@code
139 			maxrgb' = max{r',g',b'}
140 			if 0 = maxrgb'
141 			then
142 				k' = 1
143 				c' = m' = y' = 0
144 			else
145 				c' = (maxrgb' - r') / maxrgb'
146 				m' = (maxrgb' - g') / maxrgb'
147 				y' = (maxrgb' - b') / maxrgb'
148 				k' = 1 - maxrgb'
149 			endif
150 			@endcode
151 			The result for pixel components is:
152 			@code
153 			maxrgb = max{r,g,b}
154 			if 0 = maxrgb
155 			then
156 				k = M
157 				c = m = y = 0
158 			else
159 				c = (M * (maxrgb - r)) / maxrgb
160 				m = (M * (maxrgb - g)) / maxrgb
161 				y = (M * (maxrgb - b)) / maxrgb
162 				k = M - maxrgb
163 			endif
164 			@endcode
165 		*/
166 
167 
168 
169 	DK4_CS_CONV_RGB_TO_CMYK_PS_PDF
170 
171 	/**<	Algorithm as described in the PS and PDF standards.
172 			@code
173 			c' = 1 - r'
174 			m' = 1 - g'
175 			y' = 1 - b'
176 			mincmy' = min{c',m',y'}
177 			c' = c' - ucr(mincmy')
178 			m' = m' - ucr(mincmy')
179 			y' = y' - ucr(mincmy')
180 			k' = bg(mincmy')
181 			@endcode
182 			Substitution and use of simplified
183 			functions ucr(x)=x and bg(x)=x
184 			results in:
185 			@code
186 			maxrgb' = max{r',g',b'}
187 			c' = maxrgb' - r'
188 			m' = maxrgb' - g'
189 			y' = maxrgb' - b'
190 			k' = 1 - maxrgb'
191 			@endcode
192 			The result for components values is:
193 			@code
194 			maxrgb = max{r,g,b}
195 			c = maxrgb - r
196 			m = maxrgb - g
197 			y = maxrgb - b
198 			k = M - maxrgb
199 			@endcode
200 		*/
201 
202 } dk4_cs_conv_rgb_to_cmyk_t;
203 
204 
205 
206 /**	How to convert RGB to gray.
207 */
208 typedef enum {
209 								/**	Reproduce luminance (default).
210 									@code
211 									e' = 0.299 * r' + 0.587 * g' + 0.114 * b'
212 									e  = (299 * r + 587 * g + 114 * b) / 1000
213 									@endcode
214 								*/
215 	DK4_CS_CONV_RGB_TO_GRAY_ITU_BT601	= 0,
216 
217 
218 								/**	Reproduce luminance.
219 									Same as above but reduced number of digits
220 									in the coefficients.
221 									@code
222 									e' = 0.3 * r' + 0.59 * g' + 0.11 * b'
223 									e  = (30 * r + 59 * g + 11 * b) / 100
224 									@endcode
225 								*/
226 	DK4_CS_CONV_RGB_TO_GRAY_LUMA ,
227 
228 								/**	Reproduce luminance,
229 									use alternative coefficients.
230 									@code
231 									e' = 0.2126 * r' + 0.7152 * g' + 0.0722 * b'
232 									e  = (2126 * r + 7152 * g + 722 * b) / 10000
233 									@endcode
234 								*/
235 	DK4_CS_CONV_RGB_TO_GRAY_ITU_BT709 ,
236 
237 
238 								/**	Faster approximation for pixel values.
239 									@code
240 									e = (77 * r + 151 * g + 28 * b) >> 8
241 									@endcode
242 									For normalized colors use
243 									@code
244 									e' = 0.299 * r' + 0.587 * g' + 0.114 * b'
245 									@endcode
246 								*/
247 	DK4_CS_CONV_RGB_TO_GRAY_FAST ,
248 
249 
250 								/**	Still faster - and more inaccurate -
251 									approximation for pixel values.
252 									@code
253 									e = ((r << 1) + ((g << 2) + g) + b) >> 3
254 									@endcode
255 									is a fast implementation of
256 									@code
257 									e = (2 * r + 5 * g + b) / 8
258 									@endcode
259 									For normalized colors use
260 									@code
261 									e' = 0.299 * r' + 0.587 * g' + 0.114 * b'
262 									@endcode
263 								*/
264 	DK4_CS_CONV_RGB_TO_GRAY_VERY_FAST ,
265 
266 								/**	Use average.
267 									@code
268 									e' = (r' + g' + b') / 3
269 									e  = (r + g + b) / 3
270 									@endcode
271 								*/
272 	DK4_CS_CONV_RGB_TO_GRAY_AVERAGE ,
273 
274 
275 								/**	Desaturation.
276 									Flatter than luminance, less contrast.
277 									@code
278 									e' = (max{r',g',b'} + min{r',g',b'}) / 2
279 									e  = (max{r,b,b} + min{r,g,b}) / 2
280 									@endcode
281 								*/
282 	DK4_CS_CONV_RGB_TO_GRAY_DESATURATION ,
283 
284 
285 								/**	Minimum decomposition.
286 									Produces dark images.
287 									@code
288 									e' = min{r',g',b'}
289 									e  = min{r,g,b}
290 									@endcode
291 								*/
292 	DK4_CS_CONV_RGB_TO_GRAY_MIN_DECOMPOSITION ,
293 
294 								/**	Medium value decomposition
295 									(not minimum, not maximum).
296 								*/
297 	DK4_CS_CONV_RGB_TO_GRAY_MEDIUM_DECOMPOSITION ,
298 
299 
300 								/**	Maximum decomposition.
301 									Produces bright images.
302 									@code
303 									e' = max{r',g',b'}
304 									e  = max{r,g,b}
305 									@endcode
306 								*/
307 	DK4_CS_CONV_RGB_TO_GRAY_MAX_DECOMPOSITION ,
308 
309 
310 								/**	Use just red channel.
311 									@code
312 									e' = r'
313 									e  = r
314 									@endcode
315 								*/
316 	DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_RED ,
317 
318 
319 								/**	Use just green channel.
320 									@code
321 									e' = g'
322 									e  = g
323 									@endcode
324 								*/
325 	DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_GREEN ,
326 
327 
328 								/**	Use just blue channel.
329 									@code
330 									e' = b'
331 									e  = b
332 									@endcode
333 								*/
334 	DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_BLUE ,
335 
336 								/**	Minimum value.
337 								*/
338 	DK4_CS_CONV_RGB_TO_GRAY_MIN	=	DK4_CS_CONV_RGB_TO_GRAY_ITU_BT601 ,
339 
340 								/**	Maximum value.
341 								*/
342 	DK4_CS_CONV_RGB_TO_GRAY_MAX = DK4_CS_CONV_RGB_TO_GRAY_CHANNEL_BLUE
343 
344 } dk4_cs_conv_rgb_to_gray_t;
345 
346 
347 
348 /**	How to handle alpha channel.
349 	Only used when converting from a color space containing alpha data
350 	to a color space not containing alpha data.
351 */
352 typedef enum {
353 							/**	Mix against specified background.
354 							*/
355 	DK4_CS_CONV_ALPHA_MIX	= 0,
356 
357 							/**	Ignore alpha value, just return foreground.
358 							*/
359 	DK4_CS_CONV_ALPHA_FOREGROUND
360 
361 } dk4_cs_conv_alpha_t;
362 
363 
364 
365 /**	Conversion context containing setup details for conversions.
366 */
367 
368 typedef struct {
369 	dk4_cs_conv_rgb_to_cmyk_t	rgb_to_cmyk;	/**< RGB to CMYK. */
370 	dk4_cs_conv_rgb_to_gray_t	rgb_to_gray;	/**< RGB to gray. */
371 	dk4_cs_conv_alpha_t			alpha;			/**< Alpha channel handling. */
372 } dk4_cs_conv_ctx_t;
373 
374 
375 
376 #ifdef	__cplusplus
377 extern "C" {
378 #endif
379 
380 
381 /**	Create new conversion context and initialize it.
382 	@param	erp		Error report, may be NULL.
383 	@return	Valid pointer on success, NULL on error.
384 
385 	Error codes:
386 	- DK4_E_MEMORY_ALLOCATION_FAILED<br>
387 	  with mem.elsize and mem.nelem
388 	  set if there is not enough memory available.
389 */
390 
391 dk4_cs_conv_ctx_t *
392 dk4cs_context_open(
393 	dk4_er_t		*erp
394 );
395 
396 
397 /**	Initialize a conversion context.
398 	@param	pctx	Context to set up.
399 	@param	erp		Error report, may be NULL.
400 	@return	1 on success, 0 on error.
401 
402 	Error codes:
403 	- DK4_E_INVALID_ARGUMENTS<br>
404 	  if pctx is NULL.
405 */
406 
407 int
408 dk4cs_context_init(
409 	dk4_cs_conv_ctx_t		*pctx,
410 	dk4_er_t				*erp
411 );
412 
413 
414 /**	Set RGB to CMYK handling in a conversion context.
415 	@param	pctx		Context to set up.
416 	@param	rgb_to_cmyk	Details for RGB to CMYK conversion.
417 	@param	erp			Error report, may be NULL.
418 	@return	1 on success, 0 on error.
419 
420 	Error codes:
421 	- DK4_E_INVALID_ARGUMENTS<br>
422 	  if pctx is NULL.
423 */
424 
425 int
426 dk4cs_context_set_rgb_to_cmyk(
427 	dk4_cs_conv_ctx_t			*pctx,
428 	dk4_cs_conv_rgb_to_cmyk_t	 rgb_to_cmyk,
429 	dk4_er_t					*erp
430 );
431 
432 
433 /**	Set RGB to gray handling in a conversion context.
434 	@param	pctx		Context to set up.
435 	@param	rgb_to_gray	Details or RGB to gray conversion.
436 	@param	erp			Error report, may be NULL.
437 	@return	1 on success, 0 on error.
438 
439 	Error codes:
440 	- DK4_E_INVALID_ARGUMENTS<br>
441 	  if pctx is NULL.
442 */
443 
444 int
445 dk4cs_context_set_rgb_to_gray(
446 	dk4_cs_conv_ctx_t			*pctx,
447 	dk4_cs_conv_rgb_to_gray_t	 rgb_to_gray,
448 	dk4_er_t					*erp
449 );
450 
451 
452 /**	Set alpha channel handling.
453 	@param	pctx	Context to set up.
454 	@param	alpha	Alpha channel handling method.
455 	@param	erp		Error report, may be NULL.
456 	@return	1 on success, 0 on error.
457 
458 	Error codes:
459 	- DK4_E_INVALID_ARGUMENTS<br>
460 	  if pctx is NULL.
461 */
462 
463 int
464 dk4cs_context_set_alpha(
465 	dk4_cs_conv_ctx_t			*pctx,
466 	dk4_cs_conv_alpha_t			 alpha,
467 	dk4_er_t					*erp
468 );
469 
470 /**	Destroy conversion context, release resources.
471 	@param	pctx	Conversion context to close.
472 */
473 
474 void
475 dk4cs_context_close(
476 	dk4_cs_conv_ctx_t	*pctx
477 );
478 
479 
480 /**	Convert pixel data from one color space into another, samples are dk4_px_t.
481 	@param	dptr	Address of destination array.
482 	@param	dcs		Destination color space.
483 	@param	dsz		Size of destination array (number of elements).
484 	@param	sptr	Address of source array.
485 	@param	scs		Source color space.
486 	@param	ssz		Source array size (number of elements).
487 	@param	bptr	Address of background array, may be NULL.
488 	@param	bsz		Size of background array (number of elements), may be 0.
489 	@param	max		Maximum value for a component.
490 	@param	pctx	Conversion context, may be NULL.
491 	@param	erp		Error report, may be NULL.
492 
493 	Error codes:
494 	- DK4_E_INVALID_ARGUMENTS<br>
495 	  if anything is wrong with arguments, i.e.:
496 	  * dptr or sptr is NULL,
497 	  * dcs or scs is not a valid color space,
498 	  * dsz or ssz is too small for the color space,
499 	  * max is 0,
500 	  * one of the sptr components is larger than max
501 	  * a background is required but bptr is NULL, bsz is too small
502 	    for the colro space or one of the background components is larger
503 		than max.
504 */
505 
506 void
507 dk4cs_px_convert(
508 	dk4_px_t				*dptr,
509 	int			 			 dcs,
510 	size_t		 			 dsz,
511 	dk4_px_t const			*sptr,
512 	int						 scs,
513 	size_t					 ssz,
514 	dk4_px_t const			*bptr,
515 	size_t					 bsz,
516 	dk4_px_t				 max,
517 	dk4_cs_conv_ctx_t const	*pctx,
518 	dk4_er_t				*erp
519 );
520 
521 
522 /**	Convert pixel data from one color space into another, samples are double.
523 	@param	dptr	Address of destination array, values in interval [0;1].
524 	@param	dcs		Destination color space.
525 	@param	dsz		Size of destination array (number of elements).
526 	@param	sptr	Address of source array, values in interval [0;1].
527 	@param	scs		Source color space.
528 	@param	ssz		Source array size (number of elements).
529 	@param	bptr	Address of background array, values in [0;1], may be NULL.
530 	@param	bsz		Size of background array (number of elements), may be 0.
531 	@param	pctx	Conversion context, may be NULL.
532 	@param	erp		Error report, may be NULL.
533 
534 	Error codes:
535 	- DK4_E_INVALID_ARGUMENTS<br>
536 	  if anything is wrong with arguments, i.e.:
537 	  * dptr or sptr is NULL,
538 	  * dcs or scs is not a valid color space,
539 	  * dsz or ssz is too small for the color space,
540 	  * one of the sptr components is out of interval [0;1],
541 	  * a background is required but bptr is NULL, bsz is too small
542 	    for the colro space or one of the background components is
543 		out of interval [0;1].
544 */
545 
546 void
547 dk4cs_color_convert(
548 	double					*dptr,
549 	int			 			 dcs,
550 	size_t		 			 dsz,
551 	double const			*sptr,
552 	int						 scs,
553 	size_t					 ssz,
554 	double const			*bptr,
555 	size_t					 bsz,
556 	dk4_cs_conv_ctx_t const	*pctx,
557 	dk4_er_t				*erp
558 );
559 
560 
561 /**	Mix pixel data foreground against background value.
562 	@param	value	Foreground value.
563 	@param	alpha	Foreground opacity.
564 	@param	bg		Background value.
565 	@param	max		Maximum for foreground, background, and alpha.
566 	@return	Mixing result.
567 */
568 
569 dk4_px_t
570 dk4cs_mix_alpha(
571 	dk4_px_t value,
572 	dk4_px_t alpha,
573 	dk4_px_t bg,
574 	dk4_px_t max
575 );
576 
577 
578 /**	Mix pixel data RGB to gray.
579 	@param	r		Red.
580 	@param	g		Green.
581 	@param	b		Blue.
582 	@param	pctx	Conversion context, may be NULL.
583 	@return	Gray value for RGB pixel.
584 */
585 
586 dk4_px_t
587 dk4cs_mix_rgb_to_gray(
588 	unsigned long			 r,
589 	unsigned long			 g,
590 	unsigned long			 b,
591 	dk4_cs_conv_ctx_t const	*pctx
592 );
593 
594 
595 /**	Mix normalized color foreground against background using alpha value.
596 	@param	v	Foreground value, normalized.
597 	@param	a	Alpha value, normalized.
598 	@param	b	Background value, normalized.
599 */
600 
601 double
602 dk4cs_color_mix_alpha(
603 	double		v,
604 	double		a,
605 	double		b
606 );
607 
608 
609 /**	Mix normalized color RGB to gray
610 	@param	r		Normalized red component.
611 	@param	g		Normalized green component.
612 	@param	b		Normalized blue component.
613 	@param	pctx	Conversion context, may be NULL.
614 	@return	Gray value.
615 */
616 
617 double
618 dk4cs_color_mix_rgb_to_gray(
619 	double					 r,
620 	double					 g,
621 	double					 b,
622 	dk4_cs_conv_ctx_t const	*pctx
623 );
624 
625 
626 /**	Retrieve number of components for a color space.
627 	@param	cs	Color space.
628 	@return	Number of components in color space cs.
629 */
630 
631 size_t
632 dk4cs_color_space_size(int cs);
633 
634 
635 /**	Check whether an integer number represents a valid color space.
636 	@param	cs	Number to check.
637 	@return	1 on success (cs is a color space), 0 otherwise.
638 */
639 
640 int
641 dk4cs_check(int cs);
642 
643 
644 /**	Set RGB to CMYK conversion method from text.
645 	@param	pctx	Context to set up.
646 	@param	txt		Text containing the method name.
647 	@param	erp		Error report, may be NULL.
648 
649 	Error codes:
650 	- DK4_E_INVALID_ARGUMENTS<br>
651 	  if pctx or txt is NULL,
652 	- DK4_E_SYNTAX<br>
653 	  if txt does not cotain a valid method name.
654 */
655 
656 int
657 dk4cs_context_text_rgb_to_cmyk(
658 	dk4_cs_conv_ctx_t			*pctx,
659 	dkChar				const	*txt,
660 	dk4_er_t					*erp
661 );
662 
663 
664 /**	Set RGB to GRAY conversion method from text.
665 	@param	pctx	Context to set up.
666 	@param	txt		Text containing the method name.
667 	@param	erp		Error report, may be NULL.
668 
669 	Error codes:
670 	- DK4_E_INVALID_ARGUMENTS<br>
671 	  if pctx or txt is NULL,
672 	- DK4_E_SYNTAX<br>
673 	  if txt does not cotain a valid method name.
674 */
675 
676 int
677 dk4cs_context_text_rgb_to_gray(
678 	dk4_cs_conv_ctx_t			*pctx,
679 	dkChar				const	*txt,
680 	dk4_er_t					*erp
681 );
682 
683 
684 /**	Set alpha channel handling method.
685 	@param	pctx	Context to set up.
686 	@param	txt		Text containing the method name.
687 	@param	erp		Error report, may be NULL.
688 
689 	Error codes:
690 	- DK4_E_INVALID_ARGUMENTS<br>
691 	  if pctx or txt is NULL,
692 	- DK4_E_SYNTAX<br>
693 	  if txt does not cotain a valid method name.
694 */
695 
696 int
697 dk4cs_context_text_alpha(
698 	dk4_cs_conv_ctx_t			*pctx,
699 	dkChar				const	*txt,
700 	dk4_er_t					*erp
701 );
702 
703 
704 #ifdef	__cplusplus
705 }
706 #endif
707 
708 
709 /* vim: set ai sw=4 ts=4 : */
710 
711 #endif
712