1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/*
10 * M.L. Kersten
11 * Color multiplexes
12 * [TODO: property propagations and general testing]
13 * The collection of routines provided here are map operations
14 * for the color string primitives.
15 *
16 * In line with the batcalc module, we assume that if two bat operands
17 * are provided that they are aligned.
18 */
19
20#include "monetdb_config.h"
21#include "batcolor.h"
22
23#define BATwalk(NAME,FUNC,TYPE1,ISNIL,TYPE2,TPE,APP) \
24str CLRbat##NAME(bat *ret, const bat *l) \
25{ \
26 BATiter bi; \
27 BAT *bn, *b; \
28 BUN p,q; \
29 const TYPE1 *x; \
30 TYPE2 y; \
31 char *msg = MAL_SUCCEED; \
32 \
33 if( (b= BATdescriptor(*l)) == NULL ) \
34 throw(MAL, "batcolor." #NAME, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); \
35 bn= COLnew(b->hseqbase,TPE,BATcount(b), TRANSIENT); \
36 if( bn == NULL){ \
37 BBPunfix(b->batCacheid); \
38 throw(MAL, "batcolor." #NAME, SQLSTATE(HY001) MAL_MALLOC_FAIL); \
39 } \
40 bn->tsorted=false; \
41 bn->trevsorted=false; \
42 bn->tnil = false; \
43 bn->tnonil = true; \
44 \
45 bi = bat_iterator(b); \
46 \
47 BATloop(b, p, q) { \
48 x= (const TYPE1 *) BUNtail(bi,p); \
49 if (x== 0 || ISNIL(*x)) { \
50 y = (TYPE2) TYPE2##_nil; \
51 bn->tnonil = false; \
52 bn->tnil = true; \
53 } else if ((msg = FUNC(&y,x)) != MAL_SUCCEED) \
54 goto bunins_failed; \
55 APP; \
56 } \
57 bn->theap.dirty |= BATcount(bn) > 0; \
58 *ret = bn->batCacheid; \
59 BBPkeepref(*ret); \
60 BBPunfix(b->batCacheid); \
61 return MAL_SUCCEED; \
62bunins_failed: \
63 BBPunfix(b->batCacheid); \
64 BBPunfix(bn->batCacheid); \
65 if (msg) \
66 return msg; \
67 throw(MAL, "batcolor." #NAME, OPERATION_FAILED " During bulk operation"); \
68}
69
70BATwalk(Color,CLRcolor,char *,GDK_STRNIL,color,getAtomIndex("color",5,TYPE_int),bunfastappTYPE(color, bn, &y))
71BATwalk(Str,CLRstr,color,is_color_nil,str,TYPE_str,bunfastappVAR(bn, &y))
72
73BATwalk(Red,CLRred,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
74BATwalk(Green,CLRgreen,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
75BATwalk(Blue,CLRblue,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
76
77BATwalk(Hue,CLRhue,color,is_color_nil,flt,TYPE_flt,bunfastappTYPE(flt, bn, &y))
78BATwalk(Saturation,CLRsaturation,color,is_color_nil,flt,TYPE_flt,bunfastappTYPE(flt, bn, &y))
79BATwalk(Value,CLRvalue,color,is_color_nil,flt,TYPE_flt,bunfastappTYPE(flt, bn, &y))
80
81BATwalk(HueInt,CLRhueInt,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
82BATwalk(SaturationInt,CLRsaturationInt,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
83BATwalk(ValueInt,CLRvalueInt,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
84
85BATwalk(Luminance,CLRluminance,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
86BATwalk(Cr,CLRcr,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
87BATwalk(Cb,CLRcb,color,is_color_nil,int,TYPE_int,bunfastappTYPE(int, bn, &y))
88
89#define BATwalk3(NAME,FUNC,TYPE) \
90str CLRbat##NAME(bat *ret, const bat *l, const bat *bid2, const bat *bid3) \
91{ \
92 BATiter bi, b2i, b3i; \
93 BAT *bn, *b2,*b3, *b; \
94 BUN p,q; \
95 const TYPE *x, *x2, *x3; \
96 color y; \
97 char *msg = MAL_SUCCEED; \
98 \
99 b= BATdescriptor(*l); \
100 b2= BATdescriptor(*bid2); \
101 b3= BATdescriptor(*bid3); \
102 if (b == NULL || b2 == NULL || b3 == NULL) { \
103 if (b) \
104 BBPunfix(b->batCacheid); \
105 if (b2) \
106 BBPunfix(b2->batCacheid); \
107 if (b3) \
108 BBPunfix(b3->batCacheid); \
109 throw(MAL, "batcolor." #NAME, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); \
110 } \
111 bn= COLnew(b->hseqbase,getAtomIndex("color",5,TYPE_int),BATcount(b), TRANSIENT); \
112 if( bn == NULL){ \
113 BBPunfix(b->batCacheid); \
114 BBPunfix(b2->batCacheid); \
115 BBPunfix(b3->batCacheid); \
116 throw(MAL, "batcolor." #NAME, SQLSTATE(HY001) MAL_MALLOC_FAIL); \
117 } \
118 bn->tsorted=false; \
119 bn->trevsorted=false; \
120 bn->tnil = false; \
121 bn->tnonil = true; \
122 \
123 bi = bat_iterator(b); \
124 b2i = bat_iterator(b2); \
125 b3i = bat_iterator(b3); \
126 \
127 BATloop(b, p, q) { \
128 x= (const TYPE *) BUNtail(bi,p); \
129 x2= (const TYPE *) BUNtail(b2i,p); \
130 x3= (const TYPE *) BUNtail(b3i,p); \
131 if (x== 0 || is_##TYPE##_nil(*x) || \
132 x2== 0 || is_##TYPE##_nil(*x2) || \
133 x3== 0 || is_##TYPE##_nil(*x3)) { \
134 y = color_nil; \
135 bn->tnonil = false; \
136 bn->tnil = true; \
137 } else if ((msg = FUNC(&y,x,x2,x3)) != MAL_SUCCEED) \
138 goto bunins_failed; \
139 bunfastappTYPE(color, bn, &y); \
140 } \
141 bn->theap.dirty |= BATcount(bn) > 0; \
142 *ret = bn->batCacheid; \
143 BBPkeepref(*ret); \
144 BBPunfix(b->batCacheid); \
145 BBPunfix(b2->batCacheid); \
146 BBPunfix(b3->batCacheid); \
147 return MAL_SUCCEED; \
148bunins_failed: \
149 BBPunfix(b->batCacheid); \
150 BBPunfix(b2->batCacheid); \
151 BBPunfix(b3->batCacheid); \
152 BBPunfix(bn->batCacheid); \
153 if (msg) \
154 return msg; \
155 throw(MAL, "batcolor." #NAME, OPERATION_FAILED " During bulk operation"); \
156}
157
158BATwalk3(Hsv,CLRhsv,flt)
159BATwalk3(Rgb,CLRrgb,int)
160BATwalk3(ycc,CLRycc,int)
161