Commit b62ca985 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

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.
parent 4a0f6aa7
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
......
......@@ -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);
}
......@@ -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);
/* clear all undo steps */
gimp_image_undo_free (gimage);
GimpImage *gimage = gimp_image_get_by_ID (gimp, image_id);
/* 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));
}
......@@ -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,
......
......@@ -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 } }
};
......@@ -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);
}
......
......@@ -51,6 +51,7 @@ struct _PlugInProcDef
GSList *extensions_list;
GSList *prefixes_list;
GSList *magics_list;
gchar *thumb_loader;
};
......
......@@ -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);
......
......@@ -514,6 +514,39 @@ plug_ins_file_register_mime (Gimp *gimp,
return NULL;
}