Commit 5e75f585 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

added gimp_drawable_sub_thumbnail() to enable plug-ins avoiding

2004-12-14  Michael Natterer  <mitch@gimp.org>

	* tools/pdbgen/pdb/drawable.pdb: added gimp_drawable_sub_thumbnail()
	to enable plug-ins avoiding #142074-alike bugs if they need to.

	* app/pdb/drawable_cmds.c
	* app/pdb/internal_procs.c
	* libgimp/gimpdrawable_pdb.[ch]: regenerated.

	* libgimp/gimpdrawable.[ch]
	* libgimp/gimppixbuf.[ch]: wrap it with the same convenience
	APIs as gimp_drawable_thumbnail().

	* libgimp/gimp.def
	* libgimp/gimpui.def: changed accordingly.
parent 773a9d8f
2004-12-14 Michael Natterer <mitch@gimp.org>
* tools/pdbgen/pdb/drawable.pdb: added gimp_drawable_sub_thumbnail()
to enable plug-ins avoiding #142074-alike bugs if they need to.
* app/pdb/drawable_cmds.c
* app/pdb/internal_procs.c
* libgimp/gimpdrawable_pdb.[ch]: regenerated.
* libgimp/gimpdrawable.[ch]
* libgimp/gimppixbuf.[ch]: wrap it with the same convenience
APIs as gimp_drawable_thumbnail().
* libgimp/gimp.def
* libgimp/gimpui.def: changed accordingly.
2004-12-13 Sven Neumann <sven@gimp.org>
* HACKING
......
......@@ -32,6 +32,7 @@
#include "config/gimpcoreconfig.h"
#include "core/gimp.h"
#include "core/gimpdrawable-offset.h"
#include "core/gimpdrawable-preview.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
......@@ -72,6 +73,7 @@ static ProcRecord drawable_set_pixel_proc;
static ProcRecord drawable_fill_proc;
static ProcRecord drawable_offset_proc;
static ProcRecord drawable_thumbnail_proc;
static ProcRecord drawable_sub_thumbnail_proc;
void
register_drawable_procs (Gimp *gimp)
......@@ -109,6 +111,7 @@ register_drawable_procs (Gimp *gimp)
procedural_db_register (gimp, &drawable_fill_proc);
procedural_db_register (gimp, &drawable_offset_proc);
procedural_db_register (gimp, &drawable_thumbnail_proc);
procedural_db_register (gimp, &drawable_sub_thumbnail_proc);
}
static Argument *
......@@ -2310,3 +2313,189 @@ static ProcRecord drawable_thumbnail_proc =
drawable_thumbnail_outargs,
{ { drawable_thumbnail_invoker } }
};
static Argument *
drawable_sub_thumbnail_invoker (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
Argument *args)
{
gboolean success = TRUE;
Argument *return_args;
GimpDrawable *drawable;
gint32 src_x;
gint32 src_y;
gint32 src_width;
gint32 src_height;
gint32 dest_width;
gint32 dest_height;
gint32 width = 0;
gint32 height = 0;
gint32 bpp = 0;
gint32 num_bytes = 0;
guint8 *thumbnail_data = NULL;
drawable = (GimpDrawable *) gimp_item_get_by_ID (gimp, args[0].value.pdb_int);
if (! (GIMP_IS_DRAWABLE (drawable) && ! gimp_item_is_removed (GIMP_ITEM (drawable))))
success = FALSE;
src_x = args[1].value.pdb_int;
if (src_x < 0)
success = FALSE;
src_y = args[2].value.pdb_int;
if (src_y < 0)
success = FALSE;
src_width = args[3].value.pdb_int;
if (src_width <= 0)
success = FALSE;
src_height = args[4].value.pdb_int;
if (src_height <= 0)
success = FALSE;
dest_width = args[5].value.pdb_int;
if (dest_width <= 0 || dest_width > 512)
success = FALSE;
dest_height = args[6].value.pdb_int;
if (dest_height <= 0 || dest_height > 512)
success = FALSE;
if (success)
{
success = ((src_x + src_width) <= gimp_item_width (GIMP_ITEM (drawable)) &&
(src_y + src_height) <= gimp_item_height (GIMP_ITEM (drawable)));
if (success)
{
GimpImage *gimage = gimp_item_get_image (GIMP_ITEM (drawable));
TempBuf *buf;
if (gimage->gimp->config->layer_previews)
buf = gimp_drawable_get_sub_preview (drawable,
src_x, src_y,
src_width, src_height,
dest_width, dest_height);
else
buf = gimp_viewable_get_dummy_preview (GIMP_VIEWABLE (drawable),
dest_width, dest_height,
gimp_drawable_has_alpha (drawable) ?
4 : 3);
if (buf)
{
num_bytes = buf->height * buf->width * buf->bytes;
thumbnail_data = g_memdup (temp_buf_data (buf), num_bytes);
width = buf->width;
height = buf->height;
bpp = buf->bytes;
temp_buf_free (buf);
}
else
{
success = FALSE;
}
}
}
return_args = procedural_db_return_args (&drawable_sub_thumbnail_proc, success);
if (success)
{
return_args[1].value.pdb_int = width;
return_args[2].value.pdb_int = height;
return_args[3].value.pdb_int = bpp;
return_args[4].value.pdb_int = num_bytes;
return_args[5].value.pdb_pointer = thumbnail_data;
}
return return_args;
}
static ProcArg drawable_sub_thumbnail_inargs[] =
{
{
GIMP_PDB_DRAWABLE,
"drawable",
"The drawable"
},
{
GIMP_PDB_INT32,
"src_x",
"The x coordinate of the area"
},
{
GIMP_PDB_INT32,
"src_y",
"The y coordinate of the area"
},
{
GIMP_PDB_INT32,
"src_width",
"The width of the area"
},
{
GIMP_PDB_INT32,
"src_height",
"The height of the area"
},
{
GIMP_PDB_INT32,
"dest_width",
"The thumbnail width"
},
{
GIMP_PDB_INT32,
"dest_height",
"The thumbnail height"
}
};
static ProcArg drawable_sub_thumbnail_outargs[] =
{
{
GIMP_PDB_INT32,
"width",
"The previews width"
},
{
GIMP_PDB_INT32,
"height",
"The previews height"
},
{
GIMP_PDB_INT32,
"bpp",
"The previews bpp"
},
{
GIMP_PDB_INT32,
"thumbnail_data_count",
"The number of bytes in thumbnail data"
},
{
GIMP_PDB_INT8ARRAY,
"thumbnail_data",
"The thumbnail data"
}
};
static ProcRecord drawable_sub_thumbnail_proc =
{
"gimp_drawable_sub_thumbnail",
"Get a thumbnail of a sub-area of a drawable drawable.",
"This function gets data from which a thumbnail of a drawable preview can be created. Maximum x or y dimension is 512 pixels. The pixels are returned in RGB[A] or GRAY[A] format. The bpp return value gives the number of bytes in the image.",
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer <mitch@gimp.org>",
"2004",
NULL,
GIMP_INTERNAL,
7,
drawable_sub_thumbnail_inargs,
5,
drawable_sub_thumbnail_outargs,
{ { drawable_sub_thumbnail_invoker } }
};
......@@ -74,7 +74,7 @@ void register_transform_tools_procs (Gimp *gimp);
void register_undo_procs (Gimp *gimp);
void register_unit_procs (Gimp *gimp);
/* 432 procedures registered total */
/* 433 procedures registered total */
void
internal_procs_init (Gimp *gimp,
......@@ -86,7 +86,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (_("Internal Procedures"), _("Brush"), 0.0);
register_brush_procs (gimp);
(* status_callback) (NULL, _("Brush UI"), 0.019);
(* status_callback) (NULL, _("Brush UI"), 0.018);
register_brush_select_procs (gimp);
(* status_callback) (NULL, _("Brushes"), 0.025);
......@@ -101,55 +101,55 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Context"), 0.095);
register_context_procs (gimp);
(* status_callback) (NULL, _("Convert"), 0.146);
(* status_callback) (NULL, _("Convert"), 0.145);
register_convert_procs (gimp);
(* status_callback) (NULL, _("Display procedures"), 0.153);
(* status_callback) (NULL, _("Display procedures"), 0.152);
register_display_procs (gimp);
(* status_callback) (NULL, _("Drawable procedures"), 0.162);
register_drawable_procs (gimp);
(* status_callback) (NULL, _("Transformation procedures"), 0.238);
(* status_callback) (NULL, _("Transformation procedures"), 0.24);
register_drawable_transform_procs (gimp);
(* status_callback) (NULL, _("Edit procedures"), 0.275);
(* status_callback) (NULL, _("Edit procedures"), 0.277);
register_edit_procs (gimp);
(* status_callback) (NULL, _("File Operations"), 0.296);
(* status_callback) (NULL, _("File Operations"), 0.298);
register_fileops_procs (gimp);
(* status_callback) (NULL, _("Floating selections"), 0.319);
(* status_callback) (NULL, _("Floating selections"), 0.321);
register_floating_sel_procs (gimp);
(* status_callback) (NULL, _("Font UI"), 0.333);
(* status_callback) (NULL, _("Font UI"), 0.335);
register_font_select_procs (gimp);
(* status_callback) (NULL, _("Fonts"), 0.34);
(* status_callback) (NULL, _("Fonts"), 0.342);
register_fonts_procs (gimp);
(* status_callback) (NULL, _("Gimprc procedures"), 0.345);
(* status_callback) (NULL, _("Gimprc procedures"), 0.346);
register_gimprc_procs (gimp);
(* status_callback) (NULL, _("Gradient"), 0.359);
(* status_callback) (NULL, _("Gradient"), 0.36);
register_gradient_procs (gimp);
(* status_callback) (NULL, _("Gradient UI"), 0.426);
(* status_callback) (NULL, _("Gradient UI"), 0.427);
register_gradient_select_procs (gimp);
(* status_callback) (NULL, _("Gradients"), 0.433);
(* status_callback) (NULL, _("Gradients"), 0.434);
register_gradients_procs (gimp);
(* status_callback) (NULL, _("Guide procedures"), 0.444);
(* status_callback) (NULL, _("Guide procedures"), 0.446);
register_guides_procs (gimp);
(* status_callback) (NULL, _("Help procedures"), 0.458);
(* status_callback) (NULL, _("Help procedures"), 0.46);
register_help_procs (gimp);
(* status_callback) (NULL, _("Image"), 0.461);
(* status_callback) (NULL, _("Image"), 0.462);
register_image_procs (gimp);
(* status_callback) (NULL, _("Layer"), 0.604);
(* status_callback) (NULL, _("Layer"), 0.605);
register_layer_procs (gimp);
(* status_callback) (NULL, _("Message procedures"), 0.667);
......@@ -158,25 +158,25 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Miscellaneous"), 0.674);
register_misc_procs (gimp);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.678);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.679);
register_paint_tools_procs (gimp);
(* status_callback) (NULL, _("Palette"), 0.713);
(* status_callback) (NULL, _("Palette"), 0.714);
register_palette_procs (gimp);
(* status_callback) (NULL, _("Palette UI"), 0.738);
(* status_callback) (NULL, _("Palette UI"), 0.739);
register_palette_select_procs (gimp);
(* status_callback) (NULL, _("Palettes"), 0.745);
(* status_callback) (NULL, _("Palettes"), 0.746);
register_palettes_procs (gimp);
(* status_callback) (NULL, _("Parasite procedures"), 0.755);
register_parasite_procs (gimp);
(* status_callback) (NULL, _("Paths"), 0.782);
(* status_callback) (NULL, _("Paths"), 0.783);
register_paths_procs (gimp);
(* status_callback) (NULL, _("Pattern"), 0.817);
(* status_callback) (NULL, _("Pattern"), 0.818);
register_pattern_procs (gimp);
(* status_callback) (NULL, _("Pattern UI"), 0.822);
......@@ -191,7 +191,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Procedural database"), 0.85);
register_procedural_db_procs (gimp);
(* status_callback) (NULL, _("Progress"), 0.87);
(* status_callback) (NULL, _("Progress"), 0.871);
register_progress_procs (gimp);
(* status_callback) (NULL, _("Image mask"), 0.882);
......
......@@ -103,6 +103,7 @@ EXPORTS
gimp_drawable_get_linked
gimp_drawable_get_name
gimp_drawable_get_pixel
gimp_drawable_get_sub_thumbnail_data
gimp_drawable_get_tattoo
gimp_drawable_get_thumbnail_data
gimp_drawable_get_tile
......
......@@ -288,6 +288,38 @@ gimp_drawable_get_thumbnail_data (gint32 drawable_ID,
return image_data;
}
guchar *
gimp_drawable_get_sub_thumbnail_data (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint *dest_width,
gint *dest_height,
gint *bpp)
{
gint ret_width;
gint ret_height;
guchar *image_data;
gint data_size;
_gimp_drawable_sub_thumbnail (drawable_ID,
src_x, src_y,
src_width, src_height,
*dest_width,
*dest_height,
&ret_width,
&ret_height,
bpp,
&data_size,
&image_data);
*dest_width = ret_width;
*dest_height = ret_height;
return image_data;
}
/**
* gimp_drawable_attach_new_parasite:
* @drawable_ID: the ID of the #GimpDrawable to attach the #GimpParasite to.
......
......@@ -40,32 +40,40 @@ struct _GimpDrawable
};
GimpDrawable * gimp_drawable_get (gint32 drawable_ID);
void gimp_drawable_detach (GimpDrawable *drawable);
void gimp_drawable_flush (GimpDrawable *drawable);
GimpTile * gimp_drawable_get_tile (GimpDrawable *drawable,
gint shadow,
gint row,
gint col);
GimpTile * gimp_drawable_get_tile2 (GimpDrawable *drawable,
gint shadow,
gint x,
gint y);
GimpDrawable * gimp_drawable_get (gint32 drawable_ID);
void gimp_drawable_detach (GimpDrawable *drawable);
void gimp_drawable_flush (GimpDrawable *drawable);
GimpTile * gimp_drawable_get_tile (GimpDrawable *drawable,
gint shadow,
gint row,
gint col);
GimpTile * gimp_drawable_get_tile2 (GimpDrawable *drawable,
gint shadow,
gint x,
gint y);
void gimp_drawable_get_color_uchar (gint32 drawable_ID,
const GimpRGB *color,
guchar *color_uchar);
void gimp_drawable_get_color_uchar (gint32 drawable_ID,
const GimpRGB *color,
guchar *color_uchar);
guchar * gimp_drawable_get_thumbnail_data (gint32 drawable_ID,
gint *width,
gint *height,
gint *bpp);
guchar * gimp_drawable_get_thumbnail_data (gint32 drawable_ID,
gint *width,
gint *height,
gint *bpp);
guchar * gimp_drawable_get_sub_thumbnail_data (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint *dest_width,
gint *dest_height,
gint *bpp);
void gimp_drawable_attach_new_parasite (gint32 drawable_ID,
const gchar *name,
gint flags,
gint size,
gconstpointer data);
void gimp_drawable_attach_new_parasite (gint32 drawable_ID,
const gchar *name,
gint flags,
gint size,
gconstpointer data);
G_END_DECLS
......
......@@ -1219,3 +1219,82 @@ _gimp_drawable_thumbnail (gint32 drawable_ID,
return success;
}
/**
* _gimp_drawable_sub_thumbnail:
* @drawable_ID: The drawable.
* @src_x: The x coordinate of the area.
* @src_y: The y coordinate of the area.
* @src_width: The width of the area.
* @src_height: The height of the area.
* @dest_width: The thumbnail width.
* @dest_height: The thumbnail height.
* @width: The previews width.
* @height: The previews height.
* @bpp: The previews bpp.
* @thumbnail_data_count: The number of bytes in thumbnail data.
* @thumbnail_data: The thumbnail data.
*
* Get a thumbnail of a sub-area of a drawable drawable.
*
* This function gets data from which a thumbnail of a drawable preview
* can be created. Maximum x or y dimension is 512 pixels. The pixels
* are returned in RGB[A] or GRAY[A] format. The bpp return value gives
* the number of bytes in the image.
*
* Returns: TRUE on success.
*
* Since: GIMP 2.2
*/
gboolean
_gimp_drawable_sub_thumbnail (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height,
gint *width,
gint *height,
gint *bpp,
gint *thumbnail_data_count,
guint8 **thumbnail_data)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp_drawable_sub_thumbnail",
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
GIMP_PDB_INT32, src_x,
GIMP_PDB_INT32, src_y,
GIMP_PDB_INT32, src_width,
GIMP_PDB_INT32, src_height,
GIMP_PDB_INT32, dest_width,
GIMP_PDB_INT32, dest_height,
GIMP_PDB_END);
*width = 0;
*height = 0;
*bpp = 0;
*thumbnail_data_count = 0;
*thumbnail_data = NULL;
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
if (success)
{
*width = return_vals[1].data.d_int32;
*height = return_vals[2].data.d_int32;
*bpp = return_vals[3].data.d_int32;
*thumbnail_data_count = return_vals[4].data.d_int32;
*thumbnail_data = g_new (guint8, *thumbnail_data_count);
memcpy (*thumbnail_data, return_vals[5].data.d_int8array,
*thumbnail_data_count * sizeof (guint8));
}
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}
......@@ -103,6 +103,18 @@ gboolean _gimp_drawable_thumbnail (gint32 drawable_ID,
gint *bpp,
gint *thumbnail_data_count,
guint8 **thumbnail_data);
gboolean _gimp_drawable_sub_thumbnail (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height,
gint *width,
gint *height,
gint *bpp,
gint *thumbnail_data_count,
guint8 **thumbnail_data);
G_END_DECLS
......
......@@ -114,8 +114,64 @@ gimp_drawable_get_thumbnail (gint32 drawable_ID,
return gimp_pixbuf_from_data (data,
thumb_width, thumb_height, thumb_bpp,
alpha);
else
return NULL;
return NULL;
}
/**
* gimp_drawable_get_sub_thumbnail:
* @drawable_ID: the drawable ID
* @src_x: the x coordinate of the area
* @src_y: the y coordinate of the area
* @src_width: the width of the area
* @src_height: the height of the area
* @dest_width: the requested thumbnail width (<= 512 pixels)
* @dest_height: the requested thumbnail height (<= 512 pixels)
* @alpha: how to handle an alpha channel
*
* Retrieves a thumbnail pixbuf for the drawable identified by
* @drawable_ID. The thumbnail will be not larger than the requested
* size.
*
* Return value: a new #GdkPixbuf
*
* Since: GIMP 2.2
**/
GdkPixbuf *
gimp_drawable_get_sub_thumbnail (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height,
GimpPixbufTransparency alpha)
{
gint thumb_width = dest_width;
gint thumb_height = dest_height;
gint thumb_bpp;
guchar *data;
g_return_val_if_fail (src_x >= 0, NULL);
g_return_val_if_fail (src_y >= 0, NULL);
g_return_val_if_fail (src_width > 0, NULL);
g_return_val_if_fail (src_height > 0, NULL);
g_return_val_if_fail (dest_width > 0 && dest_width <= 512, NULL);
g_return_val_if_fail (dest_height > 0 && dest_height <= 512, NULL);
data = gimp_drawable_get_sub_thumbnail_data (drawable_ID,
src_x, src_y,
src_width, src_height,
&thumb_width,
&thumb_height,
&thumb_bpp);
if (data)
return gimp_pixbuf_from_data (data,
thumb_width, thumb_height, thumb_bpp,
alpha);
return NULL;
}
static GdkPixbuf *
......
......@@ -37,14 +37,22 @@ typedef enum
} GimpPixbufTransparency;
GdkPixbuf * gimp_image_get_thumbnail (gint32 image_ID,
gint width,
gint height,
GimpPixbufTransparency alpha);
GdkPixbuf * gimp_drawable_get_thumbnail (gint32 drawable_ID,
gint width,
gint height,
GimpPixbufTransparency alpha);
GdkPixbuf * gimp_image_get_thumbnail (gint32 image_ID,
gint width,
gint height,
GimpPixbufTransparency alpha);
GdkPixbuf * gimp_drawable_get_thumbnail (gint32 drawable_ID,
gint width,
gint height,
GimpPixbufTransparency alpha);
GdkPixbuf * gimp_drawable_get_sub_thumbnail (gint32 drawable_ID,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height,
GimpPixbufTransparency alpha);
G_END_DECLS
......
......@@ -7,6 +7,7 @@ EXPORTS
gimp_channel_combo_box_new
gimp_channel_menu_new
gimp_drawable_combo_box_new
gimp_drawable_get_sub_thumbnail
gimp_drawable_get_thumbnail
gimp_drawable_menu_new
gimp_drawable_preview_draw_region
......
......@@ -685,6 +685,89 @@ CODE
);
}
sub drawable_sub_thumbnail {
$blurb = 'Get a thumbnail of a sub-area of a drawable drawable.';
$help = <<'HELP';
This function gets data from which a thumbnail of a drawable preview
can be created. Maximum x or y dimension is 512 pixels. The pixels are
returned in RGB[A] or GRAY[A] format. The bpp return value gives the
number of bytes in the image.
HELP
$author = $copyright = 'Michael Natterer <mitch@gimp.org>';
$date = '2004';
$since = '2.2';
@inargs = (
&drawable_arg,
{ name => 'src_x', type => '0 <= int32',
desc => 'The x coordinate of the area' },
{ name => 'src_y', type => '0 <= int32',
desc => 'The y coordinate of the area' },
{ name => 'src_width', type => '0 < int32',
desc => 'The width of the area' },
{ name => 'src_height', type => '0 < int32',
desc => 'The height of the area' },
{ name => 'dest_width', type => '0 < int32 <= 512',
desc => 'The thumbnail width' },
{ name => 'dest_height', type => '0 < int32 <= 512',
desc => 'The thumbnail height' }
);
@outargs = (
&dim_args,
{ name => 'thumbnail_data', type => 'int8array',
desc => 'The thumbnail data', init => 1, wrap => 1,
array => { name => 'thumbnail_data_count',
desc => 'The number of bytes in thumbnail data',
alias => 'num_bytes', init => 1 } }
);
$outargs[0]->{void_ret} = 1;