2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2004-04-16 02:39:48 +08:00
|
|
|
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* GIMP Plug-in for Windows Icon files.
|
|
|
|
* Copyright (C) 2002 Christian Kreibich <christian@whoop.org>.
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2004-04-16 02:39:48 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2004-04-16 02:39:48 +08:00
|
|
|
* (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
|
2018-07-12 05:27:07 +08:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2004-04-16 02:39:48 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include <libgimp/gimpui.h>
|
|
|
|
|
|
|
|
/* #define ICO_DBG */
|
|
|
|
|
2008-03-25 04:18:06 +08:00
|
|
|
#include "ico.h"
|
|
|
|
#include "ico-load.h"
|
|
|
|
#include "ico-save.h"
|
2004-04-16 02:39:48 +08:00
|
|
|
|
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
2006-06-27 20:19:57 +08:00
|
|
|
#define LOAD_PROC "file-ico-load"
|
|
|
|
#define LOAD_THUMB_PROC "file-ico-load-thumb"
|
|
|
|
#define SAVE_PROC "file-ico-save"
|
|
|
|
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
typedef struct _Ico Ico;
|
|
|
|
typedef struct _IcoClass IcoClass;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
struct _Ico
|
|
|
|
{
|
|
|
|
GimpPlugIn parent_instance;
|
|
|
|
};
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
struct _IcoClass
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2019-08-14 06:06:22 +08:00
|
|
|
GimpPlugInClass parent_class;
|
2004-04-16 02:39:48 +08:00
|
|
|
};
|
|
|
|
|
2004-11-10 22:44:58 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
#define ICO_TYPE (ico_get_type ())
|
|
|
|
#define ICO (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICO_TYPE, Ico))
|
|
|
|
|
|
|
|
GType ico_get_type (void) G_GNUC_CONST;
|
|
|
|
|
|
|
|
static GList * ico_query_procedures (GimpPlugIn *plug_in);
|
|
|
|
static GimpProcedure * ico_create_procedure (GimpPlugIn *plug_in,
|
|
|
|
const gchar *name);
|
|
|
|
|
|
|
|
static GimpValueArray * ico_load (GimpProcedure *procedure,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GFile *file,
|
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data);
|
|
|
|
static GimpValueArray * ico_load_thumb (GimpProcedure *procedure,
|
2019-08-19 20:04:00 +08:00
|
|
|
GFile *file,
|
|
|
|
gint size,
|
2019-08-14 06:06:22 +08:00
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data);
|
|
|
|
static GimpValueArray * ico_save (GimpProcedure *procedure,
|
|
|
|
GimpRunMode run_mode,
|
2019-08-14 21:11:25 +08:00
|
|
|
GimpImage *image,
|
|
|
|
GimpDrawable *drawable,
|
2019-08-14 06:06:22 +08:00
|
|
|
GFile *file,
|
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data);
|
|
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (Ico, ico, GIMP_TYPE_PLUG_IN)
|
|
|
|
|
|
|
|
GIMP_MAIN (ICO_TYPE)
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2004-11-10 22:44:58 +08:00
|
|
|
|
2004-04-16 02:39:48 +08:00
|
|
|
static void
|
2019-08-14 06:06:22 +08:00
|
|
|
ico_class_init (IcoClass *klass)
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2019-08-14 06:06:22 +08:00
|
|
|
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
|
|
|
|
|
|
|
|
plug_in_class->query_procedures = ico_query_procedures;
|
|
|
|
plug_in_class->create_procedure = ico_create_procedure;
|
2004-04-16 02:39:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-08-14 06:06:22 +08:00
|
|
|
ico_init (Ico *ico)
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2019-08-14 06:06:22 +08:00
|
|
|
}
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
static GList *
|
|
|
|
ico_query_procedures (GimpPlugIn *plug_in)
|
|
|
|
{
|
|
|
|
GList *list = NULL;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
list = g_list_append (list, g_strdup (LOAD_PROC));
|
|
|
|
list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
|
|
|
|
list = g_list_append (list, g_strdup (SAVE_PROC));
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
return list;
|
|
|
|
}
|
2012-11-30 08:38:23 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
static GimpProcedure *
|
|
|
|
ico_create_procedure (GimpPlugIn *plug_in,
|
|
|
|
const gchar *name)
|
|
|
|
{
|
|
|
|
GimpProcedure *procedure = NULL;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
if (! strcmp (name, LOAD_PROC))
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2019-08-30 18:52:28 +08:00
|
|
|
procedure = gimp_load_procedure_new (plug_in, name,
|
|
|
|
GIMP_PDB_PROC_TYPE_PLUGIN,
|
2019-08-14 06:06:22 +08:00
|
|
|
ico_load, NULL, NULL);
|
|
|
|
|
|
|
|
gimp_procedure_set_menu_label (procedure, N_("Microsoft Windows icon"));
|
2019-08-18 19:45:58 +08:00
|
|
|
gimp_procedure_set_icon_name (procedure, GIMP_ICON_BRUSH);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
|
|
|
gimp_procedure_set_documentation (procedure,
|
|
|
|
"Loads files of Windows ICO file format",
|
|
|
|
"Loads files of Windows ICO file format",
|
|
|
|
name);
|
|
|
|
gimp_procedure_set_attribution (procedure,
|
|
|
|
"Christian Kreibich <christian@whoop.org>",
|
|
|
|
"Christian Kreibich <christian@whoop.org>",
|
|
|
|
"2002");
|
|
|
|
|
|
|
|
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
|
|
|
|
"image/x-ico");
|
|
|
|
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
|
|
|
|
"ico");
|
|
|
|
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);
|
2004-04-16 02:39:48 +08:00
|
|
|
}
|
2019-08-14 06:06:22 +08:00
|
|
|
else if (! strcmp (name, LOAD_THUMB_PROC))
|
2005-05-07 08:06:33 +08:00
|
|
|
{
|
2019-08-30 18:52:28 +08:00
|
|
|
procedure = gimp_thumbnail_procedure_new (plug_in, name,
|
|
|
|
GIMP_PDB_PROC_TYPE_PLUGIN,
|
2019-08-19 20:04:00 +08:00
|
|
|
ico_load_thumb, NULL, NULL);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
|
|
|
gimp_procedure_set_documentation (procedure,
|
|
|
|
"Loads a preview from an Windows ICO file",
|
|
|
|
"",
|
|
|
|
name);
|
|
|
|
gimp_procedure_set_attribution (procedure,
|
|
|
|
"Dom Lachowicz, Sven Neumann",
|
|
|
|
"Sven Neumann <sven@gimp.org>",
|
|
|
|
"2005");
|
2005-05-07 08:06:33 +08:00
|
|
|
}
|
2019-08-14 06:06:22 +08:00
|
|
|
else if (! strcmp (name, SAVE_PROC))
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2019-08-30 18:52:28 +08:00
|
|
|
procedure = gimp_save_procedure_new (plug_in, name,
|
|
|
|
GIMP_PDB_PROC_TYPE_PLUGIN,
|
2019-08-14 06:06:22 +08:00
|
|
|
ico_save, NULL, NULL);
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
gimp_procedure_set_image_types (procedure, "*");
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
gimp_procedure_set_menu_label (procedure, N_("Microsoft Windows icon"));
|
2019-08-18 19:45:58 +08:00
|
|
|
gimp_procedure_set_icon_name (procedure, GIMP_ICON_BRUSH);
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
gimp_procedure_set_documentation (procedure,
|
|
|
|
"Saves files in Windows ICO file format",
|
|
|
|
"Saves files in Windows ICO file format",
|
|
|
|
name);
|
|
|
|
gimp_procedure_set_attribution (procedure,
|
|
|
|
"Christian Kreibich <christian@whoop.org>",
|
|
|
|
"Christian Kreibich <christian@whoop.org>",
|
|
|
|
"2002");
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
|
|
|
|
"image/x-ico");
|
|
|
|
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
|
|
|
|
"ico");
|
|
|
|
}
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
return procedure;
|
|
|
|
}
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
static GimpValueArray *
|
|
|
|
ico_load (GimpProcedure *procedure,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GFile *file,
|
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data)
|
|
|
|
{
|
|
|
|
GimpValueArray *return_vals;
|
|
|
|
gchar *filename;
|
2019-08-14 21:11:25 +08:00
|
|
|
GimpImage *image;
|
2019-08-14 06:06:22 +08:00
|
|
|
GError *error = NULL;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
INIT_I18N ();
|
|
|
|
gegl_init (NULL, NULL);
|
2008-08-20 14:15:35 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
filename = g_file_get_path (file);
|
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
image = ico_load_image (filename, &error);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
|
|
|
g_free (filename);
|
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
if (! image)
|
2019-08-14 06:06:22 +08:00
|
|
|
return gimp_procedure_new_return_values (procedure,
|
|
|
|
GIMP_PDB_EXECUTION_ERROR,
|
|
|
|
error);
|
|
|
|
|
|
|
|
return_vals = gimp_procedure_new_return_values (procedure,
|
|
|
|
GIMP_PDB_SUCCESS,
|
|
|
|
NULL);
|
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
|
|
|
return return_vals;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GimpValueArray *
|
|
|
|
ico_load_thumb (GimpProcedure *procedure,
|
2019-08-19 20:04:00 +08:00
|
|
|
GFile *file,
|
|
|
|
gint size,
|
2019-08-14 06:06:22 +08:00
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data)
|
|
|
|
{
|
|
|
|
GimpValueArray *return_vals;
|
2019-08-19 20:04:00 +08:00
|
|
|
gchar *filename;
|
2019-08-14 06:06:22 +08:00
|
|
|
gint width;
|
|
|
|
gint height;
|
2019-08-14 21:11:25 +08:00
|
|
|
GimpImage *image;
|
2019-08-14 06:06:22 +08:00
|
|
|
GError *error = NULL;
|
2019-08-19 20:04:00 +08:00
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
INIT_I18N ();
|
|
|
|
gegl_init (NULL, NULL);
|
|
|
|
|
2019-08-19 20:04:00 +08:00
|
|
|
filename = g_file_get_path (file);
|
|
|
|
width = size;
|
|
|
|
height = size;
|
2019-08-14 06:06:22 +08:00
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
image = ico_load_thumbnail_image (filename,
|
|
|
|
&width, &height, &error);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
if (image)
|
2019-08-14 06:06:22 +08:00
|
|
|
return gimp_procedure_new_return_values (procedure,
|
|
|
|
GIMP_PDB_EXECUTION_ERROR,
|
|
|
|
error);
|
|
|
|
|
|
|
|
return_vals = gimp_procedure_new_return_values (procedure,
|
|
|
|
GIMP_PDB_SUCCESS,
|
|
|
|
NULL);
|
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
|
2019-08-20 07:03:38 +08:00
|
|
|
GIMP_VALUES_SET_INT (return_vals, 2, width);
|
|
|
|
GIMP_VALUES_SET_INT (return_vals, 3, height);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
2019-08-19 20:04:00 +08:00
|
|
|
gimp_value_array_truncate (return_vals, 4);
|
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
return return_vals;
|
2004-04-16 02:39:48 +08:00
|
|
|
}
|
|
|
|
|
2019-08-14 06:06:22 +08:00
|
|
|
static GimpValueArray *
|
|
|
|
ico_save (GimpProcedure *procedure,
|
|
|
|
GimpRunMode run_mode,
|
2019-08-14 21:11:25 +08:00
|
|
|
GimpImage *image,
|
|
|
|
GimpDrawable *drawable,
|
2019-08-14 06:06:22 +08:00
|
|
|
GFile *file,
|
|
|
|
const GimpValueArray *args,
|
|
|
|
gpointer run_data)
|
|
|
|
{
|
|
|
|
GimpPDBStatusType status;
|
|
|
|
gchar *filename;
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
INIT_I18N ();
|
|
|
|
gegl_init (NULL, NULL);
|
|
|
|
|
|
|
|
filename = g_file_get_path (file);
|
|
|
|
|
2019-08-14 21:11:25 +08:00
|
|
|
status = ico_save_image (filename, image, run_mode, &error);
|
2019-08-14 06:06:22 +08:00
|
|
|
|
|
|
|
g_free (filename);
|
|
|
|
|
|
|
|
return gimp_procedure_new_return_values (procedure, status, error);
|
|
|
|
}
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
gint
|
|
|
|
ico_rowstride (gint width,
|
|
|
|
gint bpp)
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
|
|
|
switch (bpp)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
if ((width % 32) == 0)
|
2006-10-06 14:42:09 +08:00
|
|
|
return width / 8;
|
2004-04-16 02:39:48 +08:00
|
|
|
else
|
2006-10-06 14:42:09 +08:00
|
|
|
return 4 * (width/32 + 1);
|
2004-04-16 02:39:48 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
if ((width % 8) == 0)
|
2006-10-06 14:42:09 +08:00
|
|
|
return width / 2;
|
2004-04-16 02:39:48 +08:00
|
|
|
else
|
2006-10-06 14:42:09 +08:00
|
|
|
return 4 * (width/8 + 1);
|
2004-04-16 02:39:48 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
if ((width % 4) == 0)
|
2006-10-06 14:42:09 +08:00
|
|
|
return width;
|
2004-04-16 02:39:48 +08:00
|
|
|
else
|
2006-10-06 14:42:09 +08:00
|
|
|
return 4 * (width/4 + 1);
|
2004-04-16 02:39:48 +08:00
|
|
|
break;
|
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
case 24:
|
|
|
|
if (((width*3) % 4) == 0)
|
|
|
|
return width * 3;
|
|
|
|
else
|
|
|
|
return 4 * (width*3/4+1);
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
case 32:
|
|
|
|
return width * 4;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
default:
|
|
|
|
g_warning ("invalid bitrate: %d\n", bpp);
|
|
|
|
g_assert_not_reached ();
|
|
|
|
return width * (bpp/8);
|
|
|
|
}
|
2004-04-16 02:39:48 +08:00
|
|
|
}
|
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
guint8 *
|
|
|
|
ico_alloc_map (gint width,
|
|
|
|
gint height,
|
|
|
|
gint bpp,
|
|
|
|
gint *length)
|
2004-04-16 02:39:48 +08:00
|
|
|
{
|
2006-10-06 14:42:09 +08:00
|
|
|
gint len = 0;
|
|
|
|
guint8 *map = NULL;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
len = ico_rowstride (width, bpp) * height;
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
*length = len;
|
|
|
|
map = g_new0 (guint8, len);
|
2004-04-16 02:39:48 +08:00
|
|
|
|
2006-10-06 14:42:09 +08:00
|
|
|
return map;
|
2004-04-16 02:39:48 +08:00
|
|
|
}
|