~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/core/gimppalette-import.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
18
18
 
19
19
#include "config.h"
20
20
 
21
 
#include <string.h> /* memcpy */
22
 
#include <errno.h>
23
 
 
24
 
#ifdef HAVE_UNISTD_H
25
 
#include <unistd.h>
26
 
#endif
27
 
 
28
 
#include <sys/stat.h>
29
 
#include <sys/types.h>
30
 
#include <fcntl.h>
 
21
#include <string.h>
31
22
 
32
23
#include <glib-object.h>
33
24
 
34
 
#ifdef G_OS_WIN32
35
 
#include "libgimpbase/gimpwin32-io.h"
36
 
#endif
37
 
 
38
25
#include "libgimpbase/gimpbase.h"
39
26
#include "libgimpcolor/gimpcolor.h"
40
27
 
42
29
 
43
30
#include "base/pixel-region.h"
44
31
 
 
32
#include "gimpchannel.h"
45
33
#include "gimpcontainer.h"
 
34
#include "gimpcontext.h"
46
35
#include "gimpgradient.h"
47
36
#include "gimpimage.h"
48
37
#include "gimppalette.h"
49
 
#include "gimpprojection.h"
 
38
#include "gimppalette-import.h"
 
39
#include "gimppalette-load.h"
 
40
#include "gimppickable.h"
50
41
 
51
42
#include "gimp-intl.h"
52
43
 
58
49
 
59
50
GimpPalette *
60
51
gimp_palette_import_from_gradient (GimpGradient *gradient,
 
52
                                   GimpContext  *context,
61
53
                                   gboolean      reverse,
62
 
                                   const gchar  *palette_name,
63
 
                                   gint          n_colors)
 
54
                                   const gchar  *palette_name,
 
55
                                   gint          n_colors)
64
56
{
65
 
  GimpPalette *palette;
66
 
  gdouble      dx, cur_x;
67
 
  GimpRGB      color;
68
 
  gint         loop;
 
57
  GimpPalette         *palette;
 
58
  GimpGradientSegment *seg = NULL;
 
59
  gdouble              dx, cur_x;
 
60
  GimpRGB              color;
 
61
  gint                 i;
69
62
 
70
63
  g_return_val_if_fail (GIMP_IS_GRADIENT (gradient), NULL);
 
64
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
71
65
  g_return_val_if_fail (palette_name != NULL, NULL);
72
66
  g_return_val_if_fail (n_colors > 1, NULL);
73
67
 
74
 
  palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE));
 
68
  palette = GIMP_PALETTE (gimp_palette_new (palette_name));
75
69
 
76
70
  dx = 1.0 / (n_colors - 1);
77
71
 
78
 
  for (loop = 0, cur_x = 0; loop < n_colors; loop++, cur_x += dx)
 
72
  for (i = 0, cur_x = 0; i < n_colors; i++, cur_x += dx)
79
73
    {
80
 
      gimp_gradient_get_color_at (gradient, cur_x, reverse, &color);
81
 
      gimp_palette_add_entry (palette, NULL, &color);
 
74
      seg = gimp_gradient_get_color_at (gradient, context,
 
75
                                        seg, cur_x, reverse, &color);
 
76
      gimp_palette_add_entry (palette, -1, NULL, &color);
82
77
    }
83
78
 
84
79
  return palette;
103
98
static gint count_color_entries = 0;
104
99
 
105
100
static GHashTable *
106
 
gimp_palette_import_store_colors (GHashTable *h_array,
107
 
                                  guchar     *colors,
108
 
                                  guchar     *colors_real,
109
 
                                  gint        n_colors)
 
101
gimp_palette_import_store_colors (GHashTable *table,
 
102
                                  guchar     *colors,
 
103
                                  guchar     *colors_real,
 
104
                                  gint        n_colors)
110
105
{
111
106
  gpointer   found_color = NULL;
112
107
  ImgColors *new_color;
113
108
  guint      key_colors = colors[0] * 256 * 256 + colors[1] * 256 + colors[2];
114
109
 
115
 
  if (h_array == NULL)
 
110
  if (table == NULL)
116
111
    {
117
 
      h_array = g_hash_table_new (g_direct_hash, g_direct_equal);
 
112
      table = g_hash_table_new (g_direct_hash, g_direct_equal);
118
113
      count_color_entries = 0;
119
114
    }
120
115
  else
121
116
    {
122
 
      found_color = g_hash_table_lookup (h_array,
123
 
                                         GUINT_TO_POINTER (key_colors));
 
117
      found_color = g_hash_table_lookup (table, GUINT_TO_POINTER (key_colors));
124
118
    }
125
119
 
126
120
  if (found_color == NULL)
127
121
    {
128
122
      if (count_color_entries > MAX_IMAGE_COLORS)
129
 
        {
130
 
          /* Don't add any more new ones */
131
 
          return h_array;
132
 
        }
 
123
        {
 
124
          /* Don't add any more new ones */
 
125
          return table;
 
126
        }
133
127
 
134
128
      count_color_entries++;
135
129
 
143
137
      new_color->g     = colors[1];
144
138
      new_color->b     = colors[2];
145
139
 
146
 
      g_hash_table_insert (h_array, GUINT_TO_POINTER (key_colors), new_color);
 
140
      g_hash_table_insert (table, GUINT_TO_POINTER (key_colors), new_color);
147
141
    }
148
142
  else
149
143
    {
150
 
      new_color = (ImgColors *) found_color;
 
144
      new_color = found_color;
151
145
 
152
146
      if (new_color->count < (G_MAXINT - 1))
153
 
        new_color->count++;
 
147
        new_color->count++;
154
148
 
155
149
      /* Now do the adjustments ...*/
156
150
      new_color->r_adj += (colors_real[0] - colors[0]);
159
153
 
160
154
      /* Boundary conditions */
161
155
      if(new_color->r_adj > (G_MAXINT - 255))
162
 
        new_color->r_adj /= new_color->count;
 
156
        new_color->r_adj /= new_color->count;
163
157
 
164
158
      if(new_color->g_adj > (G_MAXINT - 255))
165
 
        new_color->g_adj /= new_color->count;
 
159
        new_color->g_adj /= new_color->count;
166
160
 
167
161
      if(new_color->b_adj > (G_MAXINT - 255))
168
 
        new_color->b_adj /= new_color->count;
 
162
        new_color->b_adj /= new_color->count;
169
163
    }
170
164
 
171
 
  return h_array;
 
165
  return table;
172
166
}
173
167
 
174
168
static void
175
 
gimp_palette_import_create_sorted_list (gpointer key,
176
 
                                        gpointer value,
177
 
                                        gpointer user_data)
 
169
gimp_palette_import_create_list (gpointer key,
 
170
                                 gpointer value,
 
171
                                 gpointer user_data)
178
172
{
179
 
  GSList    **sorted_list = (GSList**) user_data;
180
 
  ImgColors  *color_tab   = (ImgColors *) value;
 
173
  GSList    **list      = user_data;
 
174
  ImgColors  *color_tab = value;
181
175
 
182
 
  *sorted_list = g_slist_prepend (*sorted_list, color_tab);
 
176
  *list = g_slist_prepend (*list, color_tab);
183
177
}
184
178
 
185
179
static gint
186
180
gimp_palette_import_sort_colors (gconstpointer a,
187
 
                                 gconstpointer b)
 
181
                                 gconstpointer b)
188
182
{
189
 
  ImgColors *s1 = (ImgColors *) a;
190
 
  ImgColors *s2 = (ImgColors *) b;
 
183
  const ImgColors *s1 = a;
 
184
  const ImgColors *s2 = b;
191
185
 
192
186
  if(s1->count > s2->count)
193
187
    return -1;
199
193
 
200
194
static void
201
195
gimp_palette_import_create_image_palette (gpointer data,
202
 
                                          gpointer user_data)
 
196
                                          gpointer user_data)
203
197
{
204
 
  GimpPalette *palette;
205
 
  ImgColors   *color_tab;
 
198
  GimpPalette *palette   = user_data;
 
199
  ImgColors   *color_tab = data;
206
200
  gint         n_colors;
207
201
  gchar       *lab;
208
202
  GimpRGB      color;
209
203
 
210
 
  palette   = (GimpPalette *) user_data;
211
 
  color_tab = (ImgColors *) data;
212
 
 
213
204
  n_colors = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (palette),
214
 
                                                 "import_n_colors"));
 
205
                                                 "import-n-colors"));
215
206
 
216
207
  if (palette->n_colors >= n_colors)
217
208
    return;
226
217
     (guchar) color_tab->b + (color_tab->b_adj / color_tab->count),
227
218
     255);
228
219
 
229
 
  gimp_palette_add_entry (palette, lab, &color);
 
220
  gimp_palette_add_entry (palette, -1, lab, &color);
230
221
 
231
222
  g_free (lab);
232
223
}
233
224
 
234
225
static GimpPalette *
235
 
gimp_palette_import_image_make_palette (GHashTable  *h_array,
236
 
                                        const gchar *palette_name,
237
 
                                        gint         n_colors)
 
226
gimp_palette_import_make_palette (GHashTable  *table,
 
227
                                  const gchar *palette_name,
 
228
                                  gint         n_colors)
238
229
{
239
 
  GimpPalette *palette;
240
 
  GSList      *sorted_list = NULL;
241
 
 
242
 
  g_hash_table_foreach (h_array, gimp_palette_import_create_sorted_list,
243
 
                        &sorted_list);
244
 
  sorted_list = g_slist_sort (sorted_list, gimp_palette_import_sort_colors);
245
 
 
246
 
  palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE));
247
 
 
248
 
  g_object_set_data (G_OBJECT (palette), "import_n_colors",
249
 
                     GINT_TO_POINTER (n_colors));
250
 
 
251
 
  g_slist_foreach (sorted_list, gimp_palette_import_create_image_palette,
252
 
                   palette);
253
 
 
254
 
  g_object_set_data (G_OBJECT (palette), "import_n_colors", NULL);
 
230
  GimpPalette *palette = GIMP_PALETTE (gimp_palette_new (palette_name));
 
231
  GSList      *list    = NULL;
 
232
 
 
233
  if (! table)
 
234
    return palette;
 
235
 
 
236
  g_hash_table_foreach (table, gimp_palette_import_create_list, &list);
 
237
  list = g_slist_sort (list, gimp_palette_import_sort_colors);
 
238
 
 
239
  g_object_set_data (G_OBJECT (palette), "import-n-colors",
 
240
                     GINT_TO_POINTER (n_colors));
 
241
 
 
242
  g_slist_foreach (list, gimp_palette_import_create_image_palette, palette);
 
243
 
 
244
  g_object_set_data (G_OBJECT (palette), "import-n-colors", NULL);
255
245
 
256
246
  /*  Free up used memory
257
247
   *  Note the same structure is on both the hash list and the sorted
258
248
   *  list. So only delete it once.
259
249
   */
260
 
  g_hash_table_destroy (h_array);
261
 
 
262
 
  g_slist_foreach (sorted_list, (GFunc) g_free, NULL);
263
 
 
264
 
  g_slist_free (sorted_list);
 
250
  g_hash_table_destroy (table);
 
251
 
 
252
  g_slist_foreach (list, (GFunc) g_free, NULL);
 
253
 
 
254
  g_slist_free (list);
265
255
 
266
256
  return palette;
267
257
}
268
258
 
269
 
GimpPalette *
270
 
gimp_palette_import_from_image (GimpImage   *gimage,
271
 
                                const gchar *palette_name,
272
 
                                gint         n_colors,
273
 
                                gint         threshold)
 
259
static GHashTable *
 
260
gimp_palette_import_extract (GimpImage     *image,
 
261
                             GimpPickable  *pickable,
 
262
                             gint           pickable_off_x,
 
263
                             gint           pickable_off_y,
 
264
                             gboolean       selection_only,
 
265
                             gint           x,
 
266
                             gint           y,
 
267
                             gint           width,
 
268
                             gint           height,
 
269
                             gint           n_colors,
 
270
                             gint           threshold)
274
271
{
275
 
  PixelRegion    imagePR;
276
 
  guchar        *image_data;
277
 
  guchar        *idata;
278
 
  guchar         rgb[MAX_CHANNELS];
279
 
  guchar         rgb_real[MAX_CHANNELS];
280
 
  gboolean       has_alpha, indexed;
281
 
  gint           width, height;
282
 
  gint           bytes, alpha;
283
 
  gint           i, j;
284
 
  void          *pr;
285
 
  GimpImageType  d_type;
286
 
  GHashTable    *store_array = NULL;
287
 
 
288
 
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
289
 
  g_return_val_if_fail (palette_name != NULL, NULL);
290
 
  g_return_val_if_fail (n_colors > 1, NULL);
291
 
  g_return_val_if_fail (threshold > 0, NULL);
292
 
 
293
 
  gimp_projection_finish_draw (gimage->projection);
294
 
  gimp_projection_flush_now (gimage->projection);
295
 
 
296
 
  /*  Get the image information  */
297
 
  d_type    = gimp_projection_get_image_type (gimage->projection);
298
 
  bytes     = gimp_projection_get_bytes (gimage->projection);
299
 
  has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (d_type);
300
 
  indexed   = GIMP_IMAGE_TYPE_IS_INDEXED (d_type);
301
 
  width     = gimage->width;
302
 
  height    = gimage->height;
303
 
 
304
 
  pixel_region_init (&imagePR, gimp_projection_get_tiles (gimage->projection),
305
 
                     0, 0, width, height, FALSE);
306
 
 
307
 
  alpha = bytes - 1;
308
 
 
309
 
  /*  iterate over the entire image  */
310
 
  for (pr = pixel_regions_register (1, &imagePR);
 
272
  TileManager   *tiles;
 
273
  GimpImageType  type;
 
274
  PixelRegion    region;
 
275
  PixelRegion    mask_region;
 
276
  PixelRegion   *maskPR = NULL;
 
277
  gpointer       pr;
 
278
  GHashTable    *colors = NULL;
 
279
 
 
280
  tiles = gimp_pickable_get_tiles (pickable);
 
281
  type  = gimp_pickable_get_image_type (pickable);
 
282
 
 
283
  pixel_region_init (&region, tiles, x, y, width, height, FALSE);
 
284
 
 
285
  if (selection_only &&
 
286
      ! gimp_channel_is_empty (gimp_image_get_mask (image)))
 
287
    {
 
288
      pixel_region_init (&mask_region,
 
289
                         GIMP_DRAWABLE (gimp_image_get_mask (image))->tiles,
 
290
                         x + pickable_off_x, y + pickable_off_y,
 
291
                         width, height,
 
292
                         FALSE);
 
293
 
 
294
      maskPR = &mask_region;
 
295
    }
 
296
 
 
297
  for (pr = pixel_regions_register (maskPR ? 2 : 1, &region, maskPR);
311
298
       pr != NULL;
312
299
       pr = pixel_regions_process (pr))
313
300
    {
314
 
      image_data = imagePR.data;
315
 
 
316
 
      for (i = 0; i < imagePR.h; i++)
317
 
        {
318
 
          idata = image_data;
319
 
 
320
 
          for (j = 0; j < imagePR.w; j++)
321
 
            {
322
 
              /*  Get the rgb values for the color  */
323
 
              gimp_image_get_color (gimage, d_type, idata, rgb);
324
 
              memcpy (rgb_real, rgb, MAX_CHANNELS); /* Structure copy */
325
 
 
326
 
              rgb[0] = (rgb[0] / threshold) * threshold;
327
 
              rgb[1] = (rgb[1] / threshold) * threshold;
328
 
              rgb[2] = (rgb[2] / threshold) * threshold;
329
 
 
330
 
              store_array =
331
 
                gimp_palette_import_store_colors (store_array, rgb, rgb_real,
332
 
                                                  n_colors);
333
 
 
334
 
              idata += bytes;
335
 
            }
336
 
 
337
 
          image_data += imagePR.rowstride;
338
 
        }
339
 
    }
340
 
 
341
 
  return gimp_palette_import_image_make_palette (store_array,
342
 
                                                 palette_name,
343
 
                                                 n_colors);
344
 
}
 
301
      const guchar *data      = region.data;
 
302
      const guchar *mask_data = NULL;
 
303
      gint          i, j;
 
304
 
 
305
      if (maskPR)
 
306
        mask_data = maskPR->data;
 
307
 
 
308
      for (i = 0; i < region.h; i++)
 
309
        {
 
310
          const guchar *idata = data;
 
311
          const guchar *mdata = mask_data;
 
312
 
 
313
          for (j = 0; j < region.w; j++)
 
314
            {
 
315
              if (! mdata || *mdata)
 
316
                {
 
317
                  guchar rgba[MAX_CHANNELS];
 
318
 
 
319
                  gimp_image_get_color (image, type, idata, rgba);
 
320
 
 
321
                  /*  ignore completely transparent pixels  */
 
322
                  if (rgba[ALPHA_PIX])
 
323
                    {
 
324
                      guchar rgb_real[MAX_CHANNELS];
 
325
 
 
326
                      memcpy (rgb_real, rgba, MAX_CHANNELS);
 
327
 
 
328
                      rgba[0] = (rgba[0] / threshold) * threshold;
 
329
                      rgba[1] = (rgba[1] / threshold) * threshold;
 
330
                      rgba[2] = (rgba[2] / threshold) * threshold;
 
331
 
 
332
                      colors = gimp_palette_import_store_colors (colors,
 
333
                                                                 rgba, rgb_real,
 
334
                                                                 n_colors);
 
335
                    }
 
336
                }
 
337
 
 
338
              idata += region.bytes;
 
339
 
 
340
              if (mdata)
 
341
                mdata += maskPR->bytes;
 
342
            }
 
343
 
 
344
          data += region.rowstride;
 
345
 
 
346
          if (mask_data)
 
347
            mask_data += maskPR->rowstride;
 
348
        }
 
349
    }
 
350
 
 
351
  return colors;
 
352
}
 
353
 
 
354
GimpPalette *
 
355
gimp_palette_import_from_image (GimpImage   *image,
 
356
                                const gchar *palette_name,
 
357
                                gint         n_colors,
 
358
                                gint         threshold,
 
359
                                gboolean     selection_only)
 
360
{
 
361
  GHashTable *colors;
 
362
  gint        x, y;
 
363
  gint        width, height;
 
364
 
 
365
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
366
  g_return_val_if_fail (palette_name != NULL, NULL);
 
367
  g_return_val_if_fail (n_colors > 1, NULL);
 
368
  g_return_val_if_fail (threshold > 0, NULL);
 
369
 
 
370
  gimp_pickable_flush (GIMP_PICKABLE (image->projection));
 
371
 
 
372
  if (selection_only)
 
373
    {
 
374
      gimp_channel_bounds (gimp_image_get_mask (image),
 
375
                           &x, &y, &width, &height);
 
376
 
 
377
      width  -= x;
 
378
      height -= y;
 
379
    }
 
380
  else
 
381
    {
 
382
      x      = 0;
 
383
      y      = 0;
 
384
      width  = image->width;
 
385
      height = image->height;
 
386
    }
 
387
 
 
388
  colors = gimp_palette_import_extract (image,
 
389
                                        GIMP_PICKABLE (image->projection),
 
390
                                        0, 0,
 
391
                                        selection_only,
 
392
                                        x, y, width, height,
 
393
                                        n_colors, threshold);
 
394
 
 
395
  return gimp_palette_import_make_palette (colors, palette_name, n_colors);
 
396
}
 
397
 
345
398
 
346
399
/*  create a palette from an indexed image  **********************************/
347
400
 
348
401
GimpPalette *
349
 
gimp_palette_import_from_indexed_image (GimpImage   *gimage,
350
 
                                        const gchar *palette_name)
 
402
gimp_palette_import_from_indexed_image (GimpImage   *image,
 
403
                                        const gchar *palette_name)
351
404
{
352
405
  GimpPalette *palette;
353
406
  gint         count;
354
407
  GimpRGB      color;
355
408
 
356
 
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
357
 
  g_return_val_if_fail (gimp_image_base_type (gimage) == GIMP_INDEXED, NULL);
 
409
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
410
  g_return_val_if_fail (gimp_image_base_type (image) == GIMP_INDEXED, NULL);
358
411
  g_return_val_if_fail (palette_name != NULL, NULL);
359
412
 
360
 
  palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE));
 
413
  palette = GIMP_PALETTE (gimp_palette_new (palette_name));
361
414
 
362
 
  for (count= 0; count < gimage->num_cols; ++count)
 
415
  for (count = 0; count < image->num_cols; ++count)
363
416
    {
 
417
      gchar name[256];
 
418
 
 
419
      g_snprintf (name, sizeof (name), _("Index %d"), count);
 
420
 
364
421
      gimp_rgba_set_uchar (&color,
365
 
                           gimage->cmap[count * 3],
366
 
                           gimage->cmap[count * 3 + 1],
367
 
                           gimage->cmap[count * 3 + 2],
368
 
                           255);
 
422
                           image->cmap[count * 3 + 0],
 
423
                           image->cmap[count * 3 + 1],
 
424
                           image->cmap[count * 3 + 2],
 
425
                           255);
369
426
 
370
 
      gimp_palette_add_entry (palette, NULL, &color);
 
427
      gimp_palette_add_entry (palette, -1, name, &color);
371
428
    }
372
429
 
373
430
  return palette;
374
431
}
375
432
 
376
433
 
 
434
/*  create a palette from a drawable  ****************************************/
 
435
 
 
436
GimpPalette *
 
437
gimp_palette_import_from_drawable (GimpDrawable *drawable,
 
438
                                   const gchar  *palette_name,
 
439
                                   gint          n_colors,
 
440
                                   gint          threshold,
 
441
                                   gboolean      selection_only)
 
442
{
 
443
  GHashTable *colors = NULL;
 
444
  gint        x, y;
 
445
  gint        width, height;
 
446
  gint        off_x, off_y;
 
447
 
 
448
  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
 
449
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
 
450
  g_return_val_if_fail (palette_name != NULL, NULL);
 
451
  g_return_val_if_fail (n_colors > 1, NULL);
 
452
  g_return_val_if_fail (threshold > 0, NULL);
 
453
 
 
454
  if (selection_only)
 
455
    {
 
456
      if (! gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
 
457
        return NULL;
 
458
    }
 
459
  else
 
460
    {
 
461
      x      = 0;
 
462
      y      = 0;
 
463
      width  = gimp_item_width (GIMP_ITEM (drawable));
 
464
      height = gimp_item_height (GIMP_ITEM (drawable));
 
465
    }
 
466
 
 
467
  gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y);
 
468
 
 
469
  colors =
 
470
    gimp_palette_import_extract (gimp_item_get_image (GIMP_ITEM (drawable)),
 
471
                                 GIMP_PICKABLE (drawable),
 
472
                                 off_x, off_y,
 
473
                                 selection_only,
 
474
                                 x, y, width, height,
 
475
                                 n_colors, threshold);
 
476
 
 
477
  return gimp_palette_import_make_palette (colors, palette_name, n_colors);
 
478
}
 
479
 
 
480
 
377
481
/*  create a palette from a file  **********************************/
378
482
 
379
 
typedef enum
380
 
{
381
 
  GIMP_PALETTE_FILE_FORMAT_UNKNOWN,
382
 
  GIMP_PALETTE_FILE_FORMAT_GPL,    /*  GIMP palette file                    */
383
 
  GIMP_PALETTE_FILE_FORMAT_PAL,    /*  RIFF palette file                    */
384
 
  GIMP_PALETTE_FILE_FORMAT_ACT     /*  Photoshop binary color palette file  */
385
 
} GimpPaletteFileFormat;
386
 
 
387
 
static GimpPaletteFileFormat
388
 
gimp_palette_detect_file_format (const gchar *filename)
389
 
{
390
 
  GimpPaletteFileFormat format = GIMP_PALETTE_FILE_FORMAT_UNKNOWN;
391
 
  gint                  fd;
392
 
  guchar                header[16];
393
 
  struct stat           file_stat;
394
 
 
395
 
  fd = open (filename, O_RDONLY);
396
 
  if (fd)
397
 
    {
398
 
      if (read (fd, header, sizeof (header)) == sizeof (header))
399
 
        {
400
 
          if (strncmp (header + 0, "RIFF", 4) == 0 &&
401
 
              strncmp (header + 8, "PAL data", 8) == 0)
402
 
            {
403
 
              format = GIMP_PALETTE_FILE_FORMAT_PAL;
404
 
            }
405
 
 
406
 
          if (strncmp (header, "GIMP Palette", 12) == 0)
407
 
            {
408
 
              format = GIMP_PALETTE_FILE_FORMAT_GPL;
409
 
            }
410
 
        }
411
 
 
412
 
      if (fstat (fd, &file_stat) >= 0)
413
 
        {
414
 
          if (file_stat.st_size == 768)
415
 
            format = GIMP_PALETTE_FILE_FORMAT_ACT;
416
 
        }
417
 
 
418
 
      close (fd);
419
 
    }
420
 
 
421
 
  return format;
422
 
}
423
 
 
424
483
GimpPalette *
425
484
gimp_palette_import_from_file (const gchar  *filename,
426
485
                               const gchar  *palette_name,
427
486
                               GError      **error)
428
487
{
429
 
  GimpPalette *palette = NULL;
430
 
  GList       *palette_list;
431
 
  GimpRGB      color;
432
 
  gint         fd;
433
 
  guchar       color_bytes[4];
 
488
  GList *palette_list = NULL;
434
489
 
435
490
  g_return_val_if_fail (filename != NULL, NULL);
436
491
  g_return_val_if_fail (palette_name != NULL, NULL);
437
492
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
438
493
 
439
 
  fd = open (filename, O_RDONLY);
440
 
  if (! fd)
441
 
    {
442
 
      g_set_error (error,
443
 
                   G_FILE_ERROR, g_file_error_from_errno (errno),
444
 
                   _("Opening '%s' failed: %s"),
445
 
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
446
 
      return NULL;
447
 
    }
448
 
 
449
 
  switch (gimp_palette_detect_file_format (filename))
 
494
  switch (gimp_palette_load_detect_format (filename))
450
495
    {
451
496
    case GIMP_PALETTE_FILE_FORMAT_GPL:
452
 
      palette_list = gimp_palette_load (filename, FALSE, error);
453
 
      if (palette_list)
454
 
        {
455
 
          palette = palette_list->data;
456
 
          g_list_free (palette_list);
457
 
        }
 
497
      palette_list = gimp_palette_load (filename, error);
458
498
      break;
459
499
 
460
500
    case GIMP_PALETTE_FILE_FORMAT_ACT:
461
 
      palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE));
462
 
 
463
 
      while (read (fd, color_bytes, 3) == 3)
464
 
        {
465
 
          gimp_rgba_set_uchar (&color,
466
 
                               color_bytes[0],
467
 
                               color_bytes[1],
468
 
                               color_bytes[2],
469
 
                               255);
470
 
          gimp_palette_add_entry (palette, NULL, &color);
471
 
        }
472
 
      break;
473
 
 
474
 
    case GIMP_PALETTE_FILE_FORMAT_PAL:
475
 
      palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE));
476
 
 
477
 
      lseek (fd, 28, SEEK_SET);
478
 
      while (read (fd,
479
 
                   color_bytes, sizeof (color_bytes)) == sizeof (color_bytes))
480
 
        {
481
 
          gimp_rgba_set_uchar (&color,
482
 
                               color_bytes[0],
483
 
                               color_bytes[1],
484
 
                               color_bytes[2],
485
 
                               255);
486
 
          gimp_palette_add_entry (palette, NULL, &color);
487
 
        }
 
501
      palette_list = gimp_palette_load_act (filename, error);
 
502
      break;
 
503
 
 
504
    case GIMP_PALETTE_FILE_FORMAT_RIFF_PAL:
 
505
      palette_list = gimp_palette_load_riff (filename, error);
 
506
      break;
 
507
 
 
508
    case GIMP_PALETTE_FILE_FORMAT_PSP_PAL:
 
509
      palette_list = gimp_palette_load_psp (filename, error);
488
510
      break;
489
511
 
490
512
    default:
491
513
      g_set_error (error,
492
 
                   0, 0,
493
 
                   _("Unknown type of palette file:\n%s"),
 
514
                   GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
515
                   _("Unknown type of palette file: %s"),
494
516
                   gimp_filename_to_utf8 (filename));
495
517
      break;
496
518
    }
497
519
 
498
 
  close (fd);
499
 
 
500
 
  return palette;
 
520
  if (palette_list)
 
521
    {
 
522
      GimpPalette *palette = g_object_ref (palette_list->data);
 
523
 
 
524
      gimp_object_set_name (GIMP_OBJECT (palette), palette_name);
 
525
 
 
526
      g_list_foreach (palette_list, (GFunc) g_object_unref, NULL);
 
527
      g_list_free (palette_list);
 
528
 
 
529
      return palette;
 
530
    }
 
531
 
 
532
  return NULL;
501
533
}
502