~ubuntu-branches/ubuntu/maverick/gimp/maverick-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
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
22
#include <glib-object.h>
1 by Daniel Holbach
Import upstream version 2.2.9
23
24
#include "libgimpmath/gimpmath.h"
25
26
#include "gimpcolortypes.h"
27
28
#include "gimpbilinear.h"
29
30
31
gdouble
32
gimp_bilinear (gdouble  x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
33
               gdouble  y,
34
               gdouble *values)
1 by Daniel Holbach
Import upstream version 2.2.9
35
{
36
  gdouble m0, m1;
37
38
  g_return_val_if_fail (values != NULL, 0.0);
39
40
  x = fmod (x, 1.0);
41
  y = fmod (y, 1.0);
42
43
  if (x < 0.0)
44
    x += 1.0;
45
  if (y < 0.0)
46
    y += 1.0;
47
48
  m0 = (1.0 - x) * values[0] + x * values[1];
49
  m1 = (1.0 - x) * values[2] + x * values[3];
50
51
  return (1.0 - y) * m0 + y * m1;
52
}
53
54
guchar
55
gimp_bilinear_8 (gdouble x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
56
                 gdouble y,
57
                 guchar *values)
1 by Daniel Holbach
Import upstream version 2.2.9
58
{
59
  gdouble m0, m1;
60
61
  g_return_val_if_fail (values != NULL, 0);
62
63
  x = fmod (x, 1.0);
64
  y = fmod (y, 1.0);
65
66
  if (x < 0.0)
67
    x += 1.0;
68
  if (y < 0.0)
69
    y += 1.0;
70
71
  m0 = (1.0 - x) * values[0] + x * values[1];
72
  m1 = (1.0 - x) * values[2] + x * values[3];
73
74
  return (guchar) ((1.0 - y) * m0 + y * m1);
75
}
76
77
guint16
78
gimp_bilinear_16 (gdouble  x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
79
                  gdouble  y,
80
                  guint16 *values)
1 by Daniel Holbach
Import upstream version 2.2.9
81
{
82
  gdouble m0, m1;
83
84
  g_return_val_if_fail (values != NULL, 0);
85
86
  x = fmod (x, 1.0);
87
  y = fmod (y, 1.0);
88
89
  if (x < 0.0)
90
    x += 1.0;
91
  if (y < 0.0)
92
    y += 1.0;
93
94
  m0 = (1.0 - x) * values[0] + x * values[1];
95
  m1 = (1.0 - x) * values[2] + x * values[3];
96
97
  return (guint16) ((1.0 - y) * m0 + y * m1);
98
}
99
100
guint32
101
gimp_bilinear_32 (gdouble  x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
102
                  gdouble  y,
103
                  guint32 *values)
1 by Daniel Holbach
Import upstream version 2.2.9
104
{
105
  gdouble m0, m1;
106
107
  g_return_val_if_fail (values != NULL, 0);
108
109
  x = fmod (x, 1.0);
110
  y = fmod (y, 1.0);
111
112
  if (x < 0.0)
113
    x += 1.0;
114
  if (y < 0.0)
115
    y += 1.0;
116
117
  m0 = (1.0 - x) * values[0] + x * values[1];
118
  m1 = (1.0 - x) * values[2] + x * values[3];
119
120
  return (guint32) ((1.0 - y) * m0 + y * m1);
121
}
122
123
GimpRGB
124
gimp_bilinear_rgb (gdouble  x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
125
                   gdouble  y,
126
                   GimpRGB *values)
1 by Daniel Holbach
Import upstream version 2.2.9
127
{
128
  gdouble m0, m1;
129
  gdouble ix, iy;
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
130
  GimpRGB v = { 0, };
1 by Daniel Holbach
Import upstream version 2.2.9
131
132
  g_return_val_if_fail (values != NULL, v);
133
134
  x = fmod(x, 1.0);
135
  y = fmod(y, 1.0);
136
137
  if (x < 0)
138
    x += 1.0;
139
  if (y < 0)
140
    y += 1.0;
141
142
  ix = 1.0 - x;
143
  iy = 1.0 - y;
144
145
  /* Red */
146
147
  m0 = ix * values[0].r + x * values[1].r;
148
  m1 = ix * values[2].r + x * values[3].r;
149
150
  v.r = iy * m0 + y * m1;
151
152
  /* Green */
153
154
  m0 = ix * values[0].g + x * values[1].g;
155
  m1 = ix * values[2].g + x * values[3].g;
156
157
  v.g = iy * m0 + y * m1;
158
159
  /* Blue */
160
161
  m0 = ix * values[0].b + x * values[1].b;
162
  m1 = ix * values[2].b + x * values[3].b;
163
164
  v.b = iy * m0 + y * m1;
165
166
  return v;
167
}
168
169
GimpRGB
170
gimp_bilinear_rgba (gdouble  x,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
171
                    gdouble  y,
172
                    GimpRGB *values)
1 by Daniel Holbach
Import upstream version 2.2.9
173
{
174
  gdouble m0, m1;
175
  gdouble ix, iy;
176
  gdouble a0, a1, a2, a3, alpha;
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
177
  GimpRGB v = { 0, };
1 by Daniel Holbach
Import upstream version 2.2.9
178
179
  g_return_val_if_fail (values != NULL, v);
180
181
  x = fmod (x, 1.0);
182
  y = fmod (y, 1.0);
183
184
  if (x < 0)
185
    x += 1.0;
186
  if (y < 0)
187
    y += 1.0;
188
189
  ix = 1.0 - x;
190
  iy = 1.0 - y;
191
192
  a0 = values[0].a;
193
  a1 = values[1].a;
194
  a2 = values[2].a;
195
  a3 = values[3].a;
196
197
  /* Alpha */
198
199
  m0 = ix * a0 + x * a1;
200
  m1 = ix * a2 + x * a3;
201
202
  alpha = v.a = iy * m0 + y * m1;
203
204
  if (alpha > 0)
205
    {
206
      /* Red */
207
208
      m0 = ix * a0 * values[0].r + x * a1 * values[1].r;
209
      m1 = ix * a2 * values[2].r + x * a3 * values[3].r;
210
211
      v.r = (iy * m0 + y * m1)/alpha;
212
213
      /* Green */
214
215
      m0 = ix * a0 * values[0].g + x * a1 * values[1].g;
216
      m1 = ix * a2 * values[2].g + x * a3 * values[3].g;
217
218
      v.g = (iy * m0 + y * m1)/alpha;
219
220
      /* Blue */
221
222
      m0 = ix * a0 * values[0].b + x * a1 * values[1].b;
223
      m1 = ix * a2 * values[2].b + x * a3 * values[3].b;
224
225
      v.b = (iy * m0 + y * m1)/alpha;
226
    }
227
228
  return v;
229
}
230
231
/**
232
 * gimp_bilinear_pixels_8:
233
 * @dest: Pixel, where interpolation result is to be stored.
234
 * @x: x-coordinate (0.0 to 1.0).
235
 * @y: y-coordinate (0.0 to 1.0).
236
 * @bpp: Bytes per pixel.  @dest and each @values item is an array of
237
 *    @bpp bytes.
238
 * @has_alpha: %TRUE if the last channel is an alpha channel.
239
 * @values: Array of four pointers to pixels.
240
 *
241
 * Computes bilinear interpolation of four pixels.
242
 *
243
 * When @has_alpha is %FALSE, it's identical to gimp_bilinear_8() on
244
 * each channel separately.  When @has_alpha is %TRUE, it handles
245
 * alpha channel correctly.
246
 *
247
 * The pixels in @values correspond to corner x, y coordinates in the
248
 * following order: [0,0], [1,0], [0,1], [1,1].
249
 **/
250
void
251
gimp_bilinear_pixels_8 (guchar    *dest,
252
                        gdouble    x,
253
                        gdouble    y,
254
                        guint      bpp,
255
                        gboolean   has_alpha,
256
                        guchar   **values)
257
{
258
  guint i;
259
260
  g_return_if_fail (dest != NULL);
261
  g_return_if_fail (values != NULL);
262
263
  x = fmod (x, 1.0);
264
  y = fmod (y, 1.0);
265
266
  if (x < 0.0)
267
    x += 1.0;
268
  if (y < 0.0)
269
    y += 1.0;
270
271
  if (has_alpha)
272
    {
273
      guint   ai     = bpp - 1;
274
      gdouble alpha0 = values[0][ai];
275
      gdouble alpha1 = values[1][ai];
276
      gdouble alpha2 = values[2][ai];
277
      gdouble alpha3 = values[3][ai];
278
      gdouble alpha  = ((1.0 - y) * ((1.0 - x) * alpha0 + x * alpha1)
279
                        + y * ((1.0 - x) * alpha2 + x * alpha3));
280
281
      dest[ai] = (guchar) alpha;
282
      if (dest[ai])
283
        {
284
          for (i = 0; i < ai; i++)
285
            {
286
              gdouble m0 = ((1.0 - x) * values[0][i] * alpha0
287
                            + x * values[1][i] * alpha1);
288
              gdouble m1 = ((1.0 - x) * values[2][i] * alpha2
289
                            + x * values[3][i] * alpha3);
290
291
              dest[i] = (guchar) (((1.0 - y) * m0 + y * m1) / alpha);
292
            }
293
        }
294
    }
295
  else
296
    {
297
      for (i = 0; i < bpp; i++)
298
        {
299
          gdouble m0 = (1.0 - x) * values[0][i] + x * values[1][i];
300
          gdouble m1 = (1.0 - x) * values[2][i] + x * values[3][i];
301
302
          dest[i] = (guchar) ((1.0 - y) * m0 + y * m1);
303
        }
304
    }
305
}