source: synfigstudio/trunk/fuentes/src/brushlib/helpers.hpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 6.3 KB
Line 
1/* brushlib - The MyPaint Brush Library
2 * Copyright (C) 2007-2008 Martin Renold <martinxyz@gmx.ch>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef __helpers_h__
18#define __helpers_h__
19
20#include <glib.h>
21#include <assert.h>
22
23// MAX, MIN, ABS, CLAMP are already available from gmacros.h
24#define ROUND(x) ((int) ((x) + 0.5))
25#define SIGN(x) ((x)>0?1:(-1))
26#define SQR(x) ((x)*(x))
27
28#define MAX3(a, b, c) ((a)>(b)?MAX((a),(c)):MAX((b),(c)))
29#define MIN3(a, b, c) ((a)<(b)?MIN((a),(c)):MIN((b),(c)))
30
31namespace brushlib {
32
33typedef struct { int x, y, w, h; } Rect;
34// originally from my mass project (mass.sourceforge.net)
35void ExpandRectToIncludePoint(Rect * r, int x, int y) 
36{
37  if (r->w == 0) {
38    r->w = 1; r->h = 1;
39    r->x = x; r->y = y;
40  } else {
41    if (x < r->x) { r->w += r->x-x; r->x = x; } else
42    if (x >= r->x+r->w) { r->w = x - r->x + 1; }
43
44    if (y < r->y) { r->h += r->y-y; r->y = y; } else
45    if (y >= r->y+r->h) { r->h = y - r->y + 1; }
46  }
47}
48
49// Optimized version from one in GIMP (noisify.c), where it was
50// adapted from ppmforge.c, which is part of PBMPLUS. The algorithm
51// comes from: 'The Science Of Fractal Images'. Peitgen, H.-O., and
52// Saupe, D. eds.  Springer Verlag, New York, 1988.
53float rand_gauss (GRand * rng)
54{
55  float sum = 0.0;
56  uint32_t rand1 = g_rand_int(rng);
57  uint32_t rand2 = g_rand_int(rng);
58  sum +=  rand1        & 0x7FFF;
59  sum += (rand1 >> 16) & 0x7FFF;
60  sum +=  rand2        & 0x7FFF;
61  sum += (rand2 >> 16) & 0x7FFF;
62  return sum * 5.28596089837e-5 - 3.46410161514;
63}
64
65// stolen from GIMP (gimpcolorspace.c)
66// (from gimp_rgb_to_hsv)
67void
68rgb_to_hsv_float (float *r_ /*h*/, float *g_ /*s*/, float *b_ /*v*/)
69{
70  float max, min, delta;
71  float h, s, v;
72  float r, g, b;
73
74  h = 0.0; // silence gcc warning
75
76  r = *r_;
77  g = *g_;
78  b = *b_;
79
80  r = CLAMP(r, 0.0, 1.0);
81  g = CLAMP(g, 0.0, 1.0);
82  b = CLAMP(b, 0.0, 1.0);
83
84  max = MAX3(r, g, b);
85  min = MIN3(r, g, b);
86
87  v = max;
88  delta = max - min;
89
90  if (delta > 0.0001)
91    {
92      s = delta / max;
93
94      if (r == max)
95        {
96          h = (g - b) / delta;
97          if (h < 0.0)
98            h += 6.0;
99        }
100      else if (g == max)
101        {
102          h = 2.0 + (b - r) / delta;
103        }
104      else if (b == max)
105        {
106          h = 4.0 + (r - g) / delta;
107        }
108
109      h /= 6.0;
110    }
111  else
112    {
113      s = 0.0;
114      h = 0.0;
115    }
116
117  *r_ = h;
118  *g_ = s;
119  *b_ = v;
120}
121
122// (from gimp_hsv_to_rgb)
123void
124hsv_to_rgb_float (float *h_, float *s_, float *v_)
125{
126  gint    i;
127  gdouble f, w, q, t;
128  float h, s, v;
129  float r, g, b;
130  r = g = b = 0.0; // silence gcc warning
131
132  h = *h_;
133  s = *s_;
134  v = *v_;
135
136  h = h - floor(h);
137  s = CLAMP(s, 0.0, 1.0);
138  v = CLAMP(v, 0.0, 1.0);
139
140  gdouble hue;
141
142  if (s == 0.0)
143    {
144      r = v;
145      g = v;
146      b = v;
147    }
148  else
149    {
150      hue = h;
151
152      if (hue == 1.0)
153        hue = 0.0;
154
155      hue *= 6.0;
156
157      i = (gint) hue;
158      f = hue - i;
159      w = v * (1.0 - s);
160      q = v * (1.0 - (s * f));
161      t = v * (1.0 - (s * (1.0 - f)));
162
163      switch (i)
164        {
165        case 0:
166          r = v;
167          g = t;
168          b = w;
169          break;
170        case 1:
171          r = q;
172          g = v;
173          b = w;
174          break;
175        case 2:
176          r = w;
177          g = v;
178          b = t;
179          break;
180        case 3:
181          r = w;
182          g = q;
183          b = v;
184          break;
185        case 4:
186          r = t;
187          g = w;
188          b = v;
189          break;
190        case 5:
191          r = v;
192          g = w;
193          b = q;
194          break;
195        }
196    }
197
198  *h_ = r;
199  *s_ = g;
200  *v_ = b;
201}
202
203// (from gimp_rgb_to_hsl)
204void
205rgb_to_hsl_float (float *r_, float *g_, float *b_)
206{
207  gdouble max, min, delta;
208
209  float h, s, l;
210  float r, g, b;
211
212  // silence gcc warnings
213  h=0;
214
215  r = *r_;
216  g = *g_;
217  b = *b_;
218
219  r = CLAMP(r, 0.0, 1.0);
220  g = CLAMP(g, 0.0, 1.0);
221  b = CLAMP(b, 0.0, 1.0);
222
223  max = MAX3(r, g, b);
224  min = MIN3(r, g, b);
225
226  l = (max + min) / 2.0;
227
228  if (max == min)
229    {
230      s = 0.0;
231      h = 0.0; //GIMP_HSL_UNDEFINED;
232    }
233  else
234    {
235      if (l <= 0.5)
236        s = (max - min) / (max + min);
237      else
238        s = (max - min) / (2.0 - max - min);
239
240      delta = max - min;
241
242      if (delta == 0.0)
243        delta = 1.0;
244
245      if (r == max)
246        {
247          h = (g - b) / delta;
248        }
249      else if (g == max)
250        {
251          h = 2.0 + (b - r) / delta;
252        }
253      else if (b == max)
254        {
255          h = 4.0 + (r - g) / delta;
256        }
257
258      h /= 6.0;
259
260      if (h < 0.0)
261        h += 1.0;
262    }
263
264  *r_ = h;
265  *g_ = s;
266  *b_ = l;
267}
268
269static double
270hsl_value (gdouble n1,
271           gdouble n2,
272           gdouble hue)
273{
274  gdouble val;
275
276  if (hue > 6.0)
277    hue -= 6.0;
278  else if (hue < 0.0)
279    hue += 6.0;
280
281  if (hue < 1.0)
282    val = n1 + (n2 - n1) * hue;
283  else if (hue < 3.0)
284    val = n2;
285  else if (hue < 4.0)
286    val = n1 + (n2 - n1) * (4.0 - hue);
287  else
288    val = n1;
289
290  return val;
291}
292
293
294/**
295 * gimp_hsl_to_rgb:
296 * @hsl: A color value in the HSL colorspace
297 * @rgb: The value converted to a value in the RGB colorspace
298 *
299 * Convert a HSL color value to an RGB color value.
300 **/
301void
302hsl_to_rgb_float (float *h_, float *s_, float *l_)
303{
304  float h, s, l;
305  float r, g, b;
306
307  h = *h_;
308  s = *s_;
309  l = *l_;
310
311  h = h - floor(h);
312  s = CLAMP(s, 0.0, 1.0);
313  l = CLAMP(l, 0.0, 1.0);
314
315  if (s == 0)
316    {
317      /*  achromatic case  */
318      r = l;
319      g = l;
320      b = l;
321    }
322  else
323    {
324      gdouble m1, m2;
325
326      if (l <= 0.5)
327        m2 = l * (1.0 + s);
328      else
329        m2 = l + s - l * s;
330
331      m1 = 2.0 * l - m2;
332
333      r = hsl_value (m1, m2, h * 6.0 + 2.0);
334      g = hsl_value (m1, m2, h * 6.0);
335      b = hsl_value (m1, m2, h * 6.0 - 2.0);
336    }
337
338  *h_ = r;
339  *s_ = g;
340  *l_ = b;
341}
342
343}
344#endif
Note: See TracBrowser for help on using the repository browser.