3 * Convert PixelType values macros and functions
5 * Copyright (C) 2011-2014 Cyril Hrubis <metan@ucw.cz>
6 * Copyright (C) 2011 Tomas Gavenciak <gavento@ucw.cz>
9 @ # RGB -> CMYK requires special handling
10 @ def rgb_to_cmyk(in_pix, out_pix):
11 @ R = in_pix.chans['R']
12 @ G = in_pix.chans['G']
13 @ B = in_pix.chans['B']
14 @ C = out_pix.chans['C']
15 @ M = out_pix.chans['M']
16 @ Y = out_pix.chans['Y']
17 @ K = out_pix.chans['K']
18 @ max_size = max(R.size, G.size, B.size)
19 @ max_val = 2 ** max_size - 1
20 GP_Pixel _R = GP_SCALE_VAL_{{ R.size }}_{{ max_size }}(GP_GET_BITS({{ R.off }}+o1, {{ R.size }}, p1)); \
21 GP_Pixel _G = GP_SCALE_VAL_{{ G.size }}_{{ max_size }}(GP_GET_BITS({{ G.off }}+o1, {{ G.size }}, p1)); \
22 GP_Pixel _B = GP_SCALE_VAL_{{ B.size }}_{{ max_size }}(GP_GET_BITS({{ B.off }}+o1, {{ B.size }}, p1)); \
23 GP_Pixel _K = GP_MAX3(_R, _G, _B); \
24 GP_SET_BITS({{ C.off }}+o2, {{ C.size }}, p2, GP_SCALE_VAL_{{ max_size }}_{{ C.size }}((_K - _R))); \
25 GP_SET_BITS({{ M.off }}+o2, {{ M.size }}, p2, GP_SCALE_VAL_{{ max_size }}_{{ M.size }}((_K - _G))); \
26 GP_SET_BITS({{ Y.off }}+o2, {{ Y.size }}, p2, GP_SCALE_VAL_{{ max_size }}_{{ Y.size }}((_K - _B))); \
27 GP_SET_BITS({{ K.off }}+o2, {{ K.size }}, p2, GP_SCALE_VAL_{{ max_size }}_{{ K.size }}({{ max_val }} - _K)); \
30 @ def GP_Pixel_TYPE_TO_TYPE(pt1, pt2):
31 /*** {{ pt1.name }} -> {{ pt2.name }} ***
32 * macro reads p1 ({{ pt1.name }} at bit-offset o1)
33 * and writes to p2 ({{ pt2.name }} at bit-offset o2)
34 * the relevant part of p2 is assumed to be cleared (zero) */
35 #define GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}_OFFSET(p1, o1, p2, o2) do { \
37 @ if pt1.is_rgb() and pt2.is_cmyk():
38 @ rgb_to_cmyk(pt1, pt2)
40 @ for c2 in pt2.chanslist:
41 @ # case 1: just copy a channel
42 @ if c2[0] in pt1.chans.keys():
43 @ c1 = pt1.chans[c2[0]]
44 /* {{ c2[0] }}:={{ c1[0] }} */ GP_SET_BITS({{ c2.off }}+o2, {{ c2.size }}, p2,\
45 GP_SCALE_VAL_{{ c1.size }}_{{ c2.size }}(GP_GET_BITS({{ c1.off }}+o1, {{ c1.size }}, p1))); \
46 @ # case 2: set A to full opacity (not present in source)
48 /* A:={{ c2.C_max }} */GP_SET_BITS({{ c2.off }}+o2, {{ c2.size }}, p2, {{ c2.C_max }}); \
49 @ # case 3: calculate V as average of RGB
50 @ elif c2[0]=='V' and pt1.is_rgb():
51 /* V:=RGB_avg */ GP_SET_BITS({{ c2.off }}+o2, {{ c2.size }}, p2, ( \
52 @ for c1 in [pt1.chans['R'], pt1.chans['G'], pt1.chans['B']]:
53 /* {{ c1.name }} */ GP_SCALE_VAL_{{ c1.size }}_{{ c2.size }}(GP_GET_BITS({{ c1.off }}+o1, {{ c1.size }}, p1)) + \
56 @ # case 4: set each RGB to V -#}
57 @ elif c2[0] in 'RGB' and pt1.is_gray():
59 /* {{ c2[0] }}:=V */ GP_SET_BITS({{ c2.off }}+o2, {{ c2.size }}, p2,\
60 GP_SCALE_VAL_{{ c1.size }}_{{ c2.size }}(GP_GET_BITS({{ c1.off }}+o1, {{ c1.size }}, p1))); \
61 @ # case 5: CMYK to RGB
62 @ elif c2[0] in 'RGB' and pt1.is_cmyk():
71 GP_SET_BITS({{ c2.off }}+o2, {{ c2.size }}, p2,\
72 (({{ c2.C_max }} * ({{ K.C_max }} - GP_GET_BITS({{ K.off }}+o1, {{ K.size }}, p1)) * \
73 ({{ V.C_max }} - GP_GET_BITS({{ V.off }}+o1, {{ V.size }}, p1)))) / ({{ K.C_max }} * {{ V.C_max }})); \
74 @ # case 7: invalid mapping
76 {{ error('Channel conversion ' + pt1.name + ' to ' + pt2.name + ' not supported.') }}
80 /* a version without offsets */
81 #define GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}(p1, p2) \
82 GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}_OFFSET(p1, 0, p2, 0)
86 #include "GP_GetSetBits.h"
87 #include "GP_Pixmap.h"
91 @ # Loop around "central" pixel types
93 @ for pt in [pixeltypes_dict['RGB888'], pixeltypes_dict['RGBA8888']]:
94 @ for i in pixeltypes:
95 @ if not i.is_unknown() and not i.is_palette():
96 @ GP_Pixel_TYPE_TO_TYPE(pt, i)
97 @ if i.name not in ['RGB888', 'RGBA8888']:
98 @ GP_Pixel_TYPE_TO_TYPE(i, pt)
102 * Convert {{ pt.name }} to any other PixelType
103 * Does not work on palette types at all (yet)
105 GP_Pixel GP_{{ pt.name }}ToPixel(GP_Pixel pixel, GP_PixelType type);
108 * Function converting to {{ pt.name }} from any other PixelType
109 * Does not work on palette types at all (yet)
111 GP_Pixel GP_PixelTo{{ pt.name }}(GP_Pixel pixel, GP_PixelType type);
115 /* Experimental macros testing generated scripts */
116 @ GP_Pixel_TYPE_TO_TYPE(pixeltypes_dict['RGB565'], pixeltypes_dict['RGBA8888'])
117 @ GP_Pixel_TYPE_TO_TYPE(pixeltypes_dict['RGBA8888'], pixeltypes_dict['G2'])