572 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			572 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /* PIKA - Photo and Image Kooker Application
 | ||
|  |  * a rebranding of The GNU Image Manipulation Program (created with heckimp) | ||
|  |  * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio | ||
|  |  * | ||
|  |  * Original copyright, applying to most contents (license remains unchanged):  | ||
|  |  * Copyright (C) 1995 Spencer Kimball and Peter Mattis | ||
|  |  * | ||
|  |  * This program is free software: you can redistribute it and/or modify | ||
|  |  * it under the terms of the GNU General Public License as published by | ||
|  |  * the Free Software Foundation; either version 3 of the License, or | ||
|  |  * (at your option) any later version. | ||
|  |  * | ||
|  |  * This program is distributed in the hope that it will be useful, | ||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||
|  |  * GNU General Public License for more details. | ||
|  |  * | ||
|  |  * You should have received a copy of the GNU General Public License | ||
|  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||
|  |  */ | ||
|  | 
 | ||
|  | #include "config.h"
 | ||
|  | 
 | ||
|  | #include <cairo.h>
 | ||
|  | #include <gegl.h>
 | ||
|  | #include <gdk-pixbuf/gdk-pixbuf.h>
 | ||
|  | 
 | ||
|  | #include "libpikabase/pikabase.h"
 | ||
|  | #include "libpikacolor/pikacolor.h"
 | ||
|  | 
 | ||
|  | #include "core-types.h"
 | ||
|  | 
 | ||
|  | #include "pikachannel.h"
 | ||
|  | #include "pikacontainer.h"
 | ||
|  | #include "pikacontext.h"
 | ||
|  | #include "pikagradient.h"
 | ||
|  | #include "pikaimage.h"
 | ||
|  | #include "pikaimage-colormap.h"
 | ||
|  | #include "pikapalette.h"
 | ||
|  | #include "pikapalette-import.h"
 | ||
|  | #include "pikapalette-load.h"
 | ||
|  | #include "pikapickable.h"
 | ||
|  | 
 | ||
|  | #include "pika-intl.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #define MAX_IMAGE_COLORS (10000 * 2)
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /*  create a palette from a gradient  ****************************************/ | ||
|  | 
 | ||
|  | PikaPalette * | ||
|  | pika_palette_import_from_gradient (PikaGradient                *gradient, | ||
|  |                                    PikaContext                 *context, | ||
|  |                                    gboolean                     reverse, | ||
|  |                                    PikaGradientBlendColorSpace  blend_color_space, | ||
|  |                                    const gchar                 *palette_name, | ||
|  |                                    gint                         n_colors) | ||
|  | { | ||
|  |   PikaPalette         *palette; | ||
|  |   PikaGradientSegment *seg = NULL; | ||
|  |   gdouble              dx, cur_x; | ||
|  |   PikaRGB              color; | ||
|  |   gint                 i; | ||
|  | 
 | ||
|  |   g_return_val_if_fail (PIKA_IS_GRADIENT (gradient), NULL); | ||
|  |   g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); | ||
|  |   g_return_val_if_fail (palette_name != NULL, NULL); | ||
|  |   g_return_val_if_fail (n_colors > 1, NULL); | ||
|  | 
 | ||
|  |   palette = PIKA_PALETTE (pika_palette_new (context, palette_name)); | ||
|  | 
 | ||
|  |   dx = 1.0 / (n_colors - 1); | ||
|  | 
 | ||
|  |   for (i = 0, cur_x = 0; i < n_colors; i++, cur_x += dx) | ||
|  |     { | ||
|  |       seg = pika_gradient_get_color_at (gradient, context, | ||
|  |                                         seg, cur_x, reverse, blend_color_space, | ||
|  |                                         &color); | ||
|  |       pika_palette_add_entry (palette, -1, NULL, &color); | ||
|  |     } | ||
|  | 
 | ||
|  |   return palette; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*  create a palette from a non-indexed image  *******************************/ | ||
|  | 
 | ||
|  | typedef struct _ImgColors ImgColors; | ||
|  | 
 | ||
|  | struct _ImgColors | ||
|  | { | ||
|  |   guint  count; | ||
|  |   guint  r_adj; | ||
|  |   guint  g_adj; | ||
|  |   guint  b_adj; | ||
|  |   guchar r; | ||
|  |   guchar g; | ||
|  |   guchar b; | ||
|  | }; | ||
|  | 
 | ||
|  | static gint count_color_entries = 0; | ||
|  | 
 | ||
|  | static GHashTable * | ||
|  | pika_palette_import_store_colors (GHashTable *table, | ||
|  |                                   guchar     *colors, | ||
|  |                                   guchar     *colors_real, | ||
|  |                                   gint        n_colors) | ||
|  | { | ||
|  |   gpointer   found_color = NULL; | ||
|  |   ImgColors *new_color; | ||
|  |   guint      key_colors = colors[0] * 256 * 256 + colors[1] * 256 + colors[2]; | ||
|  | 
 | ||
|  |   if (table == NULL) | ||
|  |     { | ||
|  |       table = g_hash_table_new (g_direct_hash, g_direct_equal); | ||
|  |       count_color_entries = 0; | ||
|  |     } | ||
|  |   else | ||
|  |     { | ||
|  |       found_color = g_hash_table_lookup (table, GUINT_TO_POINTER (key_colors)); | ||
|  |     } | ||
|  | 
 | ||
|  |   if (found_color == NULL) | ||
|  |     { | ||
|  |       if (count_color_entries > MAX_IMAGE_COLORS) | ||
|  |         { | ||
|  |           /* Don't add any more new ones */ | ||
|  |           return table; | ||
|  |         } | ||
|  | 
 | ||
|  |       count_color_entries++; | ||
|  | 
 | ||
|  |       new_color = g_slice_new (ImgColors); | ||
|  | 
 | ||
|  |       new_color->count = 1; | ||
|  |       new_color->r_adj = 0; | ||
|  |       new_color->g_adj = 0; | ||
|  |       new_color->b_adj = 0; | ||
|  |       new_color->r     = colors[0]; | ||
|  |       new_color->g     = colors[1]; | ||
|  |       new_color->b     = colors[2]; | ||
|  | 
 | ||
|  |       g_hash_table_insert (table, GUINT_TO_POINTER (key_colors), new_color); | ||
|  |     } | ||
|  |   else | ||
|  |     { | ||
|  |       new_color = found_color; | ||
|  | 
 | ||
|  |       if (new_color->count < (G_MAXINT - 1)) | ||
|  |         new_color->count++; | ||
|  | 
 | ||
|  |       /* Now do the adjustments ...*/ | ||
|  |       new_color->r_adj += (colors_real[0] - colors[0]); | ||
|  |       new_color->g_adj += (colors_real[1] - colors[1]); | ||
|  |       new_color->b_adj += (colors_real[2] - colors[2]); | ||
|  | 
 | ||
|  |       /* Boundary conditions */ | ||
|  |       if(new_color->r_adj > (G_MAXINT - 255)) | ||
|  |         new_color->r_adj /= new_color->count; | ||
|  | 
 | ||
|  |       if(new_color->g_adj > (G_MAXINT - 255)) | ||
|  |         new_color->g_adj /= new_color->count; | ||
|  | 
 | ||
|  |       if(new_color->b_adj > (G_MAXINT - 255)) | ||
|  |         new_color->b_adj /= new_color->count; | ||
|  |     } | ||
|  | 
 | ||
|  |   return table; | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | pika_palette_import_create_list (gpointer key, | ||
|  |                                  gpointer value, | ||
|  |                                  gpointer user_data) | ||
|  | { | ||
|  |   GSList    **list      = user_data; | ||
|  |   ImgColors  *color_tab = value; | ||
|  | 
 | ||
|  |   *list = g_slist_prepend (*list, color_tab); | ||
|  | } | ||
|  | 
 | ||
|  | static gint | ||
|  | pika_palette_import_sort_colors (gconstpointer a, | ||
|  |                                  gconstpointer b) | ||
|  | { | ||
|  |   const ImgColors *s1 = a; | ||
|  |   const ImgColors *s2 = b; | ||
|  | 
 | ||
|  |   if(s1->count > s2->count) | ||
|  |     return -1; | ||
|  |   if(s1->count < s2->count) | ||
|  |     return 1; | ||
|  | 
 | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | pika_palette_import_create_image_palette (gpointer data, | ||
|  |                                           gpointer user_data) | ||
|  | { | ||
|  |   PikaPalette *palette   = user_data; | ||
|  |   ImgColors   *color_tab = data; | ||
|  |   gint         n_colors; | ||
|  |   gchar       *lab; | ||
|  |   PikaRGB      color; | ||
|  | 
 | ||
|  |   n_colors = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (palette), | ||
|  |                                                  "import-n-colors")); | ||
|  | 
 | ||
|  |   if (pika_palette_get_n_colors (palette) >= n_colors) | ||
|  |     return; | ||
|  | 
 | ||
|  |   /* TRANSLATORS: the "%s" is an item title and "%u" is the number of
 | ||
|  |      occurrences for this item. */ | ||
|  |   lab = g_strdup_printf (_("%s (occurs %u)"), | ||
|  |                          _("Untitled"), | ||
|  |                          color_tab->count); | ||
|  | 
 | ||
|  |   /* Adjust the colors to the mean of the the sample */ | ||
|  |   pika_rgba_set_uchar | ||
|  |     (&color, | ||
|  |      (guchar) color_tab->r + (color_tab->r_adj / color_tab->count), | ||
|  |      (guchar) color_tab->g + (color_tab->g_adj / color_tab->count), | ||
|  |      (guchar) color_tab->b + (color_tab->b_adj / color_tab->count), | ||
|  |      255); | ||
|  | 
 | ||
|  |   pika_palette_add_entry (palette, -1, lab, &color); | ||
|  | 
 | ||
|  |   g_free (lab); | ||
|  | } | ||
|  | 
 | ||
|  | static PikaPalette * | ||
|  | pika_palette_import_make_palette (GHashTable  *table, | ||
|  |                                   const gchar *palette_name, | ||
|  |                                   PikaContext *context, | ||
|  |                                   gint         n_colors) | ||
|  | { | ||
|  |   PikaPalette *palette; | ||
|  |   GSList      *list = NULL; | ||
|  |   GSList      *iter; | ||
|  | 
 | ||
|  |   palette = PIKA_PALETTE (pika_palette_new (context, palette_name)); | ||
|  | 
 | ||
|  |   if (! table) | ||
|  |     return palette; | ||
|  | 
 | ||
|  |   g_hash_table_foreach (table, pika_palette_import_create_list, &list); | ||
|  |   list = g_slist_sort (list, pika_palette_import_sort_colors); | ||
|  | 
 | ||
|  |   g_object_set_data (G_OBJECT (palette), "import-n-colors", | ||
|  |                      GINT_TO_POINTER (n_colors)); | ||
|  | 
 | ||
|  |   g_slist_foreach (list, pika_palette_import_create_image_palette, palette); | ||
|  | 
 | ||
|  |   g_object_set_data (G_OBJECT (palette), "import-n-colors", NULL); | ||
|  | 
 | ||
|  |   /*  Free up used memory
 | ||
|  |    *  Note the same structure is on both the hash list and the sorted | ||
|  |    *  list. So only delete it once. | ||
|  |    */ | ||
|  |   g_hash_table_destroy (table); | ||
|  | 
 | ||
|  |   for (iter = list; iter; iter = iter->next) | ||
|  |     g_slice_free (ImgColors, iter->data); | ||
|  | 
 | ||
|  |   g_slist_free (list); | ||
|  | 
 | ||
|  |   return palette; | ||
|  | } | ||
|  | 
 | ||
|  | static GHashTable * | ||
|  | pika_palette_import_extract (PikaImage     *image, | ||
|  |                              GHashTable    *colors, | ||
|  |                              PikaPickable  *pickable, | ||
|  |                              gint           pickable_off_x, | ||
|  |                              gint           pickable_off_y, | ||
|  |                              gboolean       selection_only, | ||
|  |                              gint           x, | ||
|  |                              gint           y, | ||
|  |                              gint           width, | ||
|  |                              gint           height, | ||
|  |                              gint           n_colors, | ||
|  |                              gint           threshold) | ||
|  | { | ||
|  |   GeglBuffer         *buffer; | ||
|  |   GeglBufferIterator *iter; | ||
|  |   GeglRectangle      *mask_roi = NULL; | ||
|  |   GeglRectangle       rect     = { x, y, width, height }; | ||
|  |   const Babl         *format; | ||
|  |   gint                bpp; | ||
|  |   gint                mask_bpp = 0; | ||
|  | 
 | ||
|  |   buffer = pika_pickable_get_buffer (pickable); | ||
|  |   format = babl_format ("R'G'B'A u8"); | ||
|  | 
 | ||
|  |   iter = gegl_buffer_iterator_new (buffer, &rect, 0, format, | ||
|  |                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2); | ||
|  |   bpp = babl_format_get_bytes_per_pixel (format); | ||
|  | 
 | ||
|  |   if (selection_only && | ||
|  |       ! pika_channel_is_empty (pika_image_get_mask (image))) | ||
|  |     { | ||
|  |       PikaDrawable *mask = PIKA_DRAWABLE (pika_image_get_mask (image)); | ||
|  | 
 | ||
|  |       rect.x = x + pickable_off_x; | ||
|  |       rect.y = y + pickable_off_y; | ||
|  | 
 | ||
|  |       buffer = pika_drawable_get_buffer (mask); | ||
|  |       format = babl_format ("Y u8"); | ||
|  | 
 | ||
|  |       gegl_buffer_iterator_add (iter, buffer, &rect, 0, format, | ||
|  |                                 GEGL_ACCESS_READ, GEGL_ABYSS_NONE); | ||
|  |       mask_roi = &iter->items[1].roi; | ||
|  |       mask_bpp = babl_format_get_bytes_per_pixel (format); | ||
|  |     } | ||
|  | 
 | ||
|  |   while (gegl_buffer_iterator_next (iter)) | ||
|  |     { | ||
|  |       const guchar *data      = iter->items[0].data; | ||
|  |       const guchar *mask_data = NULL; | ||
|  |       gint          length    = iter->length; | ||
|  | 
 | ||
|  |       if (mask_roi) | ||
|  |         mask_data = iter->items[1].data; | ||
|  | 
 | ||
|  |       while (length--) | ||
|  |         { | ||
|  |           /*  ignore unselected, and completely transparent pixels  */ | ||
|  |           if ((! mask_data || *mask_data) && data[ALPHA]) | ||
|  |             { | ||
|  |               guchar rgba[MAX_CHANNELS]     = { 0, }; | ||
|  |               guchar rgb_real[MAX_CHANNELS] = { 0, }; | ||
|  | 
 | ||
|  |               memcpy (rgba, data, 4); | ||
|  |               memcpy (rgb_real, rgba, 4); | ||
|  | 
 | ||
|  |               rgba[0] = (rgba[0] / threshold) * threshold; | ||
|  |               rgba[1] = (rgba[1] / threshold) * threshold; | ||
|  |               rgba[2] = (rgba[2] / threshold) * threshold; | ||
|  | 
 | ||
|  |               colors = pika_palette_import_store_colors (colors, | ||
|  |                                                          rgba, rgb_real, | ||
|  |                                                          n_colors); | ||
|  |             } | ||
|  | 
 | ||
|  |           data += bpp; | ||
|  | 
 | ||
|  |           if (mask_data) | ||
|  |             mask_data += mask_bpp; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |   return colors; | ||
|  | } | ||
|  | 
 | ||
|  | PikaPalette * | ||
|  | pika_palette_import_from_image (PikaImage   *image, | ||
|  |                                 PikaContext *context, | ||
|  |                                 const gchar *palette_name, | ||
|  |                                 gint         n_colors, | ||
|  |                                 gint         threshold, | ||
|  |                                 gboolean     selection_only) | ||
|  | { | ||
|  |   GHashTable *colors; | ||
|  |   gint        x, y; | ||
|  |   gint        width, height; | ||
|  | 
 | ||
|  |   g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL); | ||
|  |   g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); | ||
|  |   g_return_val_if_fail (palette_name != NULL, NULL); | ||
|  |   g_return_val_if_fail (n_colors > 1, NULL); | ||
|  |   g_return_val_if_fail (threshold > 0, NULL); | ||
|  | 
 | ||
|  |   pika_pickable_flush (PIKA_PICKABLE (image)); | ||
|  | 
 | ||
|  |   if (selection_only) | ||
|  |     { | ||
|  |       pika_item_bounds (PIKA_ITEM (pika_image_get_mask (image)), | ||
|  |                         &x, &y, &width, &height); | ||
|  |     } | ||
|  |   else | ||
|  |     { | ||
|  |       x      = 0; | ||
|  |       y      = 0; | ||
|  |       width  = pika_image_get_width  (image); | ||
|  |       height = pika_image_get_height (image); | ||
|  |     } | ||
|  | 
 | ||
|  |   colors = pika_palette_import_extract (image, | ||
|  |                                         NULL, | ||
|  |                                         PIKA_PICKABLE (image), | ||
|  |                                         0, 0, | ||
|  |                                         selection_only, | ||
|  |                                         x, y, width, height, | ||
|  |                                         n_colors, threshold); | ||
|  | 
 | ||
|  |   return pika_palette_import_make_palette (colors, palette_name, context, | ||
|  |                                            n_colors); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*  create a palette from an indexed image  **********************************/ | ||
|  | 
 | ||
|  | PikaPalette * | ||
|  | pika_palette_import_from_indexed_image (PikaImage   *image, | ||
|  |                                         PikaContext *context, | ||
|  |                                         const gchar *palette_name) | ||
|  | { | ||
|  |   PikaPalette  *palette; | ||
|  | 
 | ||
|  |   g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL); | ||
|  |   g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); | ||
|  |   g_return_val_if_fail (pika_image_get_base_type (image) == PIKA_INDEXED, NULL); | ||
|  |   g_return_val_if_fail (palette_name != NULL, NULL); | ||
|  | 
 | ||
|  |   palette = PIKA_PALETTE (pika_data_duplicate (PIKA_DATA (pika_image_get_colormap_palette (image)))); | ||
|  | 
 | ||
|  |   pika_object_set_name (PIKA_OBJECT (palette), palette_name); | ||
|  | 
 | ||
|  |   return palette; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*  create a palette from a drawable  ****************************************/ | ||
|  | 
 | ||
|  | PikaPalette * | ||
|  | pika_palette_import_from_drawables (GList       *drawables, | ||
|  |                                     PikaContext *context, | ||
|  |                                     const gchar *palette_name, | ||
|  |                                     gint         n_colors, | ||
|  |                                     gint         threshold, | ||
|  |                                     gboolean     selection_only) | ||
|  | { | ||
|  |   GHashTable *colors = NULL; | ||
|  |   GList      *iter; | ||
|  |   gint        x, y; | ||
|  |   gint        width, height; | ||
|  |   gint        off_x, off_y; | ||
|  | 
 | ||
|  |   g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); | ||
|  |   g_return_val_if_fail (palette_name != NULL, NULL); | ||
|  |   g_return_val_if_fail (n_colors > 1, NULL); | ||
|  |   g_return_val_if_fail (threshold > 0, NULL); | ||
|  | 
 | ||
|  |   for (iter = drawables; iter; iter = iter->next) | ||
|  |     { | ||
|  |       PikaDrawable *drawable = iter->data; | ||
|  | 
 | ||
|  |       g_return_val_if_fail (PIKA_IS_DRAWABLE (drawable), NULL); | ||
|  |       g_return_val_if_fail (pika_item_is_attached (PIKA_ITEM (drawable)), NULL); | ||
|  | 
 | ||
|  |       if (selection_only) | ||
|  |         { | ||
|  |           if (! pika_item_mask_intersect (PIKA_ITEM (drawable), | ||
|  |                                           &x, &y, &width, &height)) | ||
|  |             return NULL; | ||
|  |         } | ||
|  |       else | ||
|  |         { | ||
|  |           x      = 0; | ||
|  |           y      = 0; | ||
|  |           width  = pika_item_get_width  (PIKA_ITEM (drawable)); | ||
|  |           height = pika_item_get_height (PIKA_ITEM (drawable)); | ||
|  |         } | ||
|  | 
 | ||
|  |       pika_item_get_offset (PIKA_ITEM (drawable), &off_x, &off_y); | ||
|  | 
 | ||
|  |       colors = | ||
|  |         pika_palette_import_extract (pika_item_get_image (PIKA_ITEM (drawable)), | ||
|  |                                      colors, | ||
|  |                                      PIKA_PICKABLE (drawable), | ||
|  |                                      off_x, off_y, | ||
|  |                                      selection_only, | ||
|  |                                      x, y, width, height, | ||
|  |                                      n_colors, threshold); | ||
|  |     } | ||
|  | 
 | ||
|  |   return pika_palette_import_make_palette (colors, palette_name, context, | ||
|  |                                            n_colors); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*  create a palette from a file  **********************************/ | ||
|  | 
 | ||
|  | PikaPalette * | ||
|  | pika_palette_import_from_file (PikaContext  *context, | ||
|  |                                GFile        *file, | ||
|  |                                const gchar  *palette_name, | ||
|  |                                GError      **error) | ||
|  | { | ||
|  |   GList        *palette_list = NULL; | ||
|  |   GInputStream *input; | ||
|  |   GError       *my_error = NULL; | ||
|  | 
 | ||
|  |   g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); | ||
|  |   g_return_val_if_fail (G_IS_FILE (file), NULL); | ||
|  |   g_return_val_if_fail (palette_name != NULL, NULL); | ||
|  |   g_return_val_if_fail (error == NULL || *error == NULL, NULL); | ||
|  | 
 | ||
|  |   input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error)); | ||
|  |   if (! input) | ||
|  |     { | ||
|  |       g_set_error (error, PIKA_DATA_ERROR, PIKA_DATA_ERROR_OPEN, | ||
|  |                    _("Could not open '%s' for reading: %s"), | ||
|  |                    pika_file_get_utf8_name (file), my_error->message); | ||
|  |       g_clear_error (&my_error); | ||
|  |       return NULL; | ||
|  |     } | ||
|  | 
 | ||
|  |   switch (pika_palette_load_detect_format (file, input)) | ||
|  |     { | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_GPL: | ||
|  |       palette_list = pika_palette_load (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_ACT: | ||
|  |       palette_list = pika_palette_load_act (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_RIFF_PAL: | ||
|  |       palette_list = pika_palette_load_riff (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_PSP_PAL: | ||
|  |       palette_list = pika_palette_load_psp (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_ACO: | ||
|  |       palette_list = pika_palette_load_aco (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_ACB: | ||
|  |       palette_list = pika_palette_load_acb (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_ASE: | ||
|  |       palette_list = pika_palette_load_ase (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_CSS: | ||
|  |       palette_list = pika_palette_load_css (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     case PIKA_PALETTE_FILE_FORMAT_SBZ: | ||
|  |       palette_list = pika_palette_load_sbz (context, file, input, error); | ||
|  |       break; | ||
|  | 
 | ||
|  |     default: | ||
|  |       g_set_error (error, | ||
|  |                    PIKA_DATA_ERROR, PIKA_DATA_ERROR_READ, | ||
|  |                    _("Unknown type of palette file: %s"), | ||
|  |                    pika_file_get_utf8_name (file)); | ||
|  |       break; | ||
|  |     } | ||
|  | 
 | ||
|  |   g_object_unref (input); | ||
|  | 
 | ||
|  |   if (palette_list) | ||
|  |     { | ||
|  |       PikaPalette *palette = g_object_ref (palette_list->data); | ||
|  | 
 | ||
|  |       pika_object_set_name (PIKA_OBJECT (palette), palette_name); | ||
|  | 
 | ||
|  |       g_list_free_full (palette_list, (GDestroyNotify) g_object_unref); | ||
|  | 
 | ||
|  |       return palette; | ||
|  |     } | ||
|  | 
 | ||
|  |   return NULL; | ||
|  | } |