vfs: check userland buffers before reading them.
[haiku.git] / headers / libs / agg / agg_color_gray.h
blob5fa44ce227eaf5441037d04f830d0f6c174cd39c
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
24 // color types gray8, gray16
26 //----------------------------------------------------------------------------
28 #ifndef AGG_COLOR_GRAY_INCLUDED
29 #define AGG_COLOR_GRAY_INCLUDED
31 #include "agg_basics.h"
32 #include "agg_color_rgba.h"
34 namespace agg
37 //===================================================================gray8
38 struct gray8
40 typedef int8u value_type;
41 typedef int32u calc_type;
42 typedef int32 long_type;
43 enum base_scale_e
45 base_shift = 8,
46 base_scale = 1 << base_shift,
47 base_mask = base_scale - 1
49 typedef gray8 self_type;
51 value_type v;
52 value_type a;
54 //--------------------------------------------------------------------
55 gray8() {}
57 //--------------------------------------------------------------------
58 explicit gray8(unsigned v_, unsigned a_=base_mask) :
59 v(int8u(v_)), a(int8u(a_)) {}
61 //--------------------------------------------------------------------
62 gray8(const self_type& c, unsigned a_) :
63 v(c.v), a(value_type(a_)) {}
65 //--------------------------------------------------------------------
66 gray8(const rgba& c) :
67 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
68 a((value_type)uround(c.a * double(base_mask))) {}
70 //--------------------------------------------------------------------
71 gray8(const rgba& c, double a_) :
72 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
73 a((value_type)uround(a_ * double(base_mask))) {}
75 //--------------------------------------------------------------------
76 gray8(const rgba8& c) :
77 v((c.r*77 + c.g*150 + c.b*29) >> 8),
78 a(c.a) {}
80 //--------------------------------------------------------------------
81 gray8(const rgba8& c, unsigned a_) :
82 v((c.r*77 + c.g*150 + c.b*29) >> 8),
83 a(a_) {}
85 //--------------------------------------------------------------------
86 void clear()
88 v = a = 0;
91 //--------------------------------------------------------------------
92 const self_type& transparent()
94 a = 0;
95 return *this;
98 //--------------------------------------------------------------------
99 void opacity(double a_)
101 if(a_ < 0.0) a_ = 0.0;
102 if(a_ > 1.0) a_ = 1.0;
103 a = (value_type)uround(a_ * double(base_mask));
106 //--------------------------------------------------------------------
107 double opacity() const
109 return double(a) / double(base_mask);
113 //--------------------------------------------------------------------
114 const self_type& premultiply()
116 if(a == base_mask) return *this;
117 if(a == 0)
119 v = 0;
120 return *this;
122 v = value_type((calc_type(v) * a) >> base_shift);
123 return *this;
126 //--------------------------------------------------------------------
127 const self_type& premultiply(unsigned a_)
129 if(a == base_mask && a_ >= base_mask) return *this;
130 if(a == 0 || a_ == 0)
132 v = a = 0;
133 return *this;
135 calc_type v_ = (calc_type(v) * a_) / a;
136 v = value_type((v_ > a_) ? a_ : v_);
137 a = value_type(a_);
138 return *this;
141 //--------------------------------------------------------------------
142 const self_type& demultiply()
144 if(a == base_mask) return *this;
145 if(a == 0)
147 v = 0;
148 return *this;
150 calc_type v_ = (calc_type(v) * base_mask) / a;
151 v = value_type((v_ > base_mask) ? base_mask : v_);
152 return *this;
155 //--------------------------------------------------------------------
156 self_type gradient(self_type c, double k) const
158 self_type ret;
159 calc_type ik = uround(k * base_scale);
160 ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
161 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
162 return ret;
165 //--------------------------------------------------------------------
166 AGG_INLINE void add(const self_type& c, unsigned cover)
168 calc_type cv, ca;
169 if(cover == cover_mask)
171 if(c.a == base_mask)
173 *this = c;
175 else
177 cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
178 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
181 else
183 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
184 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
185 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
186 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
190 //--------------------------------------------------------------------
191 static self_type no_color() { return self_type(0,0); }
195 //-------------------------------------------------------------gray8_pre
196 inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask)
198 return gray8(v,a).premultiply();
200 inline gray8 gray8_pre(const gray8& c, unsigned a)
202 return gray8(c,a).premultiply();
204 inline gray8 gray8_pre(const rgba& c)
206 return gray8(c).premultiply();
208 inline gray8 gray8_pre(const rgba& c, double a)
210 return gray8(c,a).premultiply();
212 inline gray8 gray8_pre(const rgba8& c)
214 return gray8(c).premultiply();
216 inline gray8 gray8_pre(const rgba8& c, unsigned a)
218 return gray8(c,a).premultiply();
224 //==================================================================gray16
225 struct gray16
227 typedef int16u value_type;
228 typedef int32u calc_type;
229 typedef int64 long_type;
230 enum base_scale_e
232 base_shift = 16,
233 base_scale = 1 << base_shift,
234 base_mask = base_scale - 1
236 typedef gray16 self_type;
238 value_type v;
239 value_type a;
241 //--------------------------------------------------------------------
242 gray16() {}
244 //--------------------------------------------------------------------
245 explicit gray16(unsigned v_, unsigned a_=base_mask) :
246 v(int16u(v_)), a(int16u(a_)) {}
248 //--------------------------------------------------------------------
249 gray16(const self_type& c, unsigned a_) :
250 v(c.v), a(value_type(a_)) {}
252 //--------------------------------------------------------------------
253 gray16(const rgba& c) :
254 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
255 a((value_type)uround(c.a * double(base_mask))) {}
257 //--------------------------------------------------------------------
258 gray16(const rgba& c, double a_) :
259 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
260 a((value_type)uround(a_ * double(base_mask))) {}
262 //--------------------------------------------------------------------
263 gray16(const rgba8& c) :
264 v(c.r*77 + c.g*150 + c.b*29),
265 a((value_type(c.a) << 8) | c.a) {}
267 //--------------------------------------------------------------------
268 gray16(const rgba8& c, unsigned a_) :
269 v(c.r*77 + c.g*150 + c.b*29),
270 a((value_type(a_) << 8) | c.a) {}
272 //--------------------------------------------------------------------
273 void clear()
275 v = a = 0;
278 //--------------------------------------------------------------------
279 const self_type& transparent()
281 a = 0;
282 return *this;
285 //--------------------------------------------------------------------
286 void opacity(double a_)
288 if(a_ < 0.0) a_ = 0.0;
289 if(a_ > 1.0) a_ = 1.0;
290 a = (value_type)uround(a_ * double(base_mask));
293 //--------------------------------------------------------------------
294 double opacity() const
296 return double(a) / double(base_mask);
300 //--------------------------------------------------------------------
301 const self_type& premultiply()
303 if(a == base_mask) return *this;
304 if(a == 0)
306 v = 0;
307 return *this;
309 v = value_type((calc_type(v) * a) >> base_shift);
310 return *this;
313 //--------------------------------------------------------------------
314 const self_type& premultiply(unsigned a_)
316 if(a == base_mask && a_ >= base_mask) return *this;
317 if(a == 0 || a_ == 0)
319 v = a = 0;
320 return *this;
322 calc_type v_ = (calc_type(v) * a_) / a;
323 v = value_type((v_ > a_) ? a_ : v_);
324 a = value_type(a_);
325 return *this;
328 //--------------------------------------------------------------------
329 const self_type& demultiply()
331 if(a == base_mask) return *this;
332 if(a == 0)
334 v = 0;
335 return *this;
337 calc_type v_ = (calc_type(v) * base_mask) / a;
338 v = value_type((v_ > base_mask) ? base_mask : v_);
339 return *this;
342 //--------------------------------------------------------------------
343 self_type gradient(self_type c, double k) const
345 self_type ret;
346 calc_type ik = uround(k * base_scale);
347 ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
348 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
349 return ret;
352 //--------------------------------------------------------------------
353 AGG_INLINE void add(const self_type& c, unsigned cover)
355 calc_type cv, ca;
356 if(cover == cover_mask)
358 if(c.a == base_mask)
360 *this = c;
362 else
364 cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
365 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
368 else
370 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
371 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
372 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
373 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
377 //--------------------------------------------------------------------
378 static self_type no_color() { return self_type(0,0); }
382 //------------------------------------------------------------gray16_pre
383 inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask)
385 return gray16(v,a).premultiply();
387 inline gray16 gray16_pre(const gray16& c, unsigned a)
389 return gray16(c,a).premultiply();
391 inline gray16 gray16_pre(const rgba& c)
393 return gray16(c).premultiply();
395 inline gray16 gray16_pre(const rgba& c, double a)
397 return gray16(c,a).premultiply();
399 inline gray16 gray16_pre(const rgba8& c)
401 return gray16(c).premultiply();
403 inline gray16 gray16_pre(const rgba8& c, unsigned a)
405 return gray16(c,a).premultiply();
414 #endif