app/plug-in/plug-in-proc-def.[ch] app/plug-in/plug-in-rc.c allow to

2004-11-13  Sven Neumann  <sven@gimp.org>

	* app/plug-in/plug-in-proc-def.[ch]
	* app/plug-in/plug-in-rc.c
	* app/plug-in/plug-ins.[ch]: allow to associate a procedure for
	thumbnail loading with any file load procedure.

	* tools/pdbgen/pdb/fileops.pdb: export this functionality to the
	PDB as gimp_register_thumbnail_loader().

	* app/pdb/fileops_cmds.c
	* app/pdb/internal_procs.c
	* libgimp/gimpfileops_pdb.[ch]: regenerated.

	* app/core/gimpimagefile.c
	* app/file/file-open.[ch]: when creating a thumbnail for an image
	file, use a thumbnail load procedure if available.

	* plug-ins/common/svg.c: added "file_svg_load_thumb", a procedure
	that allows to load a small preview of the SVG image.
This commit is contained in:
Sven Neumann 2004-11-13 17:06:06 +00:00 committed by Sven Neumann
parent 4a0f6aa775
commit b62ca985aa
24 changed files with 612 additions and 122 deletions

View File

@ -1,3 +1,24 @@
2004-11-13 Sven Neumann <sven@gimp.org>
* app/plug-in/plug-in-proc-def.[ch]
* app/plug-in/plug-in-rc.c
* app/plug-in/plug-ins.[ch]: allow to associate a procedure for
thumbnail loading with any file load procedure.
* tools/pdbgen/pdb/fileops.pdb: export this functionality to the
PDB as gimp_register_thumbnail_loader().
* app/pdb/fileops_cmds.c
* app/pdb/internal_procs.c
* libgimp/gimpfileops_pdb.[ch]: regenerated.
* app/core/gimpimagefile.c
* app/file/file-open.[ch]: when creating a thumbnail for an image
file, use a thumbnail load procedure if available.
* plug-ins/common/svg.c: added "file_svg_load_thumb", a procedure
that allows to load a small preview of the SVG image.
2004-11-13 DindinX <dindinx@gimp.org>
* app/actions/layers-actions.c: added back <control>H as a shortcut

View File

@ -78,6 +78,15 @@ static gboolean gimp_imagefile_save_thumb (GimpImagefile *imagefile,
static gchar * gimp_imagefile_get_description (GimpViewable *viewable,
gchar **tooltip);
static void gimp_thumbnail_set_info_from_image (GimpThumbnail *thumbnail,
const gchar *mime_type,
GimpImage *image);
static void gimp_thumbnail_set_info (GimpThumbnail *thumbnail,
const gchar *mime_type,
gint width,
gint height);
static guint gimp_imagefile_signals[LAST_SIGNAL] = { 0 };
@ -253,34 +262,46 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
if (gimp_thumbnail_peek_image (thumbnail) >= GIMP_THUMB_STATE_EXISTS)
{
GimpImage *gimage;
GimpPDBStatusType dummy;
gboolean success;
const gchar *mime_type = NULL;
GError *error = NULL;
GimpImage *image;
gboolean success;
gint width = 0;
gint height = 0;
const gchar *mime_type = NULL;
GError *error = NULL;
g_object_ref (imagefile);
gimage = file_open_image (imagefile->gimp, context, progress,
thumbnail->image_uri,
thumbnail->image_uri,
NULL,
GIMP_RUN_NONINTERACTIVE,
&dummy,
&mime_type,
NULL);
image = file_open_thumbnail (imagefile->gimp, context, progress,
thumbnail->image_uri, size,
&mime_type, &width, &height);
if (gimage)
if (image)
{
if (mime_type)
g_object_set (thumbnail,
"image-mimetype", mime_type,
NULL);
gimp_thumbnail_set_info (imagefile->thumbnail,
mime_type, width, height);
}
else
{
GimpPDBStatusType status;
image = file_open_image (imagefile->gimp, context, progress,
thumbnail->image_uri, thumbnail->image_uri,
NULL, GIMP_RUN_NONINTERACTIVE,
&status, &mime_type, NULL);
if (image)
gimp_thumbnail_set_info_from_image (imagefile->thumbnail,
mime_type, image);
}
if (image)
{
success = gimp_imagefile_save_thumb (imagefile,
gimage, size, replace, &error);
image, size, replace,
&error);
g_object_unref (gimage);
g_object_unref (image);
}
else
{
@ -386,13 +407,11 @@ gimp_imagefile_save_thumbnail (GimpImagefile *imagefile,
if (size > 0)
{
/* peek the thumbnail to make sure that mtime and filesize are set */
gimp_thumbnail_peek_image (imagefile->thumbnail);
gimp_thumbnail_set_info_from_image (imagefile->thumbnail, NULL, gimage);
success = gimp_imagefile_save_thumb (imagefile,
gimage, size, FALSE,
&error);
if (! success)
{
g_message (error->message);
@ -719,9 +738,6 @@ gimp_imagefile_save_thumb (GimpImagefile *imagefile,
{
GimpThumbnail *thumbnail = imagefile->thumbnail;
GdkPixbuf *pixbuf;
GimpEnumDesc *enum_desc;
GimpImageType type;
gint num_layers;
gint width, height;
gboolean success = FALSE;
@ -755,24 +771,6 @@ gimp_imagefile_save_thumb (GimpImagefile *imagefile,
if (! pixbuf)
return TRUE;
type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (gimp_image_base_type (gimage));
if (gimp_image_has_alpha (gimage))
type = GIMP_IMAGE_TYPE_WITH_ALPHA (type);
enum_desc = gimp_enum_get_desc (g_type_class_peek (GIMP_TYPE_IMAGE_TYPE),
type);
num_layers = gimp_container_num_children (gimage->layers);
g_object_set (thumbnail,
"image-width", gimage->width,
"image-height", gimage->height,
"image-type", enum_desc->value_desc,
"image-num-layers", num_layers,
NULL);
success = gimp_thumbnail_save_thumb (thumbnail,
pixbuf,
"The GIMP " GIMP_VERSION,
@ -792,3 +790,48 @@ gimp_imagefile_save_thumb (GimpImagefile *imagefile,
return success;
}
static void
gimp_thumbnail_set_info_from_image (GimpThumbnail *thumbnail,
const gchar *mime_type,
GimpImage *image)
{
GimpEnumDesc *desc;
GimpImageType type;
/* peek the thumbnail to make sure that mtime and filesize are set */
gimp_thumbnail_peek_image (thumbnail);
type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (gimp_image_base_type (image));
if (gimp_image_has_alpha (image))
type = GIMP_IMAGE_TYPE_WITH_ALPHA (type);
desc = gimp_enum_get_desc (g_type_class_peek (GIMP_TYPE_IMAGE_TYPE), type);
g_object_set (thumbnail,
"image-mimetype", mime_type,
"image-width", gimp_image_get_width (image),
"image-height", gimp_image_get_height (image),
"image-type", desc->value_desc,
"image-num-layers", gimp_container_num_children (image->layers),
NULL);
}
static void
gimp_thumbnail_set_info (GimpThumbnail *thumbnail,
const gchar *mime_type,
gint width,
gint height)
{
/* peek the thumbnail to make sure that mtime and filesize are set */
gimp_thumbnail_peek_image (thumbnail);
g_object_set (thumbnail,
"image-mimetype", mime_type,
"image-width", width,
"image-height", height,
"image-type", NULL,
"image-num-layers", NULL,
NULL);
}

View File

@ -64,6 +64,9 @@
#include "gimp-intl.h"
static void file_open_sanitize_image (GimpImage *gimage);
/* public functions */
GimpImage *
@ -81,7 +84,7 @@ file_open_image (Gimp *gimp,
const ProcRecord *proc;
Argument *args;
Argument *return_vals;
gint gimage_id;
gint image_id;
gint i;
gchar *filename;
@ -89,7 +92,6 @@ file_open_image (Gimp *gimp,
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
g_return_val_if_fail (status != NULL, NULL);
g_return_val_if_fail (mime_type == NULL || *mime_type == NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
*status = GIMP_PDB_EXECUTION_ERROR;
@ -146,31 +148,19 @@ file_open_image (Gimp *gimp,
if (filename)
g_free (filename);
*status = return_vals[0].value.pdb_int;
gimage_id = return_vals[1].value.pdb_int;
*status = return_vals[0].value.pdb_int;
image_id = return_vals[1].value.pdb_int;
procedural_db_destroy_args (return_vals, proc->num_values);
g_free (args);
if (*status == GIMP_PDB_SUCCESS)
{
if (gimage_id != -1)
if (image_id != -1)
{
GimpImage *gimage = gimp_image_get_by_ID (gimp, gimage_id);
GimpImage *gimage = gimp_image_get_by_ID (gimp, image_id);
/* clear all undo steps */
gimp_image_undo_free (gimage);
/* make sure that undo is enabled */
while (gimage->undo_freeze_count)
gimp_image_undo_thaw (gimage);
/* set the image to clean */
gimp_image_clean_all (gimage);
gimp_image_invalidate_layer_previews (gimage);
gimp_image_invalidate_channel_previews (gimage);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
file_open_sanitize_image (gimage);
if (mime_type)
*mime_type = file_proc->mime_type;
@ -194,6 +184,88 @@ file_open_image (Gimp *gimp,
return NULL;
}
/* Attempts to load a thumbnail by using a registered thumbnail loader. */
GimpImage *
file_open_thumbnail (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
gint size,
const gchar **mime_type,
gint *image_width,
gint *image_height)
{
PlugInProcDef *file_proc;
const ProcRecord *proc;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
g_return_val_if_fail (mime_type != NULL, NULL);
g_return_val_if_fail (image_width != NULL, NULL);
g_return_val_if_fail (image_height != NULL, NULL);
*image_width = 0;
*image_height = 0;
file_proc = file_utils_find_proc (gimp->load_procs, uri);
if (! file_proc || ! file_proc->thumb_loader)
return NULL;
proc = procedural_db_lookup (gimp, file_proc->thumb_loader);
if (proc && proc->num_args >= 2)
{
GimpPDBStatusType status;
Argument *args;
Argument *return_vals;
gchar *filename;
gint image_id;
gint i;
filename = g_filename_from_uri (uri, NULL, NULL);
args = g_new0 (Argument, proc->num_args);
for (i = 0; i < proc->num_args; i++)
args[i].arg_type = proc->args[i].arg_type;
args[0].value.pdb_pointer = filename ? filename : (gchar *) uri;
args[1].value.pdb_int = size;
return_vals = procedural_db_execute (gimp, context, progress,
proc->name, args);
if (filename)
g_free (filename);
status = return_vals[0].value.pdb_int;
image_id = return_vals[1].value.pdb_int;
*image_width = MAX (0, return_vals[2].value.pdb_int);
*image_height = MAX (0, return_vals[3].value.pdb_int);
procedural_db_destroy_args (return_vals, proc->num_values);
g_free (args);
if (status == GIMP_PDB_SUCCESS && image_id != -1)
{
GimpImage *image = gimp_image_get_by_ID (gimp, image_id);
file_open_sanitize_image (image);
*mime_type = file_proc->mime_type;
g_printerr ("opened thumbnail at %d x %d\n",
image->width, image->height);
return image;
}
}
return NULL;
}
GimpImage *
file_open_with_display (Gimp *gimp,
GimpContext *context,
@ -347,3 +419,24 @@ file_open_layer (Gimp *gimp,
return new_layer;
}
/* private functions */
static void
file_open_sanitize_image (GimpImage *gimage)
{
/* clear all undo steps */
gimp_image_undo_free (gimage);
/* make sure that undo is enabled */
while (gimage->undo_freeze_count)
gimp_image_undo_thaw (gimage);
/* set the image to clean */
gimp_image_clean_all (gimage);
gimp_image_invalidate_layer_previews (gimage);
gimp_image_invalidate_channel_previews (gimage);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
}

View File

@ -33,6 +33,14 @@ GimpImage * file_open_image (Gimp *gimp,
const gchar **mime_type,
GError **error);
GimpImage * file_open_thumbnail (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
gint size,
const gchar **mime_type,
gint *image_width,
gint *image_height);
GimpImage * file_open_with_display (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,

View File

@ -63,6 +63,7 @@ static ProcRecord register_magic_load_handler_proc;
static ProcRecord register_load_handler_proc;
static ProcRecord register_save_handler_proc;
static ProcRecord register_file_handler_mime_proc;
static ProcRecord register_thumbnail_loader_proc;
void
register_fileops_procs (Gimp *gimp)
@ -76,6 +77,7 @@ register_fileops_procs (Gimp *gimp)
procedural_db_register (gimp, &register_load_handler_proc);
procedural_db_register (gimp, &register_save_handler_proc);
procedural_db_register (gimp, &register_file_handler_mime_proc);
procedural_db_register (gimp, &register_thumbnail_loader_proc);
}
static Argument *
@ -861,3 +863,62 @@ static ProcRecord register_file_handler_mime_proc =
NULL,
{ { register_file_handler_mime_invoker } }
};
static Argument *
register_thumbnail_loader_invoker (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
Argument *args)
{
gboolean success = TRUE;
gchar *load_proc;
gchar *thumb_proc;
load_proc = (gchar *) args[0].value.pdb_pointer;
if (load_proc == NULL || !g_utf8_validate (load_proc, -1, NULL))
success = FALSE;
thumb_proc = (gchar *) args[1].value.pdb_pointer;
if (thumb_proc == NULL || !g_utf8_validate (thumb_proc, -1, NULL))
success = FALSE;
if (success)
{
success = (plug_ins_file_register_thumb_loader (gimp,
load_proc,
thumb_proc) != NULL);
}
return procedural_db_return_args (&register_thumbnail_loader_proc, success);
}
static ProcArg register_thumbnail_loader_inargs[] =
{
{
GIMP_PDB_STRING,
"load_proc",
"The name of the procedure the thumbnail loader with."
},
{
GIMP_PDB_STRING,
"thumb_proc",
"The name of the thumbnail load procedure."
}
};
static ProcRecord register_thumbnail_loader_proc =
{
"gimp_register_thumbnail_loader",
"Associates a thumbnail loader with a file load procedure.",
"Some file formats allow for embedded thumbnails, other file formats contain a scalable image or provide the image data in different resolutions. A file plug-in for such a format may register a special procedure that allows GIMP to load a thumbnail preview of the image. This procedure is then associated with the standard load procedure using this function.",
"Sven Neumann",
"Sven Neumann",
"2004",
NULL,
GIMP_INTERNAL,
2,
register_thumbnail_loader_inargs,
0,
NULL,
{ { register_thumbnail_loader_invoker } }
};

View File

@ -100,6 +100,8 @@ plug_in_proc_def_free (PlugInProcDef *proc_def)
g_slist_foreach (proc_def->magics_list, (GFunc) g_free, NULL);
g_slist_free (proc_def->magics_list);
g_free (proc_def->thumb_loader);
g_free (proc_def);
}

View File

@ -51,6 +51,7 @@ struct _PlugInProcDef
GSList *extensions_list;
GSList *prefixes_list;
GSList *magics_list;
gchar *thumb_loader;
};

View File

@ -74,7 +74,7 @@ void register_transform_tools_procs (Gimp *gimp);
void register_undo_procs (Gimp *gimp);
void register_unit_procs (Gimp *gimp);
/* 433 procedures registered total */
/* 434 procedures registered total */
void
internal_procs_init (Gimp *gimp,
@ -98,7 +98,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Color"), 0.06);
register_color_procs (gimp);
(* status_callback) (NULL, _("Context"), 0.095);
(* status_callback) (NULL, _("Context"), 0.094);
register_context_procs (gimp);
(* status_callback) (NULL, _("Convert"), 0.145);
@ -107,61 +107,61 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Display procedures"), 0.152);
register_display_procs (gimp);
(* status_callback) (NULL, _("Drawable procedures"), 0.162);
(* status_callback) (NULL, _("Drawable procedures"), 0.161);
register_drawable_procs (gimp);
(* status_callback) (NULL, _("Transformation procedures"), 0.238);
(* status_callback) (NULL, _("Transformation procedures"), 0.237);
register_drawable_transform_procs (gimp);
(* status_callback) (NULL, _("Edit procedures"), 0.275);
(* status_callback) (NULL, _("Edit procedures"), 0.274);
register_edit_procs (gimp);
(* status_callback) (NULL, _("File Operations"), 0.293);
register_fileops_procs (gimp);
(* status_callback) (NULL, _("Floating selections"), 0.314);
(* status_callback) (NULL, _("Floating selections"), 0.316);
register_floating_sel_procs (gimp);
(* status_callback) (NULL, _("Font UI"), 0.328);
(* status_callback) (NULL, _("Font UI"), 0.329);
register_font_select_procs (gimp);
(* status_callback) (NULL, _("Fonts"), 0.335);
(* status_callback) (NULL, _("Fonts"), 0.336);
register_fonts_procs (gimp);
(* status_callback) (NULL, _("Gimprc procedures"), 0.339);
(* status_callback) (NULL, _("Gimprc procedures"), 0.341);
register_gimprc_procs (gimp);
(* status_callback) (NULL, _("Gradient"), 0.353);
(* status_callback) (NULL, _("Gradient"), 0.355);
register_gradient_procs (gimp);
(* status_callback) (NULL, _("Gradient UI"), 0.42);
(* status_callback) (NULL, _("Gradient UI"), 0.422);
register_gradient_select_procs (gimp);
(* status_callback) (NULL, _("Gradients"), 0.427);
(* status_callback) (NULL, _("Gradients"), 0.429);
register_gradients_procs (gimp);
(* status_callback) (NULL, _("Guide procedures"), 0.439);
(* status_callback) (NULL, _("Guide procedures"), 0.44);
register_guides_procs (gimp);
(* status_callback) (NULL, _("Help procedures"), 0.453);
(* status_callback) (NULL, _("Help procedures"), 0.454);
register_help_procs (gimp);
(* status_callback) (NULL, _("Image"), 0.455);
(* status_callback) (NULL, _("Image"), 0.456);
register_image_procs (gimp);
(* status_callback) (NULL, _("Layer"), 0.603);
(* status_callback) (NULL, _("Layer"), 0.604);
register_layer_procs (gimp);
(* status_callback) (NULL, _("Message procedures"), 0.665);
(* status_callback) (NULL, _("Message procedures"), 0.666);
register_message_procs (gimp);
(* status_callback) (NULL, _("Miscellaneous"), 0.672);
(* status_callback) (NULL, _("Miscellaneous"), 0.673);
register_misc_procs (gimp);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.677);
register_paint_tools_procs (gimp);
(* status_callback) (NULL, _("Palette"), 0.711);
(* status_callback) (NULL, _("Palette"), 0.712);
register_palette_procs (gimp);
(* status_callback) (NULL, _("Palette UI"), 0.737);
@ -176,7 +176,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Paths"), 0.781);
register_paths_procs (gimp);
(* status_callback) (NULL, _("Pattern"), 0.815);
(* status_callback) (NULL, _("Pattern"), 0.816);
register_pattern_procs (gimp);
(* status_callback) (NULL, _("Pattern UI"), 0.82);
@ -191,13 +191,13 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Procedural database"), 0.848);
register_procedural_db_procs (gimp);
(* status_callback) (NULL, _("Progress"), 0.868);
(* status_callback) (NULL, _("Progress"), 0.869);
register_progress_procs (gimp);
(* status_callback) (NULL, _("Image mask"), 0.88);
register_selection_procs (gimp);
(* status_callback) (NULL, _("Selection Tool procedures"), 0.921);
(* status_callback) (NULL, _("Selection Tool procedures"), 0.922);
register_selection_tools_procs (gimp);
(* status_callback) (NULL, _("Text procedures"), 0.933);

View File

@ -514,6 +514,39 @@ plug_ins_file_register_mime (Gimp *gimp,
return NULL;
}
PlugInProcDef *
plug_ins_file_register_thumb_loader (Gimp *gimp,
const gchar *load_proc,
const gchar *thumb_proc)
{
GSList *list;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (load_proc, NULL);
g_return_val_if_fail (thumb_proc, NULL);
if (gimp->current_plug_in && gimp->current_plug_in->plug_in_def)
list = gimp->current_plug_in->plug_in_def->proc_defs;
else
list = gimp->plug_in_proc_defs;
for (; list; list = list->next)
{
PlugInProcDef *proc_def = list->data;
if (strcmp (proc_def->db_info.name, load_proc) == 0)
{
if (proc_def->thumb_loader)
g_free (proc_def->thumb_loader);
proc_def->thumb_loader = g_strdup (thumb_proc);
return proc_def;
}
}
return NULL;
}
void
plug_ins_def_add_from_rc (Gimp *gimp,
PlugInDef *plug_in_def)

View File

@ -45,6 +45,12 @@ PlugInProcDef * plug_ins_file_register_mime (Gimp *gimp,
const gchar *name,
const gchar *mime_type);
PlugInProcDef * plug_ins_file_register_thumb_loader
(Gimp *gimp,
const gchar *load_proc,
const gchar *thumb_proc);
/* Add a plug-in definition. */
void plug_ins_def_add_from_rc (Gimp *gimp,
PlugInDef *plug_in_def);

View File

@ -100,6 +100,8 @@ plug_in_proc_def_free (PlugInProcDef *proc_def)
g_slist_foreach (proc_def->magics_list, (GFunc) g_free, NULL);
g_slist_free (proc_def->magics_list);
g_free (proc_def->thumb_loader);
g_free (proc_def);
}

View File

@ -51,6 +51,7 @@ struct _PlugInProcDef
GSList *extensions_list;
GSList *prefixes_list;
GSList *magics_list;
gchar *thumb_loader;
};

View File

@ -100,6 +100,8 @@ plug_in_proc_def_free (PlugInProcDef *proc_def)
g_slist_foreach (proc_def->magics_list, (GFunc) g_free, NULL);
g_slist_free (proc_def->magics_list);
g_free (proc_def->thumb_loader);
g_free (proc_def);
}

View File

@ -51,6 +51,7 @@ struct _PlugInProcDef
GSList *extensions_list;
GSList *prefixes_list;
GSList *magics_list;
gchar *thumb_loader;
};

View File

@ -57,7 +57,7 @@ static GTokenType plug_in_icon_deserialize (GScanner *scanner,
PlugInProcDef *proc_def);
static GTokenType plug_in_proc_arg_deserialize (GScanner *scanner,
ProcArg *arg);
static GTokenType plug_in_mime_type_deserialize (GScanner *scanner,
static GTokenType plug_in_extra_deserialize (GScanner *scanner,
PlugInProcDef *proc_def);
static GTokenType plug_in_locale_def_deserialize (GScanner *scanner,
PlugInDef *plug_in_def);
@ -78,7 +78,8 @@ enum
PROC_ARG,
MENU_PATH,
ICON,
MIME_TYPE
MIME_TYPE,
THUMB_LOADER
};
@ -125,6 +126,8 @@ plug_in_rc_parse (Gimp *gimp,
"icon", GINT_TO_POINTER (ICON));
g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
"mime-type", GINT_TO_POINTER (MIME_TYPE));
g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
"thumb-loader", GINT_TO_POINTER (THUMB_LOADER));
token = G_TOKEN_LEFT_PAREN;
@ -357,13 +360,10 @@ plug_in_proc_def_deserialize (GScanner *scanner,
return token;
}
if (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
{
token = plug_in_mime_type_deserialize (scanner, proc_def);
token = plug_in_extra_deserialize (scanner, proc_def);
if (token != G_TOKEN_LEFT_PAREN)
return token;
}
if (token != G_TOKEN_LEFT_PAREN)
return token;
if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
return G_TOKEN_RIGHT_PAREN;
@ -490,29 +490,50 @@ plug_in_icon_deserialize (GScanner *scanner,
return G_TOKEN_LEFT_PAREN;
}
/* Handle extra info such as mime-type and thumb-loader. */
static GTokenType
plug_in_mime_type_deserialize (GScanner *scanner,
PlugInProcDef *proc_def)
plug_in_extra_deserialize (GScanner *scanner,
PlugInProcDef *proc_def)
{
gchar *mime_type;
GTokenType token;
gchar *value;
if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN))
return G_TOKEN_LEFT_PAREN;
while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
{
token = token = g_scanner_get_next_token (scanner);
if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) ||
GPOINTER_TO_INT (scanner->value.v_symbol) != MIME_TYPE)
return G_TOKEN_SYMBOL;
if (token != G_TOKEN_LEFT_PAREN)
return token;
if (! gimp_scanner_parse_string (scanner, &mime_type))
return G_TOKEN_STRING;
if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL))
return G_TOKEN_SYMBOL;
if (proc_def->mime_type)
g_free (proc_def->mime_type);
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case MIME_TYPE:
if (! gimp_scanner_parse_string (scanner, &value))
return G_TOKEN_STRING;
proc_def->mime_type = mime_type;
g_free (proc_def->mime_type);
proc_def->mime_type = value;
break;
if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
return G_TOKEN_RIGHT_PAREN;
case THUMB_LOADER:
if (! gimp_scanner_parse_string (scanner, &value))
return G_TOKEN_STRING;
g_free (proc_def->thumb_loader);
proc_def->thumb_loader = value;
break;
default:
return G_TOKEN_SYMBOL;
}
if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
return G_TOKEN_RIGHT_PAREN;
}
return G_TOKEN_LEFT_PAREN;
}
@ -752,6 +773,13 @@ plug_in_rc_write (GSList *plug_in_defs,
gimp_config_writer_close (writer);
}
if (proc_def->thumb_loader)
{
gimp_config_writer_open (writer, "thumb-loader");
gimp_config_writer_string (writer, proc_def->thumb_loader);
gimp_config_writer_close (writer);
}
gimp_config_writer_close (writer);
}

View File

@ -514,6 +514,39 @@ plug_ins_file_register_mime (Gimp *gimp,
return NULL;
}
PlugInProcDef *
plug_ins_file_register_thumb_loader (Gimp *gimp,
const gchar *load_proc,
const gchar *thumb_proc)
{
GSList *list;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (load_proc, NULL);
g_return_val_if_fail (thumb_proc, NULL);
if (gimp->current_plug_in && gimp->current_plug_in->plug_in_def)
list = gimp->current_plug_in->plug_in_def->proc_defs;
else
list = gimp->plug_in_proc_defs;
for (; list; list = list->next)
{
PlugInProcDef *proc_def = list->data;
if (strcmp (proc_def->db_info.name, load_proc) == 0)
{
if (proc_def->thumb_loader)
g_free (proc_def->thumb_loader);
proc_def->thumb_loader = g_strdup (thumb_proc);
return proc_def;
}
}
return NULL;
}
void
plug_ins_def_add_from_rc (Gimp *gimp,
PlugInDef *plug_in_def)

View File

@ -45,6 +45,12 @@ PlugInProcDef * plug_ins_file_register_mime (Gimp *gimp,
const gchar *name,
const gchar *mime_type);
PlugInProcDef * plug_ins_file_register_thumb_loader
(Gimp *gimp,
const gchar *load_proc,
const gchar *thumb_proc);
/* Add a plug-in definition. */
void plug_ins_def_add_from_rc (Gimp *gimp,
PlugInDef *plug_in_def);

View File

@ -367,6 +367,7 @@ gimp_register_magic_load_handler
gimp_register_load_handler
gimp_register_save_handler
gimp_register_file_handler_mime
gimp_register_thumbnail_loader
</SECTION>
<SECTION>

View File

@ -92,3 +92,13 @@ File operations (load, save, etc.)
@Returns:
<!-- ##### FUNCTION gimp_register_thumbnail_loader ##### -->
<para>
</para>
@load_proc:
@thumb_proc:
@Returns:

View File

@ -479,6 +479,7 @@ EXPORTS
gimp_register_load_handler
gimp_register_magic_load_handler
gimp_register_save_handler
gimp_register_thumbnail_loader
gimp_repeat_mode_get_type
gimp_rgn_iterate1
gimp_rgn_iterate2

View File

@ -290,3 +290,42 @@ gimp_register_file_handler_mime (const gchar *procedure_name,
return success;
}
/**
* gimp_register_thumbnail_loader:
* @load_proc: The name of the procedure the thumbnail loader with.
* @thumb_proc: The name of the thumbnail load procedure.
*
* Associates a thumbnail loader with a file load procedure.
*
* Some file formats allow for embedded thumbnails, other file formats
* contain a scalable image or provide the image data in different
* resolutions. A file plug-in for such a format may register a special
* procedure that allows GIMP to load a thumbnail preview of the image.
* This procedure is then associated with the standard load procedure
* using this function.
*
* Returns: TRUE on success.
*
* Since: GIMP 2.2
*/
gboolean
gimp_register_thumbnail_loader (const gchar *load_proc,
const gchar *thumb_proc)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp_register_thumbnail_loader",
&nreturn_vals,
GIMP_PDB_STRING, load_proc,
GIMP_PDB_STRING, thumb_proc,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}

View File

@ -50,6 +50,8 @@ gboolean gimp_register_save_handler (const gchar *procedure_name,
const gchar *prefixes);
gboolean gimp_register_file_handler_mime (const gchar *procedure_name,
const gchar *mime_type);
gboolean gimp_register_thumbnail_loader (const gchar *load_proc,
const gchar *thumb_proc);
G_END_DECLS

View File

@ -69,14 +69,14 @@ static void run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals);
static gint32 load_image (const gchar *filename);
static GdkPixbuf * load_rsvg_pixbuf (const gchar *filename,
SvgLoadVals *vals,
GError **error);
static gboolean load_rsvg_size (const gchar *filename,
SvgLoadVals *vals,
GError **error);
static gboolean load_dialog (const gchar *filename);
static gint32 load_image (const gchar *filename);
static GdkPixbuf * load_rsvg_pixbuf (const gchar *filename,
SvgLoadVals *vals,
GError **error);
static gboolean load_rsvg_size (const gchar *filename,
SvgLoadVals *vals,
GError **error);
static gboolean load_dialog (const gchar *filename);
GimpPlugInInfo PLUG_IN_INFO =
@ -115,6 +115,18 @@ query (void)
{ GIMP_PDB_IMAGE, "image", "Output image" }
};
static GimpParamDef thumb_args[] =
{
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
{ GIMP_PDB_INT32, "thumb_size", "Preferred thumbnail size" }
};
static GimpParamDef thumb_return_vals[] =
{
{ GIMP_PDB_IMAGE, "image", "Thumbnail image" },
{ GIMP_PDB_INT32, "image_width", "Width of full-sized image" },
{ GIMP_PDB_INT32, "image_height", "Height of full-sized image" }
};
gimp_install_procedure ("file_svg_load",
"Loads files in the SVG file format",
"Renders SVG files to raster graphics using librsvg.",
@ -132,6 +144,21 @@ query (void)
gimp_register_magic_load_handler ("file_svg_load",
"svg", "",
"0,string,<?xml,0,string,<svg");
gimp_install_procedure ("file_svg_load_thumb",
"Loads a small preview from an SVG image",
"",
"Dom Lachowicz, Sven Neumann",
"Dom Lachowicz <cinamod@hotmail.com>",
SVG_VERSION,
N_("Scalable SVG image"),
NULL,
GIMP_PLUGIN,
G_N_ELEMENTS (thumb_args),
G_N_ELEMENTS (thumb_return_vals),
thumb_args, thumb_return_vals);
gimp_register_thumbnail_loader ("file_svg_load", "file_svg_load_thumb");
}
static void
@ -192,14 +219,13 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS)
{
gint32 image_ID = load_image (param[1].data.d_string);
const gchar *filename = param[1].data.d_string;
gint32 image_ID = load_image (filename);
if (image_ID != -1)
{
if (load_vals.import)
gimp_path_import (image_ID,
param[1].data.d_string,
load_vals.merge, TRUE);
gimp_path_import (image_ID, filename, load_vals.merge, TRUE);
*nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE;
@ -213,6 +239,47 @@ run (const gchar *name,
gimp_set_data ("file_svg_load", &load_vals, sizeof (load_vals));
}
}
else if (strcmp (name, "file_svg_load_thumb") == 0)
{
if (nparams < 2)
{
status = GIMP_PDB_CALLING_ERROR;
}
else
{
const gchar *filename = param[0].data.d_string;
gint width = 0;
gint height = 0;
gint32 image_ID;
if (load_rsvg_size (filename, &load_vals, NULL))
{
width = load_vals.width;
height = load_vals.height;
}
load_vals.resolution = SVG_DEFAULT_RESOLUTION;
load_vals.width = - param[1].data.d_int32;
load_vals.height = - param[1].data.d_int32;
image_ID = load_image (filename);
if (image_ID != -1)
{
*nreturn_vals = 4;
values[1].type = GIMP_PDB_IMAGE;
values[1].data.d_image = image_ID;
values[2].type = GIMP_PDB_INT32;
values[2].data.d_int32 = width;
values[3].type = GIMP_PDB_INT32;
values[3].data.d_int32 = height;
}
else
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
}
else
{
status = GIMP_PDB_CALLING_ERROR;

View File

@ -528,6 +528,34 @@ CODE
);
}
sub register_thumbnail_loader {
$blurb = 'Associates a thumbnail loader with a file load procedure.';
$help = <<'HELP';
Some file formats allow for embedded thumbnails, other file formats contain a scalable image or provide the image data in different resolutions. A file plug-in for such a format may register a special procedure that allows GIMP to load a thumbnail preview of the image. This procedure is then associated with the standard load procedure using this function.
HELP
$author = $copyright = 'Sven Neumann';
$date = '2004';
$since = '2.2';
@inargs = (
{ name => 'load_proc', type => 'string',
desc => "The name of the procedure the thumbnail loader with." },
{ name => 'thumb_proc', type => 'string',
desc => "The name of the thumbnail load procedure." }
);
%invoke = (
code => <<'CODE'
{
success = (plug_ins_file_register_thumb_loader (gimp,
load_proc,
thumb_proc) != NULL);
}
CODE
);
}
@headers = qw(<sys/types.h> <unistd.h> <gdk-pixbuf/gdk-pixbuf.h>
"libgimpbase/gimpbase.h" "libgimpthumb/gimpthumb.h"
"core/gimp.h" "core/gimpimagefile.h"
@ -537,8 +565,9 @@ CODE
@procs = qw(file_load file_save file_load_thumbnail file_save_thumbnail
temp_name register_magic_load_handler register_load_handler
register_save_handler register_file_handler_mime);
%exports = (app => [@procs], lib => [@procs[0,1,4..8]]);
register_save_handler register_file_handler_mime
register_thumbnail_loader);
%exports = (app => [@procs], lib => [@procs[0,1,4..9]]);
$desc = 'File Operations';