[gimp] plug-ins: port file-gif-save to GIO
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port file-gif-save to GIO
- Date: Thu, 14 Apr 2016 17:50:10 +0000 (UTC)
commit ba8dd1739670e1770f06ad94d7b03bc3c318b99e
Author: Michael Natterer <mitch gimp org>
Date: Thu Apr 14 18:49:00 2016 +0100
plug-ins: port file-gif-save to GIO
plug-ins/common/file-gif-save.c | 767 +++++++++++++++++++++++----------------
1 files changed, 457 insertions(+), 310 deletions(-)
---
diff --git a/plug-ins/common/file-gif-save.c b/plug-ins/common/file-gif-save.c
index c5c9b9c..a708721 100644
--- a/plug-ins/common/file-gif-save.c
+++ b/plug-ins/common/file-gif-save.c
@@ -28,11 +28,8 @@
#include "config.h"
-#include <errno.h>
#include <string.h>
-#include <glib/gstdio.h>
-
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
@@ -84,13 +81,13 @@ static void run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals);
-static gboolean save_image (const gchar *filename,
+static gboolean save_image (GFile *file,
gint32 image_ID,
gint32 drawable_ID,
gint32 orig_image_ID,
GError **error);
-static GimpPDBStatusType sanity_check (const gchar *filename,
+static GimpPDBStatusType sanity_check (GFile *file,
gint32 *image_ID,
GimpRunMode run_mode,
GError **error);
@@ -132,8 +129,8 @@ MAIN ()
{ GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }"
}, \
{ GIMP_PDB_IMAGE, "image", "Image to export" }, \
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to export" }, \
- { GIMP_PDB_STRING, "filename", "The name of the file to export the image in" }, \
- { GIMP_PDB_STRING, "raw-filename", "The name entered" }, \
+ { GIMP_PDB_STRING, "uri", "The name of the URI to export the image in" }, \
+ { GIMP_PDB_STRING, "raw-uri", "The name of the URI to export the image in" }, \
{ GIMP_PDB_INT32, "interlace", "Try to export as interlaced" }, \
{ GIMP_PDB_INT32, "loop", "(animated gif) loop infinitely" }, \
{ GIMP_PDB_INT32, "default-delay", "(animated gif) Default delay between framese in milliseconds"
}, \
@@ -194,6 +191,9 @@ query (void)
gimp_register_file_handler_mime (SAVE_PROC, "image/gif");
gimp_register_save_handler (SAVE_PROC, "gif", "");
+ gimp_register_file_handler_uri (SAVE_PROC);
+
+ gimp_register_file_handler_uri (SAVE2_PROC);
}
static void
@@ -223,21 +223,21 @@ run (const gchar *name,
if (strcmp (name, SAVE_PROC) == 0 ||
strcmp (name, SAVE2_PROC) == 0)
{
- const gchar *filename;
- gint32 image_ID;
- gint32 orig_image_ID;
- gint32 sanitized_image_ID = 0;
- gint32 drawable_ID;
+ GFile *file;
+ gint32 image_ID;
+ gint32 orig_image_ID;
+ gint32 sanitized_image_ID = 0;
+ gint32 drawable_ID;
image_ID = orig_image_ID = param[1].data.d_int32;
drawable_ID = param[2].data.d_int32;
- filename = param[3].data.d_string;
+ file = g_file_new_for_uri (param[3].data.d_string);
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
gimp_ui_init (PLUG_IN_BINARY, FALSE);
- status = sanity_check (filename, &image_ID, run_mode, &error);
+ status = sanity_check (file, &image_ID, run_mode, &error);
/* Get the export options */
if (status == GIMP_PDB_SUCCESS)
@@ -326,7 +326,7 @@ run (const gchar *name,
}
/* Write the image to file */
- if (save_image (param[3].data.d_string,
+ if (save_image (file,
image_ID, drawable_ID, orig_image_ID,
&error))
{
@@ -343,6 +343,8 @@ run (const gchar *name,
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image_ID);
+
+ g_object_unref (file);
}
if (status != GIMP_PDB_SUCCESS && error)
@@ -387,83 +389,105 @@ typedef gint (* ifunptr) (gint x,
gint y);
-static gint find_unused_ia_color (const guchar *pixels,
- gint numpixels,
- gint num_indices,
- gint *colors);
+static gint find_unused_ia_color (const guchar *pixels,
+ gint numpixels,
+ gint num_indices,
+ gint *colors);
-static void special_flatten_indexed_alpha (guchar *pixels,
- gint transparent,
- gint numpixels);
+static void special_flatten_indexed_alpha (guchar *pixels,
+ gint transparent,
+ gint numpixels);
-static gint colors_to_bpp (gint colors);
-static gint bpp_to_colors (gint bpp);
-static gint get_pixel (gint x,
- gint y);
-static gint gif_next_pixel (ifunptr getpixel);
+static gint colors_to_bpp (gint colors);
+static gint bpp_to_colors (gint bpp);
+static gint get_pixel (gint x,
+ gint y);
+static gint gif_next_pixel (ifunptr getpixel);
static void bump_pixel (void);
-static void gif_encode_header (FILE *fp,
- gboolean gif89,
- gint width,
- gint height,
- gint background,
- gint bpp,
- gint *red,
- gint *green,
- gint *blue,
- ifunptr get_pixel);
-static void gif_encode_graphic_control_ext (FILE *fp,
- gint disposal,
- gint delay89,
- gint n_frames,
- gint width,
- gint height,
- gint transparent,
- gint bpp,
- ifunptr get_pixel);
-static void gif_encode_image_data (FILE *fp,
- gint width,
- gint height,
- gint interlace,
- gint bpp,
- ifunptr get_pixel,
- gint offset_x,
- gint offset_y);
-static void gif_encode_close (FILE *fp);
-static void gif_encode_loop_ext (FILE *fp,
- guint n_loops);
-static void gif_encode_comment_ext (FILE *fp,
- const gchar *comment);
+static gboolean gif_encode_header (GOutputStream *output,
+ gboolean gif89,
+ gint width,
+ gint height,
+ gint background,
+ gint bpp,
+ gint *red,
+ gint *green,
+ gint *blue,
+ ifunptr get_pixel,
+ GError **error);
+static gboolean gif_encode_graphic_control_ext (GOutputStream *output,
+ gint disposal,
+ gint delay89,
+ gint n_frames,
+ gint width,
+ gint height,
+ gint transparent,
+ gint bpp,
+ ifunptr get_pixel,
+ GError **error);
+static gboolean gif_encode_image_data (GOutputStream *output,
+ gint width,
+ gint height,
+ gint interlace,
+ gint bpp,
+ ifunptr get_pixel,
+ gint offset_x,
+ gint offset_y,
+ GError **error);
+static gboolean gif_encode_close (GOutputStream *output,
+ GError **error);
+static gboolean gif_encode_loop_ext (GOutputStream *output,
+ guint n_loops,
+ GError **error);
+static gboolean gif_encode_comment_ext (GOutputStream *output,
+ const gchar *comment,
+ GError **error);
static gint rowstride;
static guchar *pixels;
static gint cur_progress;
static gint max_progress;
-static void compress (gint init_bits,
- FILE *outfile,
- ifunptr ReadValue);
-static void no_compress (gint init_bits,
- FILE *outfile,
- ifunptr ReadValue);
-static void rle_compress (gint init_bits,
- FILE *outfile,
- ifunptr ReadValue);
-static void normal_compress (gint init_bits,
- FILE *outfile,
- ifunptr ReadValue);
-
-static void put_word (gint w,
- FILE *outfile);
-static void output (FILE *outfile,
- gint code);
-static void cl_block (FILE *outfile);
-static void cl_hash (glong hsize);
-static void char_init (void);
-static void char_out (FILE *outfile,
- gint c);
-static void flush_char (FILE *outfile);
+static gboolean compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error);
+static gboolean no_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error);
+static gboolean rle_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error);
+static gboolean normal_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error);
+
+static gboolean put_byte (GOutputStream *output,
+ guchar b,
+ GError **error);
+static gboolean put_word (GOutputStream *output,
+ gint w,
+ GError **error);
+static gboolean put_string (GOutputStream *output,
+ const gchar *s,
+ GError **error);
+static gboolean output_code (GOutputStream *output,
+ gint code,
+ GError **error);
+static gboolean cl_block (GOutputStream *output,
+ GError **error);
+static void cl_hash (glong hsize);
+
+static void char_init (void);
+static gboolean char_out (GOutputStream *output,
+ gint c,
+ GError **error);
+static gboolean char_flush (GOutputStream *output,
+ GError **error);
static gint
@@ -616,7 +640,7 @@ parse_disposal_tag (const gchar *str)
static GimpPDBStatusType
-sanity_check (const gchar *filename,
+sanity_check (GFile *file,
gint32 *image_ID,
GimpRunMode run_mode,
GError **error)
@@ -636,7 +660,7 @@ sanity_check (const gchar *filename,
_("Unable to export '%s'. "
"The GIF file format does not support images that are "
"more than %d pixels wide or tall."),
- gimp_filename_to_utf8 (filename), G_MAXUSHORT);
+ gimp_file_get_utf8_name (file), G_MAXUSHORT);
return GIMP_PDB_EXECUTION_ERROR;
}
@@ -686,16 +710,16 @@ sanity_check (const gchar *filename,
static gboolean
-save_image (const gchar *filename,
- gint32 image_ID,
- gint32 drawable_ID,
- gint32 orig_image_ID,
- GError **error)
+save_image (GFile *file,
+ gint32 image_ID,
+ gint32 drawable_ID,
+ gint32 orig_image_ID,
+ GError **error)
{
GeglBuffer *buffer;
GimpImageType drawable_type;
const Babl *format = NULL;
- FILE *outfile;
+ GOutputStream *output;
gint Red[MAXCOLORS];
gint Green[MAXCOLORS];
gint Blue[MAXCOLORS];
@@ -731,7 +755,7 @@ save_image (const gchar *filename,
parasite = gimp_parasite_new ("gimp-comment",
GIMP_PARASITE_PERSISTENT,
strlen (globalcomment) + 1,
- (void*) globalcomment);
+ (gpointer) globalcomment);
gimp_image_attach_parasite (orig_image_ID, parasite);
gimp_parasite_free (parasite);
}
@@ -839,16 +863,27 @@ save_image (const gchar *filename,
/* init the progress meter */
gimp_progress_init_printf (_("Exporting '%s'"),
- gimp_filename_to_utf8 (filename));
+ gimp_file_get_utf8_name (file));
/* open the destination file for writing */
- outfile = g_fopen (filename, "wb");
- if (!outfile)
+ output = G_OUTPUT_STREAM (g_file_replace (file,
+ NULL, FALSE, G_FILE_CREATE_NONE,
+ NULL, error));
+ if (output)
+ {
+ GDataOutputStream *data_output;
+
+ data_output = g_data_output_stream_new (output);
+ g_object_unref (output);
+
+ g_data_output_stream_set_byte_order (data_output,
+ G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
+
+ output = G_OUTPUT_STREAM (data_output);
+ }
+ else
{
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Could not open '%s' for writing: %s"),
- gimp_filename_to_utf8 (filename), g_strerror (errno));
return FALSE;
}
@@ -879,20 +914,24 @@ save_image (const gchar *filename,
cols = gimp_image_width (image_ID);
rows = gimp_image_height (image_ID);
Interlace = gsvals.interlace;
- gif_encode_header (outfile, is_gif89, cols, rows, bgindex,
- BitsPerPixel, Red, Green, Blue, get_pixel);
+ if (! gif_encode_header (output, is_gif89, cols, rows, bgindex,
+ BitsPerPixel, Red, Green, Blue, get_pixel,
+ error))
+ return FALSE;
/* If the image has multiple layers it'll be made into an animated
* GIF, so write out the infinite-looping extension
*/
if ((nlayers > 1) && (gsvals.loop))
- gif_encode_loop_ext (outfile, 0);
+ if (! gif_encode_loop_ext (output, 0, error))
+ return FALSE;
/* Write comment extension - mustn't be written before the looping ext. */
if (gsvals.save_comment && globalcomment)
{
- gif_encode_comment_ext (outfile, globalcomment);
+ if (! gif_encode_comment_ext (output, globalcomment, error))
+ return FALSE;
}
@@ -1001,18 +1040,24 @@ save_image (const gchar *filename,
Delay89 = 1;
}
- gif_encode_graphic_control_ext (outfile, Disposal, Delay89, nlayers,
- cols, rows,
- transparent,
- useBPP,
- get_pixel);
+ if (! gif_encode_graphic_control_ext (output,
+ Disposal, Delay89, nlayers,
+ cols, rows,
+ transparent,
+ useBPP,
+ get_pixel,
+ error))
+ return FALSE;
}
- gif_encode_image_data (outfile, cols, rows,
- (rows > 4) ? gsvals.interlace : 0,
- useBPP,
- get_pixel,
- offset_x, offset_y);
+ if (! gif_encode_image_data (output, cols, rows,
+ (rows > 4) ? gsvals.interlace : 0,
+ useBPP,
+ get_pixel,
+ offset_x, offset_y,
+ error))
+ return FALSE;
+
gimp_progress_update (1.0);
g_object_unref (buffer);
@@ -1022,7 +1067,8 @@ save_image (const gchar *filename,
g_free (layers);
- gif_encode_close (outfile);
+ if (! gif_encode_close (output, error))
+ return FALSE;
return TRUE;
}
@@ -1446,17 +1492,18 @@ gif_next_pixel (ifunptr getpixel)
/* public */
-static void
-gif_encode_header (FILE *fp,
- gboolean gif89,
- gint GWidth,
- gint GHeight,
- gint Background,
- gint BitsPerPixel,
- gint Red[],
- gint Green[],
- gint Blue[],
- ifunptr get_pixel)
+static gboolean
+gif_encode_header (GOutputStream *output,
+ gboolean gif89,
+ gint GWidth,
+ gint GHeight,
+ gint Background,
+ gint BitsPerPixel,
+ gint Red[],
+ gint Green[],
+ gint Blue[],
+ ifunptr get_pixel,
+ GError **error)
{
gint B;
gint RWidth, RHeight;
@@ -1489,13 +1536,15 @@ gif_encode_header (FILE *fp,
/*
* Write the Magic header
*/
- fwrite (gif89 ? "GIF89a" : "GIF87a", 1, 6, fp);
+ if (! put_string (output, gif89 ? "GIF89a" : "GIF87a", error))
+ return FALSE;
/*
* Write out the screen width and height
*/
- put_word (RWidth, fp);
- put_word (RHeight, fp);
+ if (! put_word (output, RWidth, error) ||
+ ! put_word (output, RHeight, error))
+ return FALSE;
/*
* Indicate that there is a global color map
@@ -1515,40 +1564,47 @@ gif_encode_header (FILE *fp,
/*
* Write it out
*/
- fputc (B, fp);
+ if (! put_byte (output, B, error))
+ return FALSE;
/*
* Write out the Background color
*/
- fputc (Background, fp);
+ if (! put_byte (output, Background, error))
+ return FALSE;
/*
* Byte of 0's (future expansion)
*/
- fputc (0, fp);
+ if (! put_byte (output, 0, error))
+ return FALSE;
/*
* Write out the Global Color Map
*/
for (i = 0; i < ColorMapSize; i++)
{
- fputc (Red[i], fp);
- fputc (Green[i], fp);
- fputc (Blue[i], fp);
+ if (! put_byte (output, Red[i], error) ||
+ ! put_byte (output, Green[i], error) ||
+ ! put_byte (output, Blue[i], error))
+ return FALSE;
}
+
+ return TRUE;
}
-static void
-gif_encode_graphic_control_ext (FILE *fp,
- int Disposal,
- int Delay89,
- int NumFramesInImage,
- int GWidth,
- int GHeight,
- int Transparent,
- int BitsPerPixel,
- ifunptr get_pixel)
+static gboolean
+gif_encode_graphic_control_ext (GOutputStream *output,
+ int Disposal,
+ int Delay89,
+ int NumFramesInImage,
+ int GWidth,
+ int GHeight,
+ int Transparent,
+ int BitsPerPixel,
+ ifunptr get_pixel,
+ GError **error)
{
Width = GWidth;
Height = GHeight;
@@ -1574,52 +1630,63 @@ gif_encode_graphic_control_ext (FILE *fp,
if ( (Transparent >= 0) || (NumFramesInImage > 1) )
{
/* Extension Introducer - fixed. */
- fputc ('!', fp);
+ if (! put_byte (output, '!', error))
+ return FALSE;
+
/* Graphic Control Label - fixed. */
- fputc (0xf9, fp);
+ if (! put_byte (output, 0xf9, error))
+ return FALSE;
+
/* Block Size - fixed. */
- fputc (4, fp);
+ if (! put_byte (output, 4, error))
+ return FALSE;
/* Packed Fields - XXXdddut (d=disposal, u=userInput, t=transFlag) */
/* s8421 */
- fputc ( ((Transparent >= 0) ? 0x01 : 0x00) /* TRANSPARENCY */
+ if (! put_byte (output,
+ ((Transparent >= 0) ? 0x01 : 0x00) /* TRANSPARENCY */
- /* DISPOSAL */
- | ((NumFramesInImage > 1) ? (Disposal << 2) : 0x00 ),
- /* 0x03 or 0x01 build frames cumulatively */
- /* 0x02 clears frame before drawing */
- /* 0x00 'don't care' */
+ /* DISPOSAL */
+ | ((NumFramesInImage > 1) ? (Disposal << 2) : 0x00 ),
+ /* 0x03 or 0x01 build frames cumulatively */
+ /* 0x02 clears frame before drawing */
+ /* 0x00 'don't care' */
- fp);
+ error))
+ return FALSE;
- fputc (Delay89 & 255, fp);
- fputc ((Delay89 >> 8) & 255, fp);
+ if (! put_word (output, Delay89, error))
+ return FALSE;
- fputc (Transparent, fp);
- fputc (0, fp);
+ if (! put_byte (output, Transparent, error) ||
+ ! put_byte (output, 0, error))
+ return FALSE;
}
+
+ return TRUE;
}
-static void
-gif_encode_image_data (FILE *fp,
- int GWidth,
- int GHeight,
- int GInterlace,
- int BitsPerPixel,
- ifunptr get_pixel,
- gint offset_x,
- gint offset_y)
+static gboolean
+gif_encode_image_data (GOutputStream *output,
+ int GWidth,
+ int GHeight,
+ int GInterlace,
+ int BitsPerPixel,
+ ifunptr get_pixel,
+ gint offset_x,
+ gint offset_y,
+ GError **error)
{
- int LeftOfs, TopOfs;
- int InitCodeSize;
+ gint LeftOfs, TopOfs;
+ gint InitCodeSize;
Interlace = GInterlace;
- Width = GWidth;
- Height = GHeight;
- LeftOfs = (int) offset_x;
- TopOfs = (int) offset_y;
+ Width = GWidth;
+ Height = GHeight;
+ LeftOfs = (gint) offset_x;
+ TopOfs = (gint) offset_y;
/*
* Calculate number of bits we are expecting
@@ -1647,39 +1714,50 @@ gif_encode_image_data (FILE *fp,
/*
* Write an Image separator
*/
- fputc (',', fp);
+ if (! put_byte (output, ',', error))
+ return FALSE;
/*
* Write the Image header
*/
- put_word (LeftOfs, fp);
- put_word (TopOfs, fp);
- put_word (Width, fp);
- put_word (Height, fp);
+ if (! put_word (output, LeftOfs, error) ||
+ ! put_word (output, TopOfs, error) ||
+ ! put_word (output, Width, error) ||
+ ! put_word (output, Height, error))
+ return FALSE;
/*
* Write out whether or not the image is interlaced
*/
if (Interlace)
- fputc (0x40, fp);
+ {
+ if (! put_byte (output, 0x40, error))
+ return FALSE;
+ }
else
- fputc (0x00, fp);
+ {
+ if (! put_byte (output, 0x00, error))
+ return FALSE;
+ }
/*
* Write out the initial code size
*/
- fputc (InitCodeSize, fp);
+ if (! put_byte (output, InitCodeSize, error))
+ return FALSE;
/*
* Go and actually compress the data
*/
- compress (InitCodeSize + 1, fp, get_pixel);
+ if (! compress (output, InitCodeSize + 1, get_pixel, error))
+ return FALSE;
/*
* Write out a Zero-length packet (to end the series)
*/
- fputc (0, fp);
+ if (! put_byte (output, 0, error))
+ return FALSE;
#if 0
/***************************/
@@ -1702,73 +1780,97 @@ gif_encode_image_data (FILE *fp,
*/
curx = cury = 0;
#endif
+
+ return TRUE;
}
-static void
-gif_encode_close (FILE *fp)
+static gboolean
+gif_encode_close (GOutputStream *output,
+ GError **error)
{
/*
* Write the GIF file terminator
*/
- fputc (';', fp);
+ if (! put_byte (output, ';', error))
+ return FALSE;
/*
* And close the file
*/
- fclose (fp);
+ return g_output_stream_close (output, NULL, error);
}
-static void
-gif_encode_loop_ext (FILE *fp,
- guint num_loops)
+static gboolean
+gif_encode_loop_ext (GOutputStream *output,
+ guint num_loops,
+ GError **error)
{
- fputc (0x21, fp);
- fputc (0xff, fp);
- fputc (0x0b, fp);
- fputs ("NETSCAPE2.0", fp);
- fputc (0x03, fp);
- fputc (0x01, fp);
- put_word (num_loops, fp);
- fputc (0x00, fp);
+ return (put_byte (output, 0x21, error) &&
+ put_byte (output, 0xff, error) &&
+ put_byte (output, 0x0b, error) &&
+ put_string (output, "NETSCAPE2.0", error) &&
+ put_byte (output, 0x03, error) &&
+ put_byte (output, 0x01, error) &&
+ put_word (output, num_loops, error) &&
+ put_byte (output, 0x00, error));
/* NOTE: num_loops == 0 means 'loop infinitely' */
}
-static void
-gif_encode_comment_ext (FILE *fp,
- const gchar *comment)
+static gboolean
+gif_encode_comment_ext (GOutputStream *output,
+ const gchar *comment,
+ GError **error)
{
if (!comment || !*comment)
- return;
+ return TRUE;
if (strlen (comment) > 240)
{
g_printerr ("GIF: warning:"
"comment too large - comment block not written.\n");
- return;
+ return TRUE;
}
- fputc (0x21, fp);
- fputc (0xfe, fp);
- fputc (strlen (comment), fp);
- fputs (comment, fp);
- fputc (0x00, fp);
+ return (put_byte (output, 0x21, error) &&
+ put_byte (output, 0xfe, error) &&
+ put_byte (output, strlen (comment), error) &&
+ put_string (output, comment, error) &&
+ put_byte (output, 0x00, error));
}
-
/*
- * Write out a word to the GIF file
+ * Write stuff to the GIF file
*/
-static void
-put_word (int w,
- FILE *fp)
+static gboolean
+put_byte (GOutputStream *output,
+ guchar b,
+ GError **error)
+{
+ return g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (output),
+ b, NULL, error);
+}
+
+static gboolean
+put_word (GOutputStream *output,
+ gint w,
+ GError **error)
+{
+ return g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (output),
+ w, NULL, error);
+}
+
+static gboolean
+put_string (GOutputStream *output,
+ const gchar *s,
+ GError **error)
{
- fputc (w & 0xff, fp);
- fputc ((w / 256) & 0xff, fp);
+ return g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (output),
+ s, NULL, error);
}
@@ -1785,9 +1887,9 @@ put_word (int w,
* General DEFINEs
*/
-#define GIF_BITS 12
+#define GIF_BITS 12
-#define HSIZE 5003 /* 80% occupancy */
+#define HSIZE 5003 /* 80% occupancy */
/*
* GIF Image compression - modified 'compress'
@@ -1803,9 +1905,9 @@ put_word (int w,
*
*/
-static int n_bits; /* number of bits/code */
-static int maxbits = GIF_BITS; /* user settable max # bits/code */
-static gint maxcode; /* maximum code, given n_bits */
+static gint n_bits; /* number of bits/code */
+static gint maxbits = GIF_BITS; /* user settable max # bits/code */
+static gint maxcode; /* maximum code, given n_bits */
static gint maxmaxcode = (gint) 1 << GIF_BITS; /* should NEVER generate this code */
#ifdef COMPATIBLE /* But wrong! */
#define MAXCODE(Mn_bits) ((gint) 1 << (Mn_bits) - 1)
@@ -1813,8 +1915,8 @@ static gint maxmaxcode = (gint) 1 << GIF_BITS; /* should NEVER generate t
#define MAXCODE(Mn_bits) (((gint) 1 << (Mn_bits)) - 1)
#endif /*COMPATIBLE */
-static glong htab[HSIZE];
-static unsigned short codetab[HSIZE];
+static glong htab[HSIZE];
+static gushort codetab[HSIZE];
#define HashTabOf(i) htab[i]
#define CodeTabOf(i) codetab[i]
@@ -1829,11 +1931,11 @@ static gint free_ent = 0; /* first unused entry */
* block compression parameters -- after all codes are used up,
* and compression rate changes, start over.
*/
-static int clear_flg = 0;
+static gint clear_flg = 0;
-static int offset;
-static long int in_count = 1; /* length of input */
-static long int out_count = 0; /* # of codes output (for debugging) */
+static gint offset;
+static glong in_count = 1; /* length of input */
+static glong out_count = 0; /* # of codes output (for debugging) */
/*
* compress stdin to stdout
@@ -1851,11 +1953,10 @@ static long int out_count = 0; /* # of codes output (for debugging) */
* questions about this implementation to ames!jaw.
*/
-static gint g_init_bits;
-
-static int ClearCode;
-static int EOFCode;
+static gint g_init_bits;
+static gint ClearCode;
+static gint EOFCode;
static gulong cur_accum;
static gint cur_bits;
@@ -1870,23 +1971,25 @@ static gulong masks[] =
};
-static void
-compress (int init_bits,
- FILE *outfile,
- ifunptr ReadValue)
+static gboolean
+compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error)
{
if (FALSE)
- no_compress (init_bits, outfile, ReadValue);
+ return no_compress (output, init_bits, ReadValue, error);
else if (FALSE)
- rle_compress (init_bits, outfile, ReadValue);
+ return rle_compress (output, init_bits, ReadValue, error);
else
- normal_compress (init_bits, outfile, ReadValue);
+ return normal_compress (output, init_bits, ReadValue, error);
}
-static void
-no_compress (gint init_bits,
- FILE *outfile,
- ifunptr ReadValue)
+static gboolean
+no_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error)
{
glong fcode;
gint i /* = 0 */ ;
@@ -1921,7 +2024,7 @@ no_compress (gint init_bits,
maxcode = MAXCODE (n_bits);
- char_init ();
+ char_init();
ent = gif_next_pixel (ReadValue);
@@ -1933,8 +2036,8 @@ no_compress (gint init_bits,
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
- output (outfile, (gint) ClearCode);
-
+ if (! output_code (output, (gint) ClearCode, error))
+ return FALSE;
while ((c = gif_next_pixel (ReadValue)) != EOF)
{
@@ -1943,7 +2046,9 @@ no_compress (gint init_bits,
fcode = (long) (((long) c << maxbits) + ent);
i = (((gint) c << hshift) ^ ent); /* xor hashing */
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
ent = c;
@@ -1953,30 +2058,39 @@ no_compress (gint init_bits,
HashTabOf (i) = fcode;
}
else
- cl_block (outfile);
+ {
+ if (! cl_block (output, error))
+ return FALSE;
+ }
}
/*
* Put out the final code.
*/
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
- output (outfile, (gint) EOFCode);
+
+ if (! output_code (output, (gint) EOFCode, error))
+ return FALSE;
+
+ return TRUE;
}
-static void
-rle_compress (int init_bits,
- FILE *outfile,
- ifunptr ReadValue)
+static gboolean
+rle_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error)
{
- long fcode;
- gint i /* = 0 */ ;
- int c, last;
- gint ent;
- gint disp;
- gint hsize_reg;
- int hshift;
-
+ glong fcode;
+ gint i /* = 0 */ ;
+ gint c, last;
+ gint ent;
+ gint disp;
+ gint hsize_reg;
+ gint hshift;
/*
* Set up the globals: g_init_bits - initial number of bits
@@ -2016,8 +2130,8 @@ rle_compress (int init_bits,
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
- output (outfile, (gint) ClearCode);
-
+ if (! output_code (output, (gint) ClearCode, error))
+ return FALSE;
while ((c = gif_next_pixel (ReadValue)) != EOF)
@@ -2052,7 +2166,9 @@ rle_compress (int init_bits,
goto probe;
}
nomatch:
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
last = ent = c;
if (free_ent < maxmaxcode)
@@ -2061,30 +2177,39 @@ rle_compress (int init_bits,
HashTabOf (i) = fcode;
}
else
- cl_block (outfile);
+ {
+ if (! cl_block (output, error))
+ return FALSE;
+ }
}
/*
* Put out the final code.
*/
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
- output (outfile, (gint) EOFCode);
+
+ if (! output_code (output, (gint) EOFCode, error))
+ return FALSE;
+
+ return TRUE;
}
-static void
-normal_compress (int init_bits,
- FILE *outfile,
- ifunptr ReadValue)
+static gboolean
+normal_compress (GOutputStream *output,
+ gint init_bits,
+ ifunptr ReadValue,
+ GError **error)
{
- long fcode;
- gint i /* = 0 */ ;
- int c;
- gint ent;
- gint disp;
- gint hsize_reg;
- int hshift;
-
+ glong fcode;
+ gint i /* = 0 */ ;
+ gint c;
+ gint ent;
+ gint disp;
+ gint hsize_reg;
+ gint hshift;
/*
* Set up the globals: g_init_bits - initial number of bits
@@ -2112,7 +2237,7 @@ normal_compress (int init_bits,
maxcode = MAXCODE (n_bits);
- char_init ();
+ char_init();
ent = gif_next_pixel (ReadValue);
@@ -2124,7 +2249,8 @@ normal_compress (int init_bits,
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
- output (outfile, (gint) ClearCode);
+ if (! output_code (output, (gint) ClearCode, error))
+ return FALSE;
while ((c = gif_next_pixel (ReadValue)) != EOF)
@@ -2156,7 +2282,9 @@ normal_compress (int init_bits,
if ((long) HashTabOf (i) > 0)
goto probe;
nomatch:
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
ent = c;
if (free_ent < maxmaxcode)
@@ -2165,15 +2293,24 @@ normal_compress (int init_bits,
HashTabOf (i) = fcode;
}
else
- cl_block (outfile);
+ {
+ if (! cl_block (output, error))
+ return FALSE;
+ }
}
/*
* Put out the final code.
*/
- output (outfile, (gint) ent);
+ if (! output_code (output, (gint) ent, error))
+ return FALSE;
+
++out_count;
- output (outfile, (gint) EOFCode);
+
+ if (! output_code (output, (gint) EOFCode, error))
+ return FALSE;
+
+ return TRUE;
}
@@ -2194,9 +2331,10 @@ normal_compress (int init_bits,
* code in turn. When the buffer fills up empty it and start over.
*/
-static void
-output (FILE *outfile,
- gint code)
+static gboolean
+output_code (GOutputStream *output,
+ gint code,
+ GError **error)
{
cur_accum &= masks[cur_bits];
@@ -2209,7 +2347,9 @@ output (FILE *outfile,
while (cur_bits >= 8)
{
- char_out (outfile, (guint) (cur_accum & 0xff));
+ if (! char_out (output, (guchar) (cur_accum & 0xff), error))
+ return FALSE;
+
cur_accum >>= 8;
cur_bits -= 8;
}
@@ -2222,14 +2362,11 @@ output (FILE *outfile,
{
if (clear_flg)
{
-
maxcode = MAXCODE (n_bits = g_init_bits);
clear_flg = 0;
-
}
else
{
-
++n_bits;
if (n_bits == maxbits)
maxcode = maxmaxcode;
@@ -2245,37 +2382,37 @@ output (FILE *outfile,
*/
while (cur_bits > 0)
{
- char_out (outfile, (guint) (cur_accum & 0xff));
+ if (! char_out (output, (guchar) (cur_accum & 0xff), error))
+ return FALSE;
+
cur_accum >>= 8;
cur_bits -= 8;
}
- flush_char (outfile);
-
- fflush (outfile);
-
- if (ferror (outfile))
- g_message (_("Error writing output file."));
+ if (! char_flush (output, error))
+ return FALSE;
}
+
+ return TRUE;
}
/*
* Clear out the hash table
*/
-static void
-cl_block (FILE *outfile) /* table clear for block compress */
+static gboolean
+cl_block (GOutputStream *output,
+ GError **error) /* table clear for block compress */
{
cl_hash ((glong) hsize);
free_ent = ClearCode + 2;
clear_flg = 1;
- output (outfile, (gint) ClearCode);
+ return output_code (output, (gint) ClearCode, error);
}
static void
cl_hash (glong hsize) /* reset code table */
{
-
glong *htab_p = htab + hsize;
long i;
@@ -2310,9 +2447,7 @@ cl_hash (glong hsize) /* reset code table */
/******************************************************************************
- *
* GIF Specific routines
- *
******************************************************************************/
/*
@@ -2338,27 +2473,39 @@ static char accum[256];
* Add a character to the end of the current packet, and if it is 254
* characters, flush the packet to disk.
*/
-static void
-char_out (FILE *outfile,
- gint c)
+static gboolean
+char_out (GOutputStream *output,
+ gint c,
+ GError **error)
{
accum[a_count++] = c;
+
if (a_count >= 254)
- flush_char (outfile);
+ return char_flush (output, error);
+
+ return TRUE;
}
/*
* Flush the packet to disk, and reset the accumulator
*/
-static void
-flush_char (FILE *outfile)
+static gboolean
+char_flush (GOutputStream *output,
+ GError **error)
{
if (a_count > 0)
{
- fputc (a_count, outfile);
- fwrite (accum, 1, a_count, outfile);
+ if (! put_byte (output, a_count, error))
+ return FALSE;
+
+ if (! g_output_stream_write_all (output, accum, a_count,
+ NULL, NULL, error))
+ return FALSE;
+
a_count = 0;
}
+
+ return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]