Commit bf5750d9 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

implement a thumbnail load procedure that loads only the first frame of a

2006-04-24  Sven Neumann  <sven@gimp.org>

	* plug-ins/common/gifload.c: implement a thumbnail load procedure
	that loads only the first frame of a GIF animation.
parent 7c79798b
2006-04-24 Sven Neumann <sven@gimp.org>
* plug-ins/common/gifload.c: implement a thumbnail load procedure
that loads only the first frame of a GIF animation.
2006-04-24 DindinX <dindinx@gimp.org> 2006-04-24 DindinX <dindinx@gimp.org>
* plug-ins/common/redeye.c: use a zoom preview instead of a drawable * plug-ins/common/redeye.c: use a zoom preview instead of a drawable
......
...@@ -75,20 +75,14 @@ ...@@ -75,20 +75,14 @@
#include "libgimp/stdplugins-intl.h" #include "libgimp/stdplugins-intl.h"
#define LOAD_PROC "file-gif-load" #define LOAD_PROC "file-gif-load"
#define LOAD_THUMB_PROC "file-gif-load-thumb"
/* uncomment the line below for a little debugging info */ /* uncomment the line below for a little debugging info */
/* #define GIFDEBUG yesplease */ /* #define GIFDEBUG yesplease */
/* Does the version of GIMP we're compiling for support
data attachments to images? ('Parasites') */
#define FACEHUGGERS aieee
/* PS: I know that technically facehuggers aren't parasites,
the pupal-forms are. But facehuggers are ky00te. */
/* Declare some local functions. /* Declare some local functions.
*/ */
static void query (void); static void query (void);
...@@ -97,17 +91,15 @@ static void run (const gchar *name, ...@@ -97,17 +91,15 @@ static void run (const gchar *name,
const GimpParam *param, const GimpParam *param,
gint *nreturn_vals, gint *nreturn_vals,
GimpParam **return_vals); GimpParam **return_vals);
static gint32 load_image (const gchar *filename); static gint32 load_image (const gchar *filename,
gboolean thumbnail);
static guchar used_cmap[3][256]; static guchar used_cmap[3][256];
static GimpRunMode run_mode; static guchar highest_used_index;
static guchar highest_used_index; static gboolean promote_to_rgb = FALSE;
static gboolean promote_to_rgb = FALSE; static guchar gimp_cmap[768];
static guchar gimp_cmap[768]; static GimpParasite *comment_parasite = NULL;
#ifdef FACEHUGGERS
GimpParasite* comment_parasite = NULL;
#endif
GimpPlugInInfo PLUG_IN_INFO = GimpPlugInInfo PLUG_IN_INFO =
...@@ -132,15 +124,20 @@ query (void) ...@@ -132,15 +124,20 @@ query (void)
}; };
static GimpParamDef load_return_vals[] = static GimpParamDef load_return_vals[] =
{ {
{ GIMP_PDB_IMAGE, "image", "Output image" } { 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" }
}; };
gimp_install_procedure (LOAD_PROC, gimp_install_procedure (LOAD_PROC,
"loads files of Compuserve GIF file format", "Loads files of Compuserve GIF file format",
"FIXME: write help for gif_load", "FIXME: write help for gif_load",
"Spencer Kimball, Peter Mattis, Adam Moss, David Koblas", "Spencer Kimball, Peter Mattis, Adam Moss, David Koblas",
"Spencer Kimball, Peter Mattis, Adam Moss, David Koblas", "Spencer Kimball, Peter Mattis, Adam Moss, David Koblas",
"1995-1997", "1995-2006",
N_("GIF image"), N_("GIF image"),
NULL, NULL,
GIMP_PLUGIN, GIMP_PLUGIN,
...@@ -153,8 +150,23 @@ query (void) ...@@ -153,8 +150,23 @@ query (void)
"gif", "gif",
"", "",
"0,string,GIF8"); "0,string,GIF8");
}
gimp_install_procedure (LOAD_THUMB_PROC,
"Loads only the first frame of a GIF image, to be "
"used as a thumbnail",
"",
"Sven Neumann",
"Sven Neumann",
"2006",
NULL,
NULL,
GIMP_PLUGIN,
G_N_ELEMENTS (thumb_args),
G_N_ELEMENTS (load_return_vals),
thumb_args, load_return_vals);
gimp_register_thumbnail_loader (LOAD_PROC, LOAD_THUMB_PROC);
}
static void static void
run (const gchar *name, run (const gchar *name,
...@@ -167,8 +179,6 @@ run (const gchar *name, ...@@ -167,8 +179,6 @@ run (const gchar *name,
GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 image_ID; gint32 image_ID;
run_mode = param[0].data.d_int32;
INIT_I18N (); INIT_I18N ();
*nreturn_vals = 1; *nreturn_vals = 1;
...@@ -179,28 +189,38 @@ run (const gchar *name, ...@@ -179,28 +189,38 @@ run (const gchar *name,
if (strcmp (name, LOAD_PROC) == 0) if (strcmp (name, LOAD_PROC) == 0)
{ {
image_ID = load_image (param[1].data.d_string); image_ID = load_image (param[1].data.d_string, FALSE);
}
/* The GIF format only tells you how many bits per pixel else if (strcmp (name, LOAD_THUMB_PROC) == 0)
* are in the image, not the actual number of used indices (D'OH!) {
* image_ID = load_image (param[0].data.d_string, TRUE);
* So if we're not careful, repeated load/save of a transparent GIF }
* without intermediate indexed->RGB->indexed pumps up the number of else
* bits used, as we add an index each time for the transparent {
* colour. Ouch. We either do some heavier analysis at save-time, status = GIMP_PDB_CALLING_ERROR;
* or trim down the number of GIMP colours at load-time. We do the }
* latter for now.
*/
#ifdef GIFDEBUG
g_print ("GIF: Highest used index is %d\n", highest_used_index);
#endif
if (!promote_to_rgb)
{
gimp_image_set_colormap (image_ID, gimp_cmap, highest_used_index+1);
}
if (status == GIMP_PDB_SUCCESS)
{
if (image_ID != -1) if (image_ID != -1)
{ {
/* The GIF format only tells you how many bits per pixel
* are in the image, not the actual number of used indices (D'OH!)
*
* So if we're not careful, repeated load/save of a transparent GIF
* without intermediate indexed->RGB->indexed pumps up the number of
* bits used, as we add an index each time for the transparent
* colour. Ouch. We either do some heavier analysis at save-time,
* or trim down the number of GIMP colours at load-time. We do the
* latter for now.
*/
#ifdef GIFDEBUG
g_print ("GIF: Highest used index is %d\n", highest_used_index);
#endif
if (! promote_to_rgb)
gimp_image_set_colormap (image_ID,
gimp_cmap, highest_used_index + 1);
*nreturn_vals = 2; *nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE; values[1].type = GIMP_PDB_IMAGE;
values[1].data.d_image = image_ID; values[1].data.d_image = image_ID;
...@@ -210,10 +230,6 @@ run (const gchar *name, ...@@ -210,10 +230,6 @@ run (const gchar *name,
status = GIMP_PDB_EXECUTION_ERROR; status = GIMP_PDB_EXECUTION_ERROR;
} }
} }
else
{
status = GIMP_PDB_CALLING_ERROR;
}
values[0].data.d_status = status; values[0].data.d_status = status;
} }
...@@ -243,7 +259,7 @@ static struct ...@@ -243,7 +259,7 @@ static struct
{ {
unsigned int Width; unsigned int Width;
unsigned int Height; unsigned int Height;
CMap ColorMap; CMap ColorMap;
unsigned int BitPixel; unsigned int BitPixel;
unsigned int ColorResolution; unsigned int ColorResolution;
unsigned int Background; unsigned int Background;
...@@ -251,7 +267,7 @@ static struct ...@@ -251,7 +267,7 @@ static struct
/* /*
** **
*/ */
int GrayScale; int GrayScale;
} GifScreen; } GifScreen;
static struct static struct
...@@ -262,11 +278,6 @@ static struct ...@@ -262,11 +278,6 @@ static struct
int disposal; int disposal;
} Gif89 = { -1, -1, -1, 0 }; } Gif89 = { -1, -1, -1, 0 };
int verbose = FALSE;
int showComment = TRUE;
char *globalcomment = NULL;
gint globalusecomment = TRUE;
static int ReadColorMap (FILE *, int, CMap, int *); static int ReadColorMap (FILE *, int, CMap, int *);
static int DoExtension (FILE *, int); static int DoExtension (FILE *, int);
static int GetDataBlock (FILE *, unsigned char *); static int GetDataBlock (FILE *, unsigned char *);
...@@ -278,18 +289,19 @@ static gint32 ReadImage (FILE *, const gchar *, ...@@ -278,18 +289,19 @@ static gint32 ReadImage (FILE *, const gchar *,
static gint32 static gint32
load_image (const gchar *filename) load_image (const gchar *filename,
gboolean thumbnail)
{ {
FILE *fd; FILE *fd;
guchar buf[16]; guchar buf[16];
guchar c; guchar c;
CMap localColorMap; CMap localColorMap;
gint grayScale; gint grayScale;
gint useGlobalColormap; gboolean useGlobalColormap;
gint bitPixel; gint bitPixel;
gint imageCount = 0; gint imageCount = 0;
gchar version[4]; gchar version[4];
gint32 image_ID = -1; gint32 image_ID = -1;
fd = g_fopen (filename, "rb"); fd = g_fopen (filename, "rb");
if (!fd) if (!fd)
...@@ -308,13 +320,13 @@ load_image (const gchar *filename) ...@@ -308,13 +320,13 @@ load_image (const gchar *filename)
return -1; return -1;
} }
if (strncmp ((char *) buf, "GIF", 3) != 0) if (strncmp ((gchar *) buf, "GIF", 3) != 0)
{ {
g_message (_("This is not a GIF file")); g_message (_("This is not a GIF file"));
return -1; return -1;
} }
strncpy (version, (char *) buf + 3, 3); strncpy (version, (gchar *) buf + 3, 3);
version[3] = '\0'; version[3] = '\0';
if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0)) if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0))
...@@ -339,7 +351,8 @@ load_image (const gchar *filename) ...@@ -339,7 +351,8 @@ load_image (const gchar *filename)
if (BitSet (buf[4], LOCALCOLORMAP)) if (BitSet (buf[4], LOCALCOLORMAP))
{ {
/* Global Colormap */ /* Global Colormap */
if (ReadColorMap (fd, GifScreen.BitPixel, GifScreen.ColorMap, &GifScreen.GrayScale)) if (ReadColorMap (fd, GifScreen.BitPixel, GifScreen.ColorMap,
&GifScreen.GrayScale))
{ {
g_message ("Error reading global colormap"); g_message ("Error reading global colormap");
return -1; return -1;
...@@ -354,7 +367,6 @@ load_image (const gchar *filename) ...@@ -354,7 +367,6 @@ load_image (const gchar *filename)
highest_used_index = 0; highest_used_index = 0;
for (;;) for (;;)
{ {
if (!ReadOK (fd, &c, 1)) if (!ReadOK (fd, &c, 1))
...@@ -400,7 +412,7 @@ load_image (const gchar *filename) ...@@ -400,7 +412,7 @@ load_image (const gchar *filename)
bitPixel = 1 << ((buf[8] & 0x07) + 1); bitPixel = 1 << ((buf[8] & 0x07) + 1);
if (!useGlobalColormap) if (! useGlobalColormap)
{ {
if (ReadColorMap (fd, bitPixel, localColorMap, &grayScale)) if (ReadColorMap (fd, bitPixel, localColorMap, &grayScale))
{ {
...@@ -431,15 +443,18 @@ load_image (const gchar *filename) ...@@ -431,15 +443,18 @@ load_image (const gchar *filename)
GifScreen.Height); GifScreen.Height);
} }
#ifdef FACEHUGGERS
if (comment_parasite != NULL) if (comment_parasite != NULL)
{ {
gimp_image_parasite_attach (image_ID, comment_parasite); if (! thumbnail)
gimp_image_parasite_attach (image_ID, comment_parasite);
gimp_parasite_free (comment_parasite); gimp_parasite_free (comment_parasite);
comment_parasite = NULL; comment_parasite = NULL;
} }
#endif
/* If we are loading a thumbnail, we stop after the first frame. */
if (thumbnail)
break;
} }
return image_ID; return image_ID;
...@@ -521,7 +536,6 @@ DoExtension (FILE *fd, ...@@ -521,7 +536,6 @@ DoExtension (FILE *fd,
str = "Comment Extension"; str = "Comment Extension";
while (GetDataBlock (fd, (unsigned char *) buf) > 0) while (GetDataBlock (fd, (unsigned char *) buf) > 0)
{ {
#ifdef FACEHUGGERS
if (!g_utf8_validate (buf, -1, NULL)) if (!g_utf8_validate (buf, -1, NULL))
continue; continue;
...@@ -531,10 +545,6 @@ DoExtension (FILE *fd, ...@@ -531,10 +545,6 @@ DoExtension (FILE *fd,
comment_parasite = gimp_parasite_new ("gimp-comment", comment_parasite = gimp_parasite_new ("gimp-comment",
GIMP_PARASITE_PERSISTENT, GIMP_PARASITE_PERSISTENT,
strlen (buf) + 1, buf); strlen (buf) + 1, buf);
#else
if (showComment)
g_print ("GIF: gif comment: %s\n", buf);
#endif
} }
return TRUE; return TRUE;
break; break;
...@@ -974,7 +984,7 @@ ReadImage (FILE *fd, ...@@ -974,7 +984,7 @@ ReadImage (FILE *fd,
frame_number++; frame_number++;
gimp_image_add_layer (image_ID, layer_ID, 0); gimp_image_add_layer (image_ID, layer_ID, 0);
gimp_layer_translate (layer_ID, (gint)leftpos, (gint)toppos); gimp_layer_translate (layer_ID, (gint) leftpos, (gint) toppos);
drawable = gimp_drawable_get (layer_ID); drawable = gimp_drawable_get (layer_ID);
...@@ -987,9 +997,10 @@ ReadImage (FILE *fd, ...@@ -987,9 +997,10 @@ ReadImage (FILE *fd,
else else
dest = (guchar *) g_malloc (len * height); dest = (guchar *) g_malloc (len * height);
if (verbose) #ifdef GIFDEBUG
g_print ("GIF: reading %d by %d%s GIF image, ncols=%d\n", g_print ("GIF: reading %d by %d%s GIF image, ncols=%d\n",
len, height, interlace ? " interlaced" : "", ncols); len, height, interlace ? " interlaced" : "", ncols);
#endif
if (!alpha_frame && promote_to_rgb) if (!alpha_frame && promote_to_rgb)
{ {
...@@ -1004,8 +1015,8 @@ ReadImage (FILE *fd, ...@@ -1004,8 +1015,8 @@ ReadImage (FILE *fd,
{ {
if (alpha_frame) if (alpha_frame)
{ {
if (((guchar)v > highest_used_index) && !(v == Gif89.transparent)) if (((guchar) v > highest_used_index) && !(v == Gif89.transparent))
highest_used_index = (guchar)v; highest_used_index = (guchar) v;
if (promote_to_rgb) if (promote_to_rgb)
{ {
...@@ -1024,8 +1035,8 @@ ReadImage (FILE *fd, ...@@ -1024,8 +1035,8 @@ ReadImage (FILE *fd,
} }
else else
{ {
if ((guchar)v > highest_used_index) if ((guchar) v > highest_used_index)
highest_used_index = (guchar)v; highest_used_index = (guchar) v;
temp = dest + (ypos * len) + xpos; temp = dest + (ypos * len) + xpos;
*temp = (guchar) v; *temp = (guchar) v;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment