mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-04 09:53:25 +00:00
plug-ins: Add import support for Jeff's Image Format
JIF is a variation of the GIF format that compresses indexed images using zlib rather than LZW. This patch add import support for JIF images.
This commit is contained in:
parent
992b7c40c6
commit
6395c37425
1 changed files with 305 additions and 116 deletions
|
@ -67,6 +67,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
@ -75,8 +76,10 @@
|
||||||
#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"
|
#define LOAD_THUMB_PROC "file-gif-load-thumb"
|
||||||
|
#define LOAD_JIF_PROC "file-jif-load"
|
||||||
|
#define LOAD_JIF_THUMB_PROC "file-jif-load-thumb"
|
||||||
|
|
||||||
|
|
||||||
/* uncomment the line below for a little debugging info */
|
/* uncomment the line below for a little debugging info */
|
||||||
|
@ -121,6 +124,7 @@ static GimpValueArray * gif_load_thumb (GimpProcedure *procedure,
|
||||||
|
|
||||||
static GimpImage * load_image (GFile *file,
|
static GimpImage * load_image (GFile *file,
|
||||||
gboolean thumbnail,
|
gboolean thumbnail,
|
||||||
|
gboolean is_jeff_image,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,6 +163,8 @@ gif_query_procedures (GimpPlugIn *plug_in)
|
||||||
|
|
||||||
list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
|
list = g_list_append (list, g_strdup (LOAD_THUMB_PROC));
|
||||||
list = g_list_append (list, g_strdup (LOAD_PROC));
|
list = g_list_append (list, g_strdup (LOAD_PROC));
|
||||||
|
list = g_list_append (list, g_strdup (LOAD_JIF_THUMB_PROC));
|
||||||
|
list = g_list_append (list, g_strdup (LOAD_JIF_PROC));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -215,6 +221,46 @@ gif_create_procedure (GimpPlugIn *plug_in,
|
||||||
"Sven Neumann",
|
"Sven Neumann",
|
||||||
"2006");
|
"2006");
|
||||||
}
|
}
|
||||||
|
else if (! strcmp (name, LOAD_JIF_THUMB_PROC))
|
||||||
|
{
|
||||||
|
procedure = gimp_thumbnail_procedure_new (plug_in, name,
|
||||||
|
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||||
|
gif_load_thumb, NULL, NULL);
|
||||||
|
|
||||||
|
gimp_procedure_set_documentation (procedure,
|
||||||
|
"Loads only the first frame of a "
|
||||||
|
"Jeff's Image Format image, to be "
|
||||||
|
"used as a thumbnail",
|
||||||
|
"",
|
||||||
|
name);
|
||||||
|
gimp_procedure_set_attribution (procedure,
|
||||||
|
"Alx Sa",
|
||||||
|
"Alx Sa",
|
||||||
|
"2025");
|
||||||
|
}
|
||||||
|
else if (! strcmp (name, LOAD_JIF_PROC))
|
||||||
|
{
|
||||||
|
procedure = gimp_load_procedure_new (plug_in, name,
|
||||||
|
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||||
|
gif_load, NULL, NULL);
|
||||||
|
|
||||||
|
gimp_procedure_set_menu_label (procedure, _("Jeff's Image Format"));
|
||||||
|
|
||||||
|
gimp_procedure_set_documentation (procedure,
|
||||||
|
"Loads files of Jeff's Image Format "
|
||||||
|
"file format", NULL,
|
||||||
|
name);
|
||||||
|
gimp_procedure_set_attribution (procedure,
|
||||||
|
"Alx Sa",
|
||||||
|
"Alx Sa",
|
||||||
|
"2025");
|
||||||
|
|
||||||
|
gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
|
||||||
|
"0,string,JIF99a");
|
||||||
|
|
||||||
|
gimp_load_procedure_set_thumbnail_loader (GIMP_LOAD_PROCEDURE (procedure),
|
||||||
|
LOAD_JIF_THUMB_PROC);
|
||||||
|
}
|
||||||
|
|
||||||
return procedure;
|
return procedure;
|
||||||
}
|
}
|
||||||
|
@ -231,11 +277,15 @@ gif_load (GimpProcedure *procedure,
|
||||||
{
|
{
|
||||||
GimpValueArray *return_vals;
|
GimpValueArray *return_vals;
|
||||||
GimpImage *image;
|
GimpImage *image;
|
||||||
GError *error = NULL;
|
gboolean is_jeff = FALSE;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
gegl_init (NULL, NULL);
|
gegl_init (NULL, NULL);
|
||||||
|
|
||||||
image = load_image (file, FALSE, &error);
|
/* Unlikely, but check if we're loading a Jeff Image Format image */
|
||||||
|
is_jeff = (! strcmp (gimp_procedure_get_name (procedure), LOAD_JIF_PROC));
|
||||||
|
|
||||||
|
image = load_image (file, FALSE, is_jeff, &error);
|
||||||
|
|
||||||
if (! image)
|
if (! image)
|
||||||
return gimp_procedure_new_return_values (procedure,
|
return gimp_procedure_new_return_values (procedure,
|
||||||
|
@ -279,11 +329,15 @@ gif_load_thumb (GimpProcedure *procedure,
|
||||||
{
|
{
|
||||||
GimpValueArray *return_vals;
|
GimpValueArray *return_vals;
|
||||||
GimpImage *image;
|
GimpImage *image;
|
||||||
GError *error = NULL;
|
gboolean is_jeff = FALSE;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
gegl_init (NULL, NULL);
|
gegl_init (NULL, NULL);
|
||||||
|
|
||||||
image = load_image (file, TRUE, &error);
|
/* Unlikely, but check if we're loading a Jeff Image Format image */
|
||||||
|
is_jeff = (! strcmp (gimp_procedure_get_name (procedure), LOAD_JIF_THUMB_PROC));
|
||||||
|
|
||||||
|
image = load_image (file, TRUE, is_jeff, &error);
|
||||||
|
|
||||||
if (! image)
|
if (! image)
|
||||||
return gimp_procedure_new_return_values (procedure,
|
return gimp_procedure_new_return_values (procedure,
|
||||||
|
@ -355,42 +409,53 @@ static struct
|
||||||
gint num_loops;
|
gint num_loops;
|
||||||
} Gif89 = { -1, -1, -1, 0, -1 };
|
} Gif89 = { -1, -1, -1, 0, -1 };
|
||||||
|
|
||||||
static void read_error (const gchar *error_type,
|
static void read_error (const gchar *error_type,
|
||||||
GimpImage *image,
|
GimpImage *image,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean ReadColorMap (FILE *fd,
|
static gboolean ReadColorMap (FILE *fd,
|
||||||
gint number,
|
gint number,
|
||||||
CMap buffer,
|
CMap buffer,
|
||||||
gint *format);
|
gint *format);
|
||||||
static gint DoExtension (FILE *fd,
|
static gint DoExtension (FILE *fd,
|
||||||
gint label);
|
gint label);
|
||||||
static gint GetDataBlock (FILE *fd,
|
static gint GetDataBlock (FILE *fd,
|
||||||
guchar *buf);
|
guchar *buf);
|
||||||
static gint GetCode (FILE *fd,
|
static gint GetCode (FILE *fd,
|
||||||
gint code_size,
|
gint code_size,
|
||||||
gboolean flag);
|
gboolean flag);
|
||||||
static gint LZWReadByte (FILE *fd,
|
static gint LZWReadByte (FILE *fd,
|
||||||
gint just_reset_LZW,
|
gint just_reset_LZW,
|
||||||
gint input_code_size);
|
gint input_code_size);
|
||||||
static gboolean ReadImage (FILE *fd,
|
static gboolean ReadImage (FILE *fd,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
gint len,
|
gint len,
|
||||||
gint height,
|
gint height,
|
||||||
CMap cmap,
|
CMap cmap,
|
||||||
gint ncols,
|
gint ncols,
|
||||||
gint format,
|
gint format,
|
||||||
gint interlace,
|
gint interlace,
|
||||||
gint number,
|
gint number,
|
||||||
guint leftpos,
|
guint leftpos,
|
||||||
guint toppos,
|
guint toppos,
|
||||||
guint screenwidth,
|
guint screenwidth,
|
||||||
guint screenheight,
|
guint screenheight,
|
||||||
GimpImage **image,
|
gboolean is_jeff_image,
|
||||||
GError **error);
|
GimpImage **image,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
static gboolean ReadJeffsImage (FILE *fd,
|
||||||
|
guchar *dest,
|
||||||
|
guchar bpp,
|
||||||
|
gint len,
|
||||||
|
gint height,
|
||||||
|
gboolean alpha_frame,
|
||||||
|
GimpImage **image,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
static GimpImage *
|
static GimpImage *
|
||||||
load_image (GFile *file,
|
load_image (GFile *file,
|
||||||
gboolean thumbnail,
|
gboolean thumbnail,
|
||||||
|
gboolean is_jeff_image,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
@ -425,20 +490,35 @@ load_image (GFile *file,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp ((gchar *) buf, "GIF", 3) != 0)
|
if (! is_jeff_image)
|
||||||
{
|
{
|
||||||
g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
|
if (strncmp ((gchar *) buf, "GIF", 3) != 0)
|
||||||
_("This is not a GIF file: incorrect magic code"));
|
{
|
||||||
fclose (fd);
|
g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
|
||||||
return NULL;
|
_("This is not a GIF file: incorrect magic code"));
|
||||||
}
|
fclose (fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((strncmp ((gchar *) buf + 3, "87a", 3) != 0) && (strncmp ((gchar *) buf + 3, "89a", 3) != 0))
|
if ((strncmp ((gchar *) buf + 3, "87a", 3) != 0) &&
|
||||||
|
(strncmp ((gchar *) buf + 3, "89a", 3) != 0))
|
||||||
|
{
|
||||||
|
g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
|
||||||
|
_("Incorrect GIF version: not '87a' or '89a'"));
|
||||||
|
fclose (fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
|
if (strncmp ((gchar *) buf, "JIF99a", 6) != 0)
|
||||||
_("Incorrect GIF version: not '87a' or '89a'"));
|
{
|
||||||
fclose (fd);
|
g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
|
||||||
return NULL;
|
_("This is not a Jeff's Image Format file: "
|
||||||
|
"incorrect magic code"));
|
||||||
|
fclose (fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ReadOK (fd, buf, 7))
|
if (! ReadOK (fd, buf, 7))
|
||||||
|
@ -538,7 +618,7 @@ load_image (GFile *file,
|
||||||
(guint) LM_to_uint (buf[2], buf[3]),
|
(guint) LM_to_uint (buf[2], buf[3]),
|
||||||
GifScreen.Width,
|
GifScreen.Width,
|
||||||
GifScreen.Height,
|
GifScreen.Height,
|
||||||
&image, error);
|
is_jeff_image, &image, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -551,7 +631,7 @@ load_image (GFile *file,
|
||||||
(guint) LM_to_uint (buf[2], buf[3]),
|
(guint) LM_to_uint (buf[2], buf[3]),
|
||||||
GifScreen.Width,
|
GifScreen.Width,
|
||||||
GifScreen.Height,
|
GifScreen.Height,
|
||||||
&image, error);
|
is_jeff_image, &image, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
|
@ -1067,6 +1147,7 @@ ReadImage (FILE *fd,
|
||||||
guint toppos,
|
guint toppos,
|
||||||
guint screenwidth,
|
guint screenwidth,
|
||||||
guint screenheight,
|
guint screenheight,
|
||||||
|
gboolean is_jeff_image,
|
||||||
GimpImage **image,
|
GimpImage **image,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -1111,7 +1192,8 @@ ReadImage (FILE *fd,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LZWReadByte (fd, TRUE, c) < 0)
|
/* Jeff's Image Format uses zlib compression instead of LZW */
|
||||||
|
if (! is_jeff_image && LZWReadByte (fd, TRUE, c) < 0)
|
||||||
{
|
{
|
||||||
read_error (_("compressed image data"), *image, error);
|
read_error (_("compressed image data"), *image, error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1166,7 +1248,7 @@ ReadImage (FILE *fd,
|
||||||
GIMP_INDEXEDA_IMAGE,
|
GIMP_INDEXEDA_IMAGE,
|
||||||
100,
|
100,
|
||||||
gimp_image_get_default_new_layer_mode (*image));
|
gimp_image_get_default_new_layer_mode (*image));
|
||||||
alpha_frame=TRUE;
|
alpha_frame = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (framename);
|
g_free (framename);
|
||||||
|
@ -1297,88 +1379,93 @@ ReadImage (FILE *fd,
|
||||||
else
|
else
|
||||||
dest = (guchar *) g_malloc ((gsize)len * (gsize)height);
|
dest = (guchar *) g_malloc ((gsize)len * (gsize)height);
|
||||||
|
|
||||||
while ((v = LZWReadByte (fd, FALSE, c)) >= 0)
|
if (! is_jeff_image)
|
||||||
{
|
{
|
||||||
if (alpha_frame)
|
while ((v = LZWReadByte (fd, FALSE, c)) >= 0)
|
||||||
{
|
{
|
||||||
|
if (alpha_frame)
|
||||||
if (promote_to_rgb)
|
|
||||||
{
|
{
|
||||||
temp = dest + ( (ypos * len) + xpos ) * 4;
|
if (promote_to_rgb)
|
||||||
*(temp ) = (guchar) cmap[0][v];
|
{
|
||||||
*(temp+1) = (guchar) cmap[1][v];
|
temp = dest + ( (ypos * len) + xpos ) * 4;
|
||||||
*(temp+2) = (guchar) cmap[2][v];
|
*(temp ) = (guchar) cmap[0][v];
|
||||||
*(temp+3) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
|
*(temp+1) = (guchar) cmap[1][v];
|
||||||
|
*(temp+2) = (guchar) cmap[2][v];
|
||||||
|
*(temp+3) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = dest + ( (ypos * len) + xpos ) * 2;
|
||||||
|
*temp = (guchar) v;
|
||||||
|
*(temp+1) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp = dest + ( (ypos * len) + xpos ) * 2;
|
temp = dest + (ypos * len) + xpos;
|
||||||
*temp = (guchar) v;
|
*temp = (guchar) v;
|
||||||
*(temp+1) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
temp = dest + (ypos * len) + xpos;
|
xpos++;
|
||||||
*temp = (guchar) v;
|
if (xpos == len)
|
||||||
}
|
|
||||||
|
|
||||||
xpos++;
|
|
||||||
if (xpos == len)
|
|
||||||
{
|
|
||||||
xpos = 0;
|
|
||||||
if (interlace)
|
|
||||||
{
|
{
|
||||||
switch (pass)
|
xpos = 0;
|
||||||
|
if (interlace)
|
||||||
{
|
{
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
ypos += 8;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ypos += 4;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
ypos += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ypos >= height)
|
|
||||||
{
|
|
||||||
pass++;
|
|
||||||
switch (pass)
|
switch (pass)
|
||||||
{
|
{
|
||||||
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
ypos = 4;
|
ypos += 8;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ypos = 2;
|
ypos += 4;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
ypos = 1;
|
ypos += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
goto fini;
|
|
||||||
|
if (ypos >= height)
|
||||||
|
{
|
||||||
|
pass++;
|
||||||
|
switch (pass)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
ypos = 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ypos = 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ypos = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto fini;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
ypos++;
|
||||||
ypos++;
|
}
|
||||||
|
|
||||||
|
if (frame_number == 1)
|
||||||
|
{
|
||||||
|
cur_progress++;
|
||||||
|
if ((cur_progress % 16) == 0)
|
||||||
|
gimp_progress_update ((gdouble) cur_progress /
|
||||||
|
(gdouble) max_progress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_number == 1)
|
if (ypos >= height)
|
||||||
{
|
break;
|
||||||
cur_progress++;
|
|
||||||
if ((cur_progress % 16) == 0)
|
|
||||||
gimp_progress_update ((gdouble) cur_progress /
|
|
||||||
(gdouble) max_progress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (ypos >= height)
|
else
|
||||||
break;
|
{
|
||||||
|
ReadJeffsImage (fd, dest, c, len, height, alpha_frame, image, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* v can be < 0 here, indicating an error or encountering an end_code (-2).
|
/* v can be < 0 here, indicating an error or encountering an end_code (-2).
|
||||||
|
@ -1402,16 +1489,118 @@ ReadImage (FILE *fd,
|
||||||
gboolean first = TRUE;
|
gboolean first = TRUE;
|
||||||
|
|
||||||
/* Skip remaining compressed data if any. */
|
/* Skip remaining compressed data if any. */
|
||||||
|
if (! is_jeff_image)
|
||||||
while (LZWReadByte (fd, FALSE, c) >= 0)
|
|
||||||
{
|
{
|
||||||
if (first)
|
while (LZWReadByte (fd, FALSE, c) >= 0)
|
||||||
{
|
{
|
||||||
g_message (_("Too much compressed data, ignoring extra..."));
|
if (first)
|
||||||
first = FALSE;
|
{
|
||||||
|
g_message (_("Too much compressed data, ignoring extra..."));
|
||||||
|
first = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
ReadJeffsImage (FILE *fd,
|
||||||
|
guchar *dest,
|
||||||
|
guchar bpp,
|
||||||
|
gint len,
|
||||||
|
gint height,
|
||||||
|
gboolean alpha_frame,
|
||||||
|
GimpImage **image,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guchar block_size = 255;
|
||||||
|
z_stream zs;
|
||||||
|
guchar block[255];
|
||||||
|
guchar *compressed;
|
||||||
|
guchar *indexes;
|
||||||
|
guint count = 0;
|
||||||
|
guint pos = 0;
|
||||||
|
guint mask = 0;
|
||||||
|
|
||||||
|
/* Indexes are stored as 1, 2, 4, or 8 bits per pixel
|
||||||
|
* in the uncompressed image. */
|
||||||
|
for (gint i = 7; i > 7 - bpp; i--)
|
||||||
|
{
|
||||||
|
if (i >= 0)
|
||||||
|
mask |= 1 << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
compressed = g_malloc (len * height);
|
||||||
|
indexes = g_malloc (len * height);
|
||||||
|
|
||||||
|
/* Image data is stored as a zlib stream, arbitrarily broken
|
||||||
|
* in chunks of 255 bytes or less. We read in the chunk size,
|
||||||
|
* then that many bytes of compressed data to recreate the
|
||||||
|
* full zlib stream. */
|
||||||
|
while (block_size != 0)
|
||||||
|
{
|
||||||
|
if (! ReadOK (fd, &block_size, 1))
|
||||||
|
{
|
||||||
|
read_error (_("image data"), *image, error);
|
||||||
|
g_free (compressed);
|
||||||
|
g_free (indexes);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (block_size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (! ReadOK (fd, block, block_size))
|
||||||
|
{
|
||||||
|
read_error (_("image data"), *image, error);
|
||||||
|
g_free (compressed);
|
||||||
|
g_free (indexes);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (gint i = 0; i < block_size; i++)
|
||||||
|
compressed[i + count] = block[i];
|
||||||
|
|
||||||
|
count += block_size;
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
zs.next_in = (guchar *) compressed;
|
||||||
|
zs.avail_in = count;
|
||||||
|
zs.next_out = (guchar *) indexes;
|
||||||
|
zs.avail_in = len * height;
|
||||||
|
zs.zalloc = Z_NULL;
|
||||||
|
zs.zfree = Z_NULL;
|
||||||
|
zs.opaque = Z_NULL;
|
||||||
|
|
||||||
|
if (inflateInit (&zs) != Z_OK)
|
||||||
|
{
|
||||||
|
read_error (_("image data"), *image, error);
|
||||||
|
g_free (compressed);
|
||||||
|
g_free (indexes);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
inflate (&zs, Z_NO_FLUSH);
|
||||||
|
|
||||||
|
/* We then extract the indexes based on the bits per pixel
|
||||||
|
* set in the header */
|
||||||
|
for (gint i = 0; i < zs.total_out; i++)
|
||||||
|
{
|
||||||
|
for (gint j = 0; j < 8; j += bpp)
|
||||||
|
{
|
||||||
|
dest[pos++] = (indexes[i] & (mask >> j)) >> (8 - bpp - j);
|
||||||
|
|
||||||
|
if (alpha_frame)
|
||||||
|
{
|
||||||
|
dest[pos] = (dest[pos - 1] == Gif89.transparent) ? 0 : 255;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (indexes);
|
||||||
|
g_free (compressed);
|
||||||
|
inflateEnd (&zs);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue