From 7e84dd9540ccab753e4a6be4d668d2f96b88c331 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 15 Apr 2004 15:03:20 +0000 Subject: [PATCH] app/core/gimppalette-import.[ch] added palette import from RIFF palette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2004-04-15 Sven Neumann * app/core/gimppalette-import.[ch] * app/gui/palette-import-dialog.c: added palette import from RIFF palette files based on a patch from ÉRDI Gergõ (bug #129788). --- ChangeLog | 6 ++ app/core/gimppalette-import.c | 67 +++++++++++++ app/core/gimppalette-import.h | 4 +- app/dialogs/palette-import-dialog.c | 141 ++++++++++++++++++++++++++-- app/gui/palette-import-dialog.c | 141 ++++++++++++++++++++++++++-- 5 files changed, 342 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6465d7483..7c8a17eb4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-04-15 Sven Neumann + + * app/core/gimppalette-import.[ch] + * app/gui/palette-import-dialog.c: added palette import from RIFF + palette files based on a patch from ÉRDI Gergõ (bug #129788). + 2004-04-15 Michael Natterer * app/xcf/xcf.c (xcf_save_invoker) (xcf_load_invoker): forgot diff --git a/app/core/gimppalette-import.c b/app/core/gimppalette-import.c index c676eadb30..fc56c6f002 100644 --- a/app/core/gimppalette-import.c +++ b/app/core/gimppalette-import.c @@ -19,9 +19,18 @@ #include "config.h" #include /* memcpy */ +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include #include +#include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" #include "core-types.h" @@ -355,3 +364,61 @@ gimp_palette_import_from_indexed_image (GimpImage *gimage, return palette; } + + +/* create a palette from a PAL file **********************************/ + +GimpPalette * +gimp_palette_import_from_file (const gchar *filename, + const gchar *palette_name, + GError **error) +{ + GimpPalette *palette; + GimpRGB color; + gint fd; + guchar header[28]; + guchar color_bytes[4]; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (palette_name != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + fd = open (filename, O_RDONLY); + if (! fd) + { + g_set_error (error, + G_FILE_ERROR, g_file_error_from_errno (errno), + _("Opening '%s' failed: %s"), + gimp_filename_to_utf8 (filename), g_strerror (errno)); + return NULL; + } + + /* TODO: Parse header correctly. For now, we just skip the 28 bytes */ + if (read (fd, header, sizeof (header)) != sizeof (header) || + strncmp (header + 0, "RIFF", 4) || + strncmp (header + 8, "PAL data", 8)) + { + close (fd); + g_set_error (error, + 0, 0, + _("Not a RIFF palette file:\n%s"), + gimp_filename_to_utf8 (filename)); + return NULL; + } + + palette = GIMP_PALETTE (gimp_palette_new (palette_name, FALSE)); + + while (read (fd, color_bytes, sizeof (color_bytes)) == sizeof (color_bytes)) + { + gimp_rgba_set_uchar (&color, + color_bytes[0], + color_bytes[1], + color_bytes[2], + 255); + gimp_palette_add_entry (palette, NULL, &color); + } + + close (fd); + + return palette; +} diff --git a/app/core/gimppalette-import.h b/app/core/gimppalette-import.h index 9ba6de89aa..b64342d314 100644 --- a/app/core/gimppalette-import.h +++ b/app/core/gimppalette-import.h @@ -30,6 +30,8 @@ GimpPalette * gimp_palette_import_from_image (GimpImage *gimage, gint treshold); GimpPalette * gimp_palette_import_from_indexed_image (GimpImage *gimage, const gchar *palette_name); - +GimpPalette * gimp_palette_import_from_file (const gchar *filename, + const gchar *palette_name, + GError **error); #endif /* __GIMP_PALETTE_IMPORT_H__ */ diff --git a/app/dialogs/palette-import-dialog.c b/app/dialogs/palette-import-dialog.c index c6b6932be8..ed6a1ceede 100644 --- a/app/dialogs/palette-import-dialog.c +++ b/app/dialogs/palette-import-dialog.c @@ -55,7 +55,8 @@ typedef enum { GRADIENT_IMPORT, - IMAGE_IMPORT + IMAGE_IMPORT, + FILE_IMPORT } ImportType; @@ -73,10 +74,14 @@ struct _ImportDialog GtkWidget *gradient_menu; GtkWidget *image_menu; + GtkWidget *filename_entry; GtkWidget *entry; + GtkWidget *image_radio; GtkWidget *gradient_radio; + GtkWidget *palettefile_radio; + GtkAdjustment *threshold; GtkAdjustment *num_colors; GtkAdjustment *columns; @@ -95,6 +100,8 @@ static void palette_import_gradient_changed (GimpContext *context, static void palette_import_image_changed (GimpContext *context, GimpImage *gimage, ImportDialog *import_dialog); +static void palette_import_filename_changed (GimpFileEntry *file_entry, + ImportDialog *import_dialog); static void import_dialog_drop_callback (GtkWidget *widget, GimpViewable *viewable, gpointer data); @@ -102,6 +109,8 @@ static void palette_import_grad_callback (GtkWidget *widget, ImportDialog *import_dialog); static void palette_import_image_callback (GtkWidget *widget, ImportDialog *import_dialog); +static void palette_import_file_callback (GtkWidget *widget, + ImportDialog *import_dialog); static void palette_import_columns_changed (GtkAdjustment *adjustment, ImportDialog *import_dialog); static void palette_import_image_add (GimpContainer *container, @@ -217,12 +226,12 @@ palette_import_dialog_new (Gimp *gimp) 0, 1, 0, 1); gtk_widget_show (import_dialog->gradient_radio); - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (import_dialog->gradient_radio)); - g_signal_connect (import_dialog->gradient_radio, "toggled", G_CALLBACK (palette_import_grad_callback), import_dialog); + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (import_dialog->gradient_radio)); + import_dialog->image_radio = gtk_radio_button_new_with_mnemonic (group, _("I_mage")); gtk_table_attach_defaults (GTK_TABLE (table), import_dialog->image_radio, @@ -236,6 +245,17 @@ palette_import_dialog_new (Gimp *gimp) gtk_widget_set_sensitive (import_dialog->image_radio, gimp_container_num_children (gimp->images) > 0); + import_dialog->palettefile_radio = + gtk_radio_button_new_with_mnemonic (group, _("Palette _File")); + gtk_table_attach_defaults (GTK_TABLE (table), + import_dialog->palettefile_radio, + 0, 1, 2, 3); + gtk_widget_show (import_dialog->palettefile_radio); + + g_signal_connect (import_dialog->palettefile_radio, "toggled", + G_CALLBACK (palette_import_file_callback), + import_dialog); + /* The gradient menu */ import_dialog->gradient_menu = gtk_option_menu_new (); gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, @@ -258,6 +278,15 @@ palette_import_dialog_new (Gimp *gimp) gtk_option_menu_set_menu (GTK_OPTION_MENU (import_dialog->image_menu), menu); gtk_widget_show (menu); + /* Palette file name entry */ + import_dialog->filename_entry = + gimp_file_entry_new (_("Select palette file"), 0, FALSE, FALSE); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 2, + NULL, 1.0, 0.5, + import_dialog->filename_entry, 1, FALSE); + + gtk_widget_show (import_dialog->filename_entry); + { gint focus_line_width; gint focus_padding; @@ -372,9 +401,14 @@ palette_import_dialog_new (Gimp *gimp) g_signal_connect (import_dialog->context, "image_changed", G_CALLBACK (palette_import_image_changed), import_dialog); + g_signal_connect (import_dialog->filename_entry, "filename_changed", + G_CALLBACK (palette_import_filename_changed), + import_dialog); palette_import_make_palette (import_dialog); + palette_import_grad_callback (import_dialog->gradient_radio, import_dialog); + return import_dialog; } @@ -400,10 +434,16 @@ palette_import_response (GtkWidget *widget, palette_import_image_remove, import_dialog); - if (response_id == GTK_RESPONSE_OK) - if (import_dialog->palette) + if (response_id == GTK_RESPONSE_OK && import_dialog->palette) + { + const gchar *name = gtk_entry_get_text (GTK_ENTRY (import_dialog->entry)); + + if (name && *name) + gimp_object_set_name (GIMP_OBJECT (import_dialog->palette), name); + gimp_container_add (gimp->palette_factory->container, GIMP_OBJECT (import_dialog->palette)); + } g_object_unref (import_dialog->context); @@ -434,8 +474,8 @@ palette_import_gradient_changed (GimpContext *context, } static void -palette_import_image_changed (GimpContext *context, - GimpImage *gimage, +palette_import_image_changed (GimpContext *context, + GimpImage *gimage, ImportDialog *import_dialog) { if (gimage && import_dialog->import_type == IMAGE_IMPORT) @@ -455,6 +495,35 @@ palette_import_image_changed (GimpContext *context, } } +static void +palette_import_filename_changed (GimpFileEntry *file_entry, + ImportDialog *import_dialog) +{ + gchar *filename; + + if (import_dialog->import_type != FILE_IMPORT) + return; + + filename = gimp_file_entry_get_filename (file_entry); + + if (filename && filename[0]) + { + gchar *basename = g_path_get_basename (filename); + + /* TODO: strip filename extension */ + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), basename); + g_free (basename); + } + else + { + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), ""); + } + + g_free (filename); + + palette_import_make_palette (import_dialog); +} + static void import_dialog_drop_callback (GtkWidget *widget, GimpViewable *viewable, @@ -497,10 +566,14 @@ palette_import_grad_callback (GtkWidget *widget, import_dialog->import_type = GRADIENT_IMPORT; gtk_widget_set_sensitive (import_dialog->image_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, FALSE); gtk_widget_set_sensitive (import_dialog->gradient_menu, TRUE); gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), GIMP_OBJECT (gradient)->name); + + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), TRUE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), TRUE); gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), FALSE); palette_import_make_palette (import_dialog); @@ -524,13 +597,50 @@ palette_import_image_callback (GtkWidget *widget, import_dialog->import_type = IMAGE_IMPORT; gtk_widget_set_sensitive (import_dialog->gradient_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, FALSE); gtk_widget_set_sensitive (import_dialog->image_menu, TRUE); palette_import_image_changed (import_dialog->context, gimage, import_dialog); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), TRUE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), TRUE); gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), TRUE); } +static void +palette_import_file_callback (GtkWidget *widget, + ImportDialog *import_dialog) +{ + gchar *filename; + + import_dialog->import_type = FILE_IMPORT; + + gtk_widget_set_sensitive (import_dialog->gradient_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->image_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, TRUE); + + filename = gimp_file_entry_get_filename (GIMP_FILE_ENTRY (import_dialog->filename_entry)); + + if (filename && *filename) + { + gchar *basename = g_path_get_basename (filename); + + /* TODO: strip filename extension */ + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), basename); + g_free (basename); + } + else + { + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), ""); + } + + g_free (filename); + + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), FALSE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), FALSE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), FALSE); +} + static void palette_import_columns_changed (GtkAdjustment *adjustment, ImportDialog *import_dialog) @@ -571,7 +681,7 @@ static void palette_import_make_palette (ImportDialog *import_dialog) { GimpPalette *palette = NULL; - const gchar *entry; + const gchar *entry, *filename; gchar *palette_name; GimpGradient *gradient; GimpImage *gimage; @@ -588,6 +698,7 @@ palette_import_make_palette (ImportDialog *import_dialog) gradient = gimp_context_get_gradient (import_dialog->context); gimage = gimp_context_get_image (import_dialog->context); + filename = gimp_file_entry_get_filename (GIMP_FILE_ENTRY (import_dialog->filename_entry)); n_colors = ROUND (import_dialog->num_colors->value); n_columns = ROUND (import_dialog->columns->value); @@ -617,6 +728,20 @@ palette_import_make_palette (ImportDialog *import_dialog) threshold); } break; + case FILE_IMPORT: + { + GError *error = NULL; + + palette = gimp_palette_import_from_file (filename, + palette_name, &error); + + if (! palette) + { + g_message (error->message); + g_error_free (error); + } + } + break; } g_free (palette_name); diff --git a/app/gui/palette-import-dialog.c b/app/gui/palette-import-dialog.c index c6b6932be8..ed6a1ceede 100644 --- a/app/gui/palette-import-dialog.c +++ b/app/gui/palette-import-dialog.c @@ -55,7 +55,8 @@ typedef enum { GRADIENT_IMPORT, - IMAGE_IMPORT + IMAGE_IMPORT, + FILE_IMPORT } ImportType; @@ -73,10 +74,14 @@ struct _ImportDialog GtkWidget *gradient_menu; GtkWidget *image_menu; + GtkWidget *filename_entry; GtkWidget *entry; + GtkWidget *image_radio; GtkWidget *gradient_radio; + GtkWidget *palettefile_radio; + GtkAdjustment *threshold; GtkAdjustment *num_colors; GtkAdjustment *columns; @@ -95,6 +100,8 @@ static void palette_import_gradient_changed (GimpContext *context, static void palette_import_image_changed (GimpContext *context, GimpImage *gimage, ImportDialog *import_dialog); +static void palette_import_filename_changed (GimpFileEntry *file_entry, + ImportDialog *import_dialog); static void import_dialog_drop_callback (GtkWidget *widget, GimpViewable *viewable, gpointer data); @@ -102,6 +109,8 @@ static void palette_import_grad_callback (GtkWidget *widget, ImportDialog *import_dialog); static void palette_import_image_callback (GtkWidget *widget, ImportDialog *import_dialog); +static void palette_import_file_callback (GtkWidget *widget, + ImportDialog *import_dialog); static void palette_import_columns_changed (GtkAdjustment *adjustment, ImportDialog *import_dialog); static void palette_import_image_add (GimpContainer *container, @@ -217,12 +226,12 @@ palette_import_dialog_new (Gimp *gimp) 0, 1, 0, 1); gtk_widget_show (import_dialog->gradient_radio); - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (import_dialog->gradient_radio)); - g_signal_connect (import_dialog->gradient_radio, "toggled", G_CALLBACK (palette_import_grad_callback), import_dialog); + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (import_dialog->gradient_radio)); + import_dialog->image_radio = gtk_radio_button_new_with_mnemonic (group, _("I_mage")); gtk_table_attach_defaults (GTK_TABLE (table), import_dialog->image_radio, @@ -236,6 +245,17 @@ palette_import_dialog_new (Gimp *gimp) gtk_widget_set_sensitive (import_dialog->image_radio, gimp_container_num_children (gimp->images) > 0); + import_dialog->palettefile_radio = + gtk_radio_button_new_with_mnemonic (group, _("Palette _File")); + gtk_table_attach_defaults (GTK_TABLE (table), + import_dialog->palettefile_radio, + 0, 1, 2, 3); + gtk_widget_show (import_dialog->palettefile_radio); + + g_signal_connect (import_dialog->palettefile_radio, "toggled", + G_CALLBACK (palette_import_file_callback), + import_dialog); + /* The gradient menu */ import_dialog->gradient_menu = gtk_option_menu_new (); gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, @@ -258,6 +278,15 @@ palette_import_dialog_new (Gimp *gimp) gtk_option_menu_set_menu (GTK_OPTION_MENU (import_dialog->image_menu), menu); gtk_widget_show (menu); + /* Palette file name entry */ + import_dialog->filename_entry = + gimp_file_entry_new (_("Select palette file"), 0, FALSE, FALSE); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 2, + NULL, 1.0, 0.5, + import_dialog->filename_entry, 1, FALSE); + + gtk_widget_show (import_dialog->filename_entry); + { gint focus_line_width; gint focus_padding; @@ -372,9 +401,14 @@ palette_import_dialog_new (Gimp *gimp) g_signal_connect (import_dialog->context, "image_changed", G_CALLBACK (palette_import_image_changed), import_dialog); + g_signal_connect (import_dialog->filename_entry, "filename_changed", + G_CALLBACK (palette_import_filename_changed), + import_dialog); palette_import_make_palette (import_dialog); + palette_import_grad_callback (import_dialog->gradient_radio, import_dialog); + return import_dialog; } @@ -400,10 +434,16 @@ palette_import_response (GtkWidget *widget, palette_import_image_remove, import_dialog); - if (response_id == GTK_RESPONSE_OK) - if (import_dialog->palette) + if (response_id == GTK_RESPONSE_OK && import_dialog->palette) + { + const gchar *name = gtk_entry_get_text (GTK_ENTRY (import_dialog->entry)); + + if (name && *name) + gimp_object_set_name (GIMP_OBJECT (import_dialog->palette), name); + gimp_container_add (gimp->palette_factory->container, GIMP_OBJECT (import_dialog->palette)); + } g_object_unref (import_dialog->context); @@ -434,8 +474,8 @@ palette_import_gradient_changed (GimpContext *context, } static void -palette_import_image_changed (GimpContext *context, - GimpImage *gimage, +palette_import_image_changed (GimpContext *context, + GimpImage *gimage, ImportDialog *import_dialog) { if (gimage && import_dialog->import_type == IMAGE_IMPORT) @@ -455,6 +495,35 @@ palette_import_image_changed (GimpContext *context, } } +static void +palette_import_filename_changed (GimpFileEntry *file_entry, + ImportDialog *import_dialog) +{ + gchar *filename; + + if (import_dialog->import_type != FILE_IMPORT) + return; + + filename = gimp_file_entry_get_filename (file_entry); + + if (filename && filename[0]) + { + gchar *basename = g_path_get_basename (filename); + + /* TODO: strip filename extension */ + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), basename); + g_free (basename); + } + else + { + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), ""); + } + + g_free (filename); + + palette_import_make_palette (import_dialog); +} + static void import_dialog_drop_callback (GtkWidget *widget, GimpViewable *viewable, @@ -497,10 +566,14 @@ palette_import_grad_callback (GtkWidget *widget, import_dialog->import_type = GRADIENT_IMPORT; gtk_widget_set_sensitive (import_dialog->image_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, FALSE); gtk_widget_set_sensitive (import_dialog->gradient_menu, TRUE); gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), GIMP_OBJECT (gradient)->name); + + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), TRUE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), TRUE); gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), FALSE); palette_import_make_palette (import_dialog); @@ -524,13 +597,50 @@ palette_import_image_callback (GtkWidget *widget, import_dialog->import_type = IMAGE_IMPORT; gtk_widget_set_sensitive (import_dialog->gradient_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, FALSE); gtk_widget_set_sensitive (import_dialog->image_menu, TRUE); palette_import_image_changed (import_dialog->context, gimage, import_dialog); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), TRUE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), TRUE); gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), TRUE); } +static void +palette_import_file_callback (GtkWidget *widget, + ImportDialog *import_dialog) +{ + gchar *filename; + + import_dialog->import_type = FILE_IMPORT; + + gtk_widget_set_sensitive (import_dialog->gradient_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->image_menu, FALSE); + gtk_widget_set_sensitive (import_dialog->filename_entry, TRUE); + + filename = gimp_file_entry_get_filename (GIMP_FILE_ENTRY (import_dialog->filename_entry)); + + if (filename && *filename) + { + gchar *basename = g_path_get_basename (filename); + + /* TODO: strip filename extension */ + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), basename); + g_free (basename); + } + else + { + gtk_entry_set_text (GTK_ENTRY (import_dialog->entry), ""); + } + + g_free (filename); + + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->threshold), FALSE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->num_colors), FALSE); + gimp_scale_entry_set_sensitive (GTK_OBJECT (import_dialog->columns), FALSE); +} + static void palette_import_columns_changed (GtkAdjustment *adjustment, ImportDialog *import_dialog) @@ -571,7 +681,7 @@ static void palette_import_make_palette (ImportDialog *import_dialog) { GimpPalette *palette = NULL; - const gchar *entry; + const gchar *entry, *filename; gchar *palette_name; GimpGradient *gradient; GimpImage *gimage; @@ -588,6 +698,7 @@ palette_import_make_palette (ImportDialog *import_dialog) gradient = gimp_context_get_gradient (import_dialog->context); gimage = gimp_context_get_image (import_dialog->context); + filename = gimp_file_entry_get_filename (GIMP_FILE_ENTRY (import_dialog->filename_entry)); n_colors = ROUND (import_dialog->num_colors->value); n_columns = ROUND (import_dialog->columns->value); @@ -617,6 +728,20 @@ palette_import_make_palette (ImportDialog *import_dialog) threshold); } break; + case FILE_IMPORT: + { + GError *error = NULL; + + palette = gimp_palette_import_from_file (filename, + palette_name, &error); + + if (! palette) + { + g_message (error->message); + g_error_free (error); + } + } + break; } g_free (palette_name);