~ubuntu-branches/ubuntu/dapper/gimp/dapper-security

1 by Daniel Holbach
Import upstream version 2.2.9
1
/* LIBGIMP - The GIMP Library
2
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Library General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with this library; if not, write to the
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 * Boston, MA 02111-1307, USA.
18
 */
19
20
#include "config.h"
21
22
#include <glib-object.h>
23
24
#include "libgimpmath/gimpmath.h"
25
26
#include "gimpcolortypes.h"
27
28
#include "gimprgb.h"
29
30
31
/*  RGB type  */
32
33
static GimpRGB  * rgb_copy  (const GimpRGB *rgb);
34
35
36
GType
37
gimp_rgb_get_type (void)
38
{
39
  static GType rgb_type = 0;
40
41
  if (!rgb_type)
42
    rgb_type = g_boxed_type_register_static ("GimpRGB",
43
                                             (GBoxedCopyFunc) rgb_copy,
44
                                             (GBoxedFreeFunc) g_free);
45
46
  return rgb_type;
47
}
48
49
static GimpRGB *
50
rgb_copy (const GimpRGB *rgb)
51
{
52
  return g_memdup (rgb, sizeof (GimpRGB));
53
}
54
55
56
/*  RGB functions  */
57
58
/**
59
 * gimp_rgb_set:
60
 * @rgb: a #GimpRGB struct
61
 * @red:
62
 * @green:
63
 * @blue:
64
 *
65
 * Sets the red, green and blue components of @rgb and leaves the
66
 * alpha component unchanged. The color values should be between 0.0
67
 * and 1.0 but there is no check to enforce this and the values are
68
 * set exactly as they are passed in.
69
 **/
70
void
71
gimp_rgb_set (GimpRGB *rgb,
72
	      gdouble  r,
73
	      gdouble  g,
74
	      gdouble  b)
75
{
76
  g_return_if_fail (rgb != NULL);
77
78
  rgb->r = r;
79
  rgb->g = g;
80
  rgb->b = b;
81
}
82
83
/**
84
 * gimp_rgb_set_alpha:
85
 * @rgb: a #GimpRGB struct
86
 * @alpha:
87
 *
88
 * Sets the alpha component of @rgb and leaves the RGB components unchanged.
89
 **/
90
void
91
gimp_rgb_set_alpha (GimpRGB *rgb,
92
		    gdouble  a)
93
{
94
  g_return_if_fail (rgb != NULL);
95
96
  rgb->a = a;
97
}
98
99
/**
100
 * gimp_rgb_set_uchar:
101
 * @rgb: a #GimpRGB struct
102
 * @red:
103
 * @green:
104
 * @blue:
105
 *
106
 * Sets the red, green and blue components of @rgb from 8bit values
107
 * (0 to 255) and leaves the alpha component unchanged.
108
 **/
109
void
110
gimp_rgb_set_uchar (GimpRGB *rgb,
111
		    guchar   r,
112
		    guchar   g,
113
		    guchar   b)
114
{
115
  g_return_if_fail (rgb != NULL);
116
117
  rgb->r = (gdouble) r / 255.0;
118
  rgb->g = (gdouble) g / 255.0;
119
  rgb->b = (gdouble) b / 255.0;
120
}
121
122
void
123
gimp_rgb_get_uchar (const GimpRGB *rgb,
124
		    guchar        *r,
125
		    guchar        *g,
126
		    guchar        *b)
127
{
128
  g_return_if_fail (rgb != NULL);
129
130
  if (r) *r = ROUND (CLAMP (rgb->r, 0.0, 1.0) * 255.0);
131
  if (g) *g = ROUND (CLAMP (rgb->g, 0.0, 1.0) * 255.0);
132
  if (b) *b = ROUND (CLAMP (rgb->b, 0.0, 1.0) * 255.0);
133
}
134
135
void
136
gimp_rgb_add (GimpRGB       *rgb1,
137
	      const GimpRGB *rgb2)
138
{
139
  g_return_if_fail (rgb1 != NULL);
140
  g_return_if_fail (rgb2 != NULL);
141
142
  rgb1->r += rgb2->r;
143
  rgb1->g += rgb2->g;
144
  rgb1->b += rgb2->b;
145
}
146
147
void
148
gimp_rgb_subtract (GimpRGB       *rgb1,
149
		   const GimpRGB *rgb2)
150
{
151
  g_return_if_fail (rgb1 != NULL);
152
  g_return_if_fail (rgb2 != NULL);
153
154
  rgb1->r -= rgb2->r;
155
  rgb1->g -= rgb2->g;
156
  rgb1->b -= rgb2->b;
157
}
158
159
void
160
gimp_rgb_multiply (GimpRGB *rgb,
161
		   gdouble  factor)
162
{
163
  g_return_if_fail (rgb != NULL);
164
165
  rgb->r *= factor;
166
  rgb->g *= factor;
167
  rgb->b *= factor;
168
}
169
170
gdouble
171
gimp_rgb_distance (const GimpRGB *rgb1,
172
		   const GimpRGB *rgb2)
173
{
174
  g_return_val_if_fail (rgb1 != NULL, 0.0);
175
  g_return_val_if_fail (rgb2 != NULL, 0.0);
176
177
  return (fabs (rgb1->r - rgb2->r) +
178
	  fabs (rgb1->g - rgb2->g) +
179
	  fabs (rgb1->b - rgb2->b));
180
}
181
182
gdouble
183
gimp_rgb_max (const GimpRGB *rgb)
184
{
185
  g_return_val_if_fail (rgb != NULL, 0.0);
186
187
  if (rgb->r > rgb->g)
188
     return (rgb->r > rgb->b) ? rgb->r : rgb->b;
189
  return (rgb->g > rgb->b) ? rgb->g : rgb->b;
190
}
191
192
gdouble
193
gimp_rgb_min (const GimpRGB *rgb)
194
{
195
  g_return_val_if_fail (rgb != NULL, 0.0);
196
197
  if (rgb->r < rgb->g)
198
     return (rgb->r < rgb->b) ? rgb->r : rgb->b;
199
  return (rgb->g < rgb->b) ? rgb->g : rgb->b;
200
}
201
202
void
203
gimp_rgb_clamp (GimpRGB *rgb)
204
{
205
  g_return_if_fail (rgb != NULL);
206
207
  rgb->r = CLAMP (rgb->r, 0.0, 1.0);
208
  rgb->g = CLAMP (rgb->g, 0.0, 1.0);
209
  rgb->b = CLAMP (rgb->b, 0.0, 1.0);
210
  rgb->a = CLAMP (rgb->a, 0.0, 1.0);
211
}
212
213
void
214
gimp_rgb_gamma (GimpRGB *rgb,
215
		gdouble  gamma)
216
{
217
  gdouble ig;
218
219
  g_return_if_fail (rgb != NULL);
220
221
  if (gamma != 0.0)
222
    ig = 1.0 / gamma;
223
  else
224
    ig = 0.0;
225
226
  rgb->r = pow (rgb->r, ig);
227
  rgb->g = pow (rgb->g, ig);
228
  rgb->b = pow (rgb->b, ig);
229
}
230
231
gdouble
232
gimp_rgb_intensity (const GimpRGB *rgb)
233
{
234
  gdouble intensity;
235
236
  g_return_val_if_fail (rgb != NULL, 0.0);
237
238
  intensity = GIMP_RGB_INTENSITY (rgb->r, rgb->g, rgb->b);
239
240
  return CLAMP (intensity, 0.0, 1.0);
241
}
242
243
guchar
244
gimp_rgb_intensity_uchar (const GimpRGB *rgb)
245
{
246
  g_return_val_if_fail (rgb != NULL, 0);
247
248
  return ROUND (gimp_rgb_intensity (rgb) * 255.0);
249
}
250
251
void
252
gimp_rgb_composite (GimpRGB              *color1,
253
		    const GimpRGB        *color2,
254
		    GimpRGBCompositeMode  mode)
255
{
256
  gdouble factor;
257
258
  g_return_if_fail (color1 != NULL);
259
  g_return_if_fail (color2 != NULL);
260
261
  switch (mode)
262
    {
263
    case GIMP_RGB_COMPOSITE_NONE:
264
      break;
265
266
    case GIMP_RGB_COMPOSITE_NORMAL:
267
      /*  put color2 on top of color1  */
268
      if (color2->a == 1.0)
269
	{
270
	  *color1 = *color2;
271
	}
272
      else
273
	{
274
	  factor = color1->a * (1.0 - color2->a);
275
	  color1->r = color1->r * factor + color2->r * color2->a;
276
	  color1->g = color1->g * factor + color2->g * color2->a;
277
	  color1->b = color1->b * factor + color2->b * color2->a;
278
	  color1->a = factor + color2->a;
279
	}
280
      break;
281
282
    case GIMP_RGB_COMPOSITE_BEHIND:
283
      /*  put color2 below color1  */
284
      if (color1->a < 1.0)
285
	{
286
	  factor = color2->a * (1.0 - color1->a);
287
	  color1->r = color2->r * factor + color1->r * color1->a;
288
	  color1->g = color2->g * factor + color1->g * color1->a;
289
	  color1->b = color2->b * factor + color1->b * color1->a;
290
	  color1->a = factor + color1->a;
291
	}
292
      break;
293
    }
294
}
295
296
/*  RGBA functions  */
297
298
/**
299
 * gimp_rgba_set:
300
 * @rgba: a #GimpRGB struct
301
 * @red:
302
 * @green:
303
 * @blue:
304
 * @alpha:
305
 *
306
 * Sets the red, green, blue and alpha components of @rgb. The values
307
 * should be between 0.0 and 1.0 but there is no check to enforce this
308
 * and the values are set exactly as they are passed in.
309
 **/
310
void
311
gimp_rgba_set (GimpRGB *rgba,
312
	       gdouble  r,
313
	       gdouble  g,
314
	       gdouble  b,
315
	       gdouble  a)
316
{
317
  g_return_if_fail (rgba != NULL);
318
319
  rgba->r = r;
320
  rgba->g = g;
321
  rgba->b = b;
322
  rgba->a = a;
323
}
324
325
/**
326
 * gimp_rgba_set_uchar:
327
 * @rgba: a #GimpRGB struct
328
 * @red:
329
 * @green:
330
 * @blue:
331
 * @alpha:
332
 *
333
 * Sets the red, green, blue and alpha components of @rgb from 8bit
334
 * values (0 to 255).
335
 **/
336
void
337
gimp_rgba_set_uchar (GimpRGB *rgba,
338
		     guchar   r,
339
		     guchar   g,
340
		     guchar   b,
341
		     guchar   a)
342
{
343
  g_return_if_fail (rgba != NULL);
344
345
  rgba->r = (gdouble) r / 255.0;
346
  rgba->g = (gdouble) g / 255.0;
347
  rgba->b = (gdouble) b / 255.0;
348
  rgba->a = (gdouble) a / 255.0;
349
}
350
351
void
352
gimp_rgba_get_uchar (const GimpRGB *rgba,
353
		     guchar        *r,
354
		     guchar        *g,
355
		     guchar        *b,
356
		     guchar        *a)
357
{
358
  g_return_if_fail (rgba != NULL);
359
360
  if (r) *r = ROUND (CLAMP (rgba->r, 0.0, 1.0) * 255.0);
361
  if (g) *g = ROUND (CLAMP (rgba->g, 0.0, 1.0) * 255.0);
362
  if (b) *b = ROUND (CLAMP (rgba->b, 0.0, 1.0) * 255.0);
363
  if (a) *a = ROUND (CLAMP (rgba->a, 0.0, 1.0) * 255.0);
364
}
365
366
void
367
gimp_rgba_add (GimpRGB       *rgba1,
368
	       const GimpRGB *rgba2)
369
{
370
  g_return_if_fail (rgba1 != NULL);
371
  g_return_if_fail (rgba2 != NULL);
372
373
  rgba1->r += rgba2->r;
374
  rgba1->g += rgba2->g;
375
  rgba1->b += rgba2->b;
376
  rgba1->a += rgba2->a;
377
}
378
379
void
380
gimp_rgba_subtract (GimpRGB       *rgba1,
381
		    const GimpRGB *rgba2)
382
{
383
  g_return_if_fail (rgba1 != NULL);
384
  g_return_if_fail (rgba2 != NULL);
385
386
  rgba1->r -= rgba2->r;
387
  rgba1->g -= rgba2->g;
388
  rgba1->b -= rgba2->b;
389
  rgba1->a -= rgba2->a;
390
}
391
392
void
393
gimp_rgba_multiply (GimpRGB *rgba,
394
		    gdouble  factor)
395
{
396
  g_return_if_fail (rgba != NULL);
397
398
  rgba->r *= factor;
399
  rgba->g *= factor;
400
  rgba->b *= factor;
401
  rgba->a *= factor;
402
}
403
404
gdouble
405
gimp_rgba_distance (const GimpRGB *rgba1,
406
		    const GimpRGB *rgba2)
407
{
408
  g_return_val_if_fail (rgba1 != NULL, 0.0);
409
  g_return_val_if_fail (rgba2 != NULL, 0.0);
410
411
  return (fabs (rgba1->r - rgba2->r) +
412
          fabs (rgba1->g - rgba2->g) +
413
          fabs (rgba1->b - rgba2->b) +
414
          fabs (rgba1->a - rgba2->a));
415
}