[gimp] Issue #526 - Add Import/Export for Windows .CUR files
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #526 - Add Import/Export for Windows .CUR files
- Date: Thu, 10 Feb 2022 12:09:42 +0000 (UTC)
commit a22fd4f43aa56fde190239bd0d56221e80d13691
Author: Nikc <nikcdc gmail com>
Date: Thu Feb 10 12:09:40 2022 +0000
Issue #526 - Add Import/Export for Windows .CUR files
plug-ins/file-ico/ico-dialog.c | 66 ++++++++++++++++----
plug-ins/file-ico/ico-load.c | 66 +++++++++++++-------
plug-ins/file-ico/ico-save.c | 134 ++++++++++++++++++++++++++++++++---------
plug-ins/file-ico/ico-save.h | 13 ++++
plug-ins/file-ico/ico.c | 118 +++++++++++++++++++++++++++++++++++-
plug-ins/file-ico/ico.h | 4 ++
6 files changed, 338 insertions(+), 63 deletions(-)
---
diff --git a/plug-ins/file-ico/ico-dialog.c b/plug-ins/file-ico/ico-dialog.c
index ba65f9d11f..6172149aa7 100644
--- a/plug-ins/file-ico/ico-dialog.c
+++ b/plug-ins/file-ico/ico-dialog.c
@@ -43,13 +43,16 @@ static void ico_dialog_check_compat (GtkWidget *dialog,
GtkWidget *
ico_dialog_new (IcoSaveInfo *info)
{
- GtkWidget *dialog;
- GtkWidget *main_vbox;
- GtkWidget *vbox;
- GtkWidget *frame;
- GtkWidget *scrolled_window;
- GtkWidget *viewport;
- GtkWidget *warning;
+ GtkWidget *dialog;
+ GtkWidget *main_vbox;
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *scrolled_window;
+ GtkWidget *viewport;
+ GtkWidget *grid;
+ GtkAdjustment *adj;
+ GtkWidget *spinbutton;
+ GtkWidget *warning;
dialog = gimp_export_dialog_new (_("Windows Icon"),
PLUG_IN_BINARY,
@@ -65,14 +68,55 @@ ico_dialog_new (IcoSaveInfo *info)
g_object_set_data (G_OBJECT (dialog), "save_info", info);
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
+ main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
+ /* Cursor */
+ if (info->is_cursor)
+ {
+ frame = gimp_frame_new (_("Cursor Hot spot"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 4);
+ gtk_widget_show (frame);
+
+ grid = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+ gtk_container_add (GTK_CONTAINER (frame), grid);
+ gtk_widget_show (grid);
+
+ adj = (GtkAdjustment *)
+ gtk_adjustment_new (info->hot_spot_x, 0,
+ G_MAXUINT16, 1, 10, 0);
+ spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+ 0, G_MAXUINT16);
+ gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
+ _("Hot spot _X:"), 0.0, 0.5,
+ spinbutton, 1);
+ g_signal_connect (adj, "value-changed",
+ G_CALLBACK (gimp_int_adjustment_update),
+ &info->hot_spot_x);
+
+ adj = (GtkAdjustment *)
+ gtk_adjustment_new (info->hot_spot_y, 0,
+ G_MAXUINT16, 1, 10, 0);
+ spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+ 0, G_MAXUINT16);
+ gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
+ _("Hot spot _Y:"), 0.0, 0.5,
+ spinbutton, 1);
+ g_signal_connect (adj, "value-changed",
+ G_CALLBACK (gimp_int_adjustment_update),
+ &info->hot_spot_y);
+ }
+
+ /* Cursor */
frame = gimp_frame_new (_("Icon Details"));
- gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 4);
gtk_widget_show (frame);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
@@ -98,7 +142,7 @@ ico_dialog_new (IcoSaveInfo *info)
"by all programs. Older applications may not "
"open this file correctly."),
NULL);
- gtk_box_pack_end (GTK_BOX (main_vbox), warning, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (main_vbox), warning, FALSE, FALSE, 12);
/* don't show the warning here */
g_object_set_data (G_OBJECT (dialog), "warning", warning);
diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c
index 62d8fdce20..abe4f2a915 100644
--- a/plug-ins/file-ico/ico-load.c
+++ b/plug-ins/file-ico/ico-load.c
@@ -120,7 +120,7 @@ ico_read_int8 (FILE *fp,
}
-static guint32
+static IcoFileHeader
ico_read_init (FILE *fp)
{
IcoFileHeader header;
@@ -130,12 +130,13 @@ ico_read_init (FILE *fp)
! ico_read_int16 (fp, &header.resource_type, 1) ||
! ico_read_int16 (fp, &header.icon_count, 1) ||
header.reserved != 0 ||
- header.resource_type != 1)
+ (header.resource_type != 1 && header.resource_type != 2))
{
- return 0;
+ header.icon_count = 0;
+ return header;
}
- return header.icon_count;
+ return header;
}
@@ -229,6 +230,7 @@ ico_read_info (FILE *fp,
{
info[i].width = entries[i].width;
info[i].height = entries[i].height;
+ info[i].planes = entries[i].planes;
info[i].bpp = GUINT16_FROM_LE (entries[i].bpp);
info[i].size = GUINT32_FROM_LE (entries[i].size);
info[i].offset = GUINT32_FROM_LE (entries[i].offset);
@@ -653,14 +655,17 @@ GimpImage *
ico_load_image (GFile *file,
GError **error)
{
- FILE *fp;
- IcoLoadInfo *info;
- gint max_width, max_height;
- gint i;
- GimpImage *image;
- guchar *buf;
- guint icon_count;
- gint maxsize;
+ FILE *fp;
+ IcoFileHeader header;
+ IcoLoadInfo *info;
+ gint max_width, max_height;
+ gint i;
+ GimpImage *image;
+ guchar *buf;
+ guint icon_count;
+ gint maxsize;
+ GimpParasite *parasite;
+ gchar *str;
gimp_progress_init_printf (_("Opening '%s'"),
gimp_file_get_utf8_name (file));
@@ -675,7 +680,8 @@ ico_load_image (GFile *file,
return NULL;
}
- icon_count = ico_read_init (fp);
+ header = ico_read_init (fp);
+ icon_count = header.icon_count;
if (!icon_count)
{
fclose (fp);
@@ -710,6 +716,18 @@ ico_load_image (GFile *file,
image = gimp_image_new (max_width, max_height, GIMP_RGB);
gimp_image_set_file (image, file);
+ /* Save CUR hot spot information */
+ if (header.resource_type == 2)
+ {
+ str = g_strdup_printf ("%d %d", info[0].planes, info[0].bpp);
+ parasite = gimp_parasite_new ("cur-hot-spot",
+ GIMP_PARASITE_PERSISTENT,
+ strlen (str) + 1, (gpointer) str);
+ g_free (str);
+ gimp_image_attach_parasite (image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
maxsize = max_width * max_height * 4;
buf = g_new (guchar, max_width * max_height * 4);
for (i = 0; i < icon_count; i++)
@@ -731,15 +749,16 @@ ico_load_thumbnail_image (GFile *file,
gint *height,
GError **error)
{
- FILE *fp;
- IcoLoadInfo *info;
- GimpImage *image;
- gint w = 0;
- gint h = 0;
- gint bpp = 0;
- gint match = 0;
- gint i, icon_count;
- guchar *buf;
+ FILE *fp;
+ IcoLoadInfo *info;
+ IcoFileHeader header;
+ GimpImage *image;
+ gint w = 0;
+ gint h = 0;
+ gint bpp = 0;
+ gint match = 0;
+ gint i, icon_count;
+ guchar *buf;
gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
gimp_file_get_utf8_name (file));
@@ -754,7 +773,8 @@ ico_load_thumbnail_image (GFile *file,
return NULL;
}
- icon_count = ico_read_init (fp);
+ header = ico_read_init (fp);
+ icon_count = header.icon_count;
if (! icon_count)
{
fclose (fp);
diff --git a/plug-ins/file-ico/ico-save.c b/plug-ins/file-ico/ico-save.c
index 4f8bf1c927..3f366e0145 100644
--- a/plug-ins/file-ico/ico-save.c
+++ b/plug-ins/file-ico/ico-save.c
@@ -233,13 +233,36 @@ static gboolean
ico_save_dialog (GimpImage *image,
IcoSaveInfo *info)
{
- GtkWidget *dialog;
- GList *iter;
- gint i;
- gint response;
+ GtkWidget *dialog;
+ GList *iter;
+ gint i;
+ gint response;
+ GimpParasite *parasite = NULL;
gimp_ui_init (PLUG_IN_BINARY);
+ /* Loading hot spots for cursors if applicable */
+ parasite = gimp_image_get_parasite (image, "cur-hot-spot");
+
+ if (parasite)
+ {
+ gchar *parasite_data;
+ guint32 parasite_size;
+ gint x, y;
+
+ parasite_data = (gchar *) gimp_parasite_get_data (parasite, ¶site_size);
+ parasite_data = g_strndup (parasite_data, parasite_size);
+
+ if (sscanf (parasite_data, "%i %i", &x, &y) == 2)
+ {
+ info->hot_spot_x = x;
+ info->hot_spot_y = y;
+ }
+
+ gimp_parasite_free (parasite);
+ g_free (parasite_data);
+ }
+
dialog = ico_dialog_new (info);
for (iter = info->layers, i = 0;
iter;
@@ -1065,26 +1088,61 @@ ico_save_image (GFile *file,
GimpImage *image,
gint32 run_mode,
GError **error)
+{
+ IcoSaveInfo info;
+
+ D(("*** Exporting Microsoft icon file %s\n",
+ gimp_file_get_utf8_name (file)));
+
+ info.is_cursor = FALSE;
+
+ return shared_save_image (file, image, run_mode, error, &info);
+}
+
+GimpPDBStatusType
+cur_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ gint32 hot_spot_x,
+ gint32 hot_spot_y,
+ GError **error)
+{
+ IcoSaveInfo info;
+
+ D(("*** Exporting Microsoft cursor file %s\n",
+ gimp_file_get_utf8_name (file)));
+
+ info.is_cursor = TRUE;
+ info.hot_spot_x = hot_spot_x;
+ info.hot_spot_y = hot_spot_y;
+
+ return shared_save_image (file, image, run_mode, error, &info);
+}
+
+GimpPDBStatusType
+shared_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ GError **error,
+ IcoSaveInfo *info)
{
FILE *fp;
GList *iter;
gint width;
gint height;
- IcoSaveInfo info;
IcoFileHeader header;
IcoFileEntry *entries;
gboolean saved;
gint i;
+ GimpParasite *parasite = NULL;
+ gchar *str;
- D(("*** Exporting Microsoft icon file %s\n",
- gimp_file_get_utf8_name (file)));
-
- ico_save_init (image, &info);
+ ico_save_init (image, info);
if (run_mode == GIMP_RUN_INTERACTIVE)
{
/* Allow user to override default values */
- if ( !ico_save_dialog (image, &info))
+ if ( !ico_save_dialog (image, info))
return GIMP_PDB_CANCEL;
}
@@ -1103,30 +1161,32 @@ ico_save_image (GFile *file,
header.reserved = 0;
header.resource_type = 1;
- header.icon_count = info.num_icons;
+ if (info->is_cursor)
+ header.resource_type = 2;
+ header.icon_count = info->num_icons;
if (! ico_write_int16 (fp, &header.reserved, 1) ||
! ico_write_int16 (fp, &header.resource_type, 1) ||
! ico_write_int16 (fp, &header.icon_count, 1))
{
- ico_save_info_free (&info);
+ ico_save_info_free (info);
fclose (fp);
return GIMP_PDB_EXECUTION_ERROR;
}
- entries = g_new0 (IcoFileEntry, info.num_icons);
- if (fwrite (entries, sizeof (IcoFileEntry), info.num_icons, fp) <= 0)
+ entries = g_new0 (IcoFileEntry, info->num_icons);
+ if (fwrite (entries, sizeof (IcoFileEntry), info->num_icons, fp) <= 0)
{
- ico_save_info_free (&info);
+ ico_save_info_free (info);
g_free (entries);
fclose (fp);
return GIMP_PDB_EXECUTION_ERROR;
}
- for (iter = info.layers, i = 0;
+ for (iter = info->layers, i = 0;
iter;
iter = g_list_next (iter), i++)
{
- gimp_progress_update ((gdouble)i / (gdouble)info.num_icons);
+ gimp_progress_update ((gdouble)i / (gdouble)info->num_icons);
width = gimp_drawable_get_width (iter->data);
height = gimp_drawable_get_height (iter->data);
@@ -1140,23 +1200,29 @@ ico_save_image (GFile *file,
entries[i].width = 0;
entries[i].height = 0;
}
- if ( info.depths[i] <= 8 )
- entries[i].num_colors = 1 << info.depths[i];
+ if (info->depths[i] <= 8 )
+ entries[i].num_colors = 1 << info->depths[i];
else
entries[i].num_colors = 0;
entries[i].reserved = 0;
entries[i].planes = 1;
- entries[i].bpp = info.depths[i];
+ entries[i].bpp = info->depths[i];
+ /* .cur file reuses these fields for cursor offsets */
+ if (info->is_cursor)
+ {
+ entries[i].planes = info->hot_spot_x;
+ entries[i].bpp = info->hot_spot_y;
+ }
entries[i].offset = ftell (fp);
- if (info.compress[i])
- saved = ico_write_png (fp, iter->data, info.depths[i]);
+ if (info->compress[i])
+ saved = ico_write_png (fp, iter->data, info->depths[i]);
else
- saved = ico_write_icon (fp, iter->data, info.depths[i]);
+ saved = ico_write_icon (fp, iter->data, info->depths[i]);
if (!saved)
{
- ico_save_info_free (&info);
+ ico_save_info_free (info);
fclose (fp);
return GIMP_PDB_EXECUTION_ERROR;
}
@@ -1164,7 +1230,7 @@ ico_save_image (GFile *file,
entries[i].size = ftell (fp) - entries[i].offset;
}
- for (i = 0; i < info.num_icons; i++)
+ for (i = 0; i < info->num_icons; i++)
{
entries[i].planes = GUINT16_TO_LE (entries[i].planes);
entries[i].bpp = GUINT16_TO_LE (entries[i].bpp);
@@ -1173,16 +1239,28 @@ ico_save_image (GFile *file,
}
if (fseek (fp, sizeof(IcoFileHeader), SEEK_SET) < 0
- || fwrite (entries, sizeof (IcoFileEntry), info.num_icons, fp) <= 0)
+ || fwrite (entries, sizeof (IcoFileEntry), info->num_icons, fp) <= 0)
{
- ico_save_info_free (&info);
+ ico_save_info_free (info);
fclose (fp);
return GIMP_PDB_EXECUTION_ERROR;
}
gimp_progress_update (1.0);
- ico_save_info_free (&info);
+ /* Updating parasite hot spots if needed */
+ if (info->is_cursor)
+ {
+ str = g_strdup_printf ("%d %d", info->hot_spot_x, info->hot_spot_y);
+ parasite = gimp_parasite_new ("cur-hot-spot",
+ GIMP_PARASITE_PERSISTENT,
+ strlen (str) + 1, (gpointer) str);
+ g_free (str);
+ gimp_image_attach_parasite (image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ ico_save_info_free (info);
fclose (fp);
g_free (entries);
diff --git a/plug-ins/file-ico/ico-save.h b/plug-ins/file-ico/ico-save.h
index 8e78ea969f..920feb05d5 100644
--- a/plug-ins/file-ico/ico-save.h
+++ b/plug-ins/file-ico/ico-save.h
@@ -27,6 +27,19 @@ GimpPDBStatusType ico_save_image (GFile *file,
gint32 run_mode,
GError **error);
+GimpPDBStatusType cur_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ gint32 hot_spot_x,
+ gint32 hot_spot_y,
+ GError **error);
+
+GimpPDBStatusType shared_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ GError **error,
+ IcoSaveInfo *info);
+
gboolean ico_cmap_contains_black (const guchar *cmap,
gint num_colors);
diff --git a/plug-ins/file-ico/ico.c b/plug-ins/file-ico/ico.c
index cf1926c7f2..25f0f63999 100644
--- a/plug-ins/file-ico/ico.c
+++ b/plug-ins/file-ico/ico.c
@@ -34,8 +34,10 @@
#include "libgimp/stdplugins-intl.h"
#define LOAD_PROC "file-ico-load"
+#define LOAD_CUR_PROC "file-cur-load"
#define LOAD_THUMB_PROC "file-ico-load-thumb"
#define SAVE_PROC "file-ico-save"
+#define SAVE_CUR_PROC "file-cur-save"
typedef struct _Ico Ico;
@@ -79,6 +81,14 @@ static GimpValueArray * ico_save (GimpProcedure *procedure,
GFile *file,
const GimpValueArray *args,
gpointer run_data);
+static GimpValueArray * cur_save (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GimpImage *image,
+ gint n_drawables,
+ GimpDrawable **drawables,
+ GFile *file,
+ const GimpValueArray *args,
+ gpointer run_data);
G_DEFINE_TYPE (Ico, ico, GIMP_TYPE_PLUG_IN)
@@ -107,7 +117,9 @@ ico_query_procedures (GimpPlugIn *plug_in)
list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
list = g_list_append (list, g_strdup (LOAD_PROC));
+ list = g_list_append (list, g_strdup (LOAD_CUR_PROC));
list = g_list_append (list, g_strdup (SAVE_PROC));
+ list = g_list_append (list, g_strdup (SAVE_CUR_PROC));
return list;
}
@@ -143,6 +155,36 @@ ico_create_procedure (GimpPlugIn *plug_in,
gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
"0,string,\\000\\001\\000\\000,0,string,\\000\\002\\000\\000");
+ gimp_load_procedure_set_thumbnail_loader (GIMP_LOAD_PROCEDURE (procedure),
+ LOAD_THUMB_PROC);
+ }
+ else if (! strcmp (name, LOAD_CUR_PROC))
+ {
+ procedure = gimp_load_procedure_new (plug_in, name,
+ GIMP_PDB_PROC_TYPE_PLUGIN,
+ ico_load, NULL, NULL);
+
+ gimp_procedure_set_menu_label (procedure, N_("Microsoft Windows cursor"));
+ gimp_procedure_set_icon_name (procedure, GIMP_ICON_BRUSH);
+
+ gimp_procedure_set_documentation (procedure,
+ "Loads files of Windows CUR file format",
+ "Loads files of Windows CUR file format",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Christian Kreibich <christian whoop org>, "
+ "Nikc M.",
+ "Christian Kreibich <christian whoop org>, "
+ "Nikc M.",
+ "2002-2022");
+
+ gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+ "image/vnd.microsoft.icon");
+ gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+ "cur");
+ gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
+ "0,string,\\000\\001\\000\\000,0,string,\\000\\002\\000\\000");
+
gimp_load_procedure_set_thumbnail_loader (GIMP_LOAD_PROCEDURE (procedure),
LOAD_THUMB_PROC);
}
@@ -153,7 +195,7 @@ ico_create_procedure (GimpPlugIn *plug_in,
ico_load_thumb, NULL, NULL);
gimp_procedure_set_documentation (procedure,
- "Loads a preview from an Windows ICO file",
+ "Loads a preview from a Windows ICO or CUR files",
"",
name);
gimp_procedure_set_attribution (procedure,
@@ -186,6 +228,45 @@ ico_create_procedure (GimpPlugIn *plug_in,
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"ico");
}
+ else if (! strcmp (name, SAVE_CUR_PROC))
+ {
+ procedure = gimp_save_procedure_new (plug_in, name,
+ GIMP_PDB_PROC_TYPE_PLUGIN,
+ cur_save, NULL, NULL);
+
+ gimp_procedure_set_image_types (procedure, "*");
+
+ gimp_procedure_set_menu_label (procedure, N_("Microsoft Windows cursor"));
+ gimp_procedure_set_icon_name (procedure, GIMP_ICON_BRUSH);
+
+ gimp_procedure_set_documentation (procedure,
+ "Saves files in Windows CUR file format",
+ "Saves files in Windows CUR file format",
+ name);
+ gimp_procedure_set_attribution (procedure,
+ "Christian Kreibich <christian whoop org>, "
+ "Nikc M.",
+ "Christian Kreibich <christian whoop org>, "
+ "Nikc M.",
+ "2002-2022");
+
+ gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
+ "image/vnd.microsoft.icon");
+ gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
+ "cur");
+
+ GIMP_PROC_ARG_INT (procedure, "hot-spot-x",
+ "Hot spot X",
+ "X coordinate of hot spot",
+ 0, G_MAXUINT16, 0,
+ G_PARAM_READWRITE);
+
+ GIMP_PROC_ARG_INT (procedure, "hot-spot-y",
+ "Hot spot Y",
+ "Y coordinate of hot spot",
+ 0, G_MAXUINT16, 0,
+ G_PARAM_READWRITE);
+ }
return procedure;
}
@@ -281,6 +362,41 @@ ico_save (GimpProcedure *procedure,
return gimp_procedure_new_return_values (procedure, status, error);
}
+static GimpValueArray *
+cur_save (GimpProcedure *procedure,
+ GimpRunMode run_mode,
+ GimpImage *image,
+ gint n_drawables,
+ GimpDrawable **drawables,
+ GFile *file,
+ const GimpValueArray *args,
+ gpointer run_data)
+{
+ GimpProcedureConfig *config;
+ GimpPDBStatusType status;
+ GError *error = NULL;
+ gint hot_spot_x = 0;
+ gint hot_spot_y = 0;
+
+ INIT_I18N ();
+ gegl_init (NULL, NULL);
+
+ config = gimp_procedure_create_config (procedure);
+ gimp_procedure_config_begin_run (config, image, run_mode, args);
+
+ g_object_get (config,
+ "hot-spot-x", &hot_spot_x,
+ "hot-spot-y", &hot_spot_y,
+ NULL);
+
+ status = cur_save_image (file, image, run_mode, hot_spot_x, hot_spot_y, &error);
+
+ gimp_procedure_config_end_run (config, status);
+ g_object_unref (config);
+
+ return gimp_procedure_new_return_values (procedure, status, error);
+}
+
gint
ico_rowstride (gint width,
gint bpp)
diff --git a/plug-ins/file-ico/ico.h b/plug-ins/file-ico/ico.h
index 39374a059c..972dd19ceb 100644
--- a/plug-ins/file-ico/ico.h
+++ b/plug-ins/file-ico/ico.h
@@ -80,6 +80,7 @@ typedef struct _IcoLoadInfo
guint width;
guint height;
gint bpp;
+ gint planes;
gint offset;
gint size;
} IcoLoadInfo;
@@ -91,6 +92,9 @@ typedef struct _IcoSaveInfo
gboolean *compress;
GList *layers;
gint num_icons;
+ gboolean is_cursor;
+ gint hot_spot_x;
+ gint hot_spot_y;
} IcoSaveInfo;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]