[gimp] plug-ins: port file-tiff to GIO
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port file-tiff to GIO
- Date: Tue, 19 Apr 2016 22:10:14 +0000 (UTC)
commit 4cf6dad0a0811d71f8f93d35e9a6fb4dc4effe48
Author: Michael Natterer <mitch gimp org>
Date: Tue Apr 19 23:07:34 2016 +0100
plug-ins: port file-tiff to GIO
Using code from gegl:tiff-load and gegl:tiff-save which has a mode for
local buffering if the input/output streams don't support seeking.
Unfortunately this code is broken and is disabled for now.
plug-ins/file-tiff/file-tiff-io.c | 367 ++++++++++++++++++++++++++++++++++---
plug-ins/file-tiff/file-tiff.c | 6 +-
2 files changed, 346 insertions(+), 27 deletions(-)
---
diff --git a/plug-ins/file-tiff/file-tiff-io.c b/plug-ins/file-tiff/file-tiff-io.c
index c6e5520..03df383 100644
--- a/plug-ins/file-tiff/file-tiff-io.c
+++ b/plug-ins/file-tiff/file-tiff-io.c
@@ -32,12 +32,41 @@
#include "file-tiff-io.h"
-static void tiff_warning (const gchar *module,
- const gchar *fmt,
- va_list ap) G_GNUC_PRINTF (2, 0);
-static void tiff_error (const gchar *module,
- const gchar *fmt,
- va_list ap) G_GNUC_PRINTF (2, 0);
+typedef struct
+{
+ GFile *file;
+ GObject *stream;
+ GInputStream *input;
+ GOutputStream *output;
+ gboolean can_seek;
+
+ gchar *buffer;
+ gsize allocated;
+ gsize used;
+ gsize position;
+} TiffIO;
+
+
+static void tiff_io_warning (const gchar *module,
+ const gchar *fmt,
+ va_list ap) G_GNUC_PRINTF (2, 0);
+static void tiff_io_error (const gchar *module,
+ const gchar *fmt,
+ va_list ap) G_GNUC_PRINTF (2, 0);
+static tsize_t tiff_io_read (thandle_t handle,
+ tdata_t buffer,
+ tsize_t size);
+static tsize_t tiff_io_write (thandle_t handle,
+ tdata_t buffer,
+ tsize_t size);
+static toff_t tiff_io_seek (thandle_t handle,
+ toff_t offset,
+ gint whence);
+static gint tiff_io_close (thandle_t handle);
+static toff_t tiff_io_get_file_size (thandle_t handle);
+
+
+static TiffIO tiff_io = { 0, };
TIFF *
@@ -45,33 +74,51 @@ tiff_open (GFile *file,
const gchar *mode,
GError **error)
{
- gchar *filename = g_file_get_path (file);
+ TIFFSetWarningHandler (tiff_io_warning);
+ TIFFSetErrorHandler (tiff_io_error);
- TIFFSetWarningHandler (tiff_warning);
- TIFFSetErrorHandler (tiff_error);
+ tiff_io.file = file;
-#ifdef G_OS_WIN32
- gunichar2 *utf16_filename = g_utf8_to_utf16 (filename, -1, NULL, NULL, error);
-
- if (utf16_filename)
+ if (! strcmp (mode, "r"))
{
- TIFF *tif = TIFFOpenW (utf16_filename, mode);
+ tiff_io.input = G_INPUT_STREAM (g_file_read (file, NULL, error));
+ if (! tiff_io.input)
+ return NULL;
- g_free (utf16_filename);
+ tiff_io.stream = G_OBJECT (tiff_io.input);
+ }
+ else
+ {
+ tiff_io.output = G_OUTPUT_STREAM (g_file_replace (file,
+ NULL, FALSE,
+ G_FILE_CREATE_NONE,
+ NULL, error));
+ if (! tiff_io.output)
+ return FALSE;
- return tif;
+ tiff_io.stream = G_OBJECT (tiff_io.output);
}
- return NULL;
-#else
- return TIFFOpen (filename, mode);
+#if 0
+#warning FIXME !can_seek code is broken
+ tiff_io.can_seek = g_seekable_can_seek (G_SEEKABLE (tiff_io.stream));
#endif
+ tiff_io.can_seek = TRUE;
+
+ return TIFFClientOpen ("file-tiff", mode,
+ (thandle_t) &tiff_io,
+ tiff_io_read,
+ tiff_io_write,
+ tiff_io_seek,
+ tiff_io_close,
+ tiff_io_get_file_size,
+ NULL, NULL);
}
static void
-tiff_warning (const gchar *module,
- const gchar *fmt,
- va_list ap)
+tiff_io_warning (const gchar *module,
+ const gchar *fmt,
+ va_list ap)
{
gint tag = 0;
@@ -116,9 +163,9 @@ tiff_warning (const gchar *module,
}
static void
-tiff_error (const gchar *module,
- const gchar *fmt,
- va_list ap)
+tiff_io_error (const gchar *module,
+ const gchar *fmt,
+ va_list ap)
{
/* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=132297
* Ignore the errors related to random access and JPEG compression
@@ -128,3 +175,273 @@ tiff_error (const gchar *module,
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
}
+
+static tsize_t
+tiff_io_read (thandle_t handle,
+ tdata_t buffer,
+ tsize_t size)
+{
+ TiffIO *io = (TiffIO *) handle;
+ GError *error = NULL;
+ gssize read = -1;
+
+ if (io->can_seek)
+ {
+ gsize bytes_read = 0;
+
+ if (! g_input_stream_read_all (io->input,
+ (void *) buffer, (gsize) size,
+ &bytes_read,
+ NULL, &error))
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ read = bytes_read;
+ }
+ else
+ {
+ if (io->position + size > io->used)
+ {
+ gsize missing;
+ gsize bytes_read;
+
+ missing = io->position + size - io->used;
+
+ if (io->used + missing > io->allocated)
+ {
+ gchar *new_buffer;
+ gsize new_size = 1;
+ gsize needed;
+
+ needed = io->used + missing - io->allocated;
+ while (new_size < io->allocated + needed)
+ new_size *= 2;
+
+ new_buffer = g_try_realloc (io->buffer, new_size);
+ if (! new_buffer)
+ return -1;
+
+ io->buffer = new_buffer;
+ io->allocated = new_size;
+ }
+
+ if (! g_input_stream_read_all (io->input,
+ (void *) (io->buffer + io->used),
+ missing,
+ &bytes_read, NULL, &error))
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ io->used += bytes_read;
+ }
+
+ g_assert (io->position + size <= io->used);
+
+ memcpy (buffer, io->buffer + io->position, size);
+ io->position += size;
+
+ read = size;
+ }
+
+ return (tsize_t) read;
+}
+
+static tsize_t
+tiff_io_write (thandle_t handle,
+ tdata_t buffer,
+ tsize_t size)
+{
+ TiffIO *io = (TiffIO *) handle;
+ GError *error = NULL;
+ gssize written = -1;
+
+ if (io->can_seek)
+ {
+ gsize bytes_written = 0;
+
+ if (! g_output_stream_write_all (io->output,
+ (void *) buffer, (gsize) size,
+ &bytes_written,
+ NULL, &error))
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ written = bytes_written;
+ }
+ else
+ {
+ if (io->position + size > io->allocated)
+ {
+ gchar *new_buffer;
+ gsize new_size;
+
+ new_size = io->position + size;
+
+ new_buffer = g_try_realloc (io->buffer, new_size);
+ if (! new_buffer)
+ return -1;
+
+ io->buffer = new_buffer;
+ io->allocated = new_size;
+ }
+
+ g_assert (io->position + size <= io->allocated);
+
+ memcpy (io->buffer + io->position, buffer, size);
+ io->position += size;
+
+ io->used = MAX (io->used, io->position);
+
+ written = size;
+ }
+
+ return (tsize_t) written;
+}
+
+static GSeekType
+lseek_to_seek_type (gint whence)
+{
+ switch (whence)
+ {
+ default:
+ case SEEK_SET:
+ return G_SEEK_SET;
+
+ case SEEK_CUR:
+ return G_SEEK_CUR;
+
+ case SEEK_END:
+ return G_SEEK_END;
+ }
+}
+
+static toff_t
+tiff_io_seek (thandle_t handle,
+ toff_t offset,
+ gint whence)
+{
+ TiffIO *io = (TiffIO *) handle;
+ GError *error = NULL;
+ gboolean sought = FALSE;
+ goffset position = -1;
+
+ if (io->can_seek)
+ {
+ sought = g_seekable_seek (G_SEEKABLE (io->stream),
+ (goffset) offset, lseek_to_seek_type (whence),
+ NULL, &error);
+ if (sought)
+ {
+ position = g_seekable_tell (G_SEEKABLE (io->stream));
+ }
+ else
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+ }
+ else
+ {
+ switch (whence)
+ {
+ default:
+ case SEEK_SET:
+ if (offset <= io->used)
+ position = io->position = offset;
+ break;
+
+ case SEEK_CUR:
+ if (io->position + offset <= io->used)
+ position = io->position += offset;
+ break;
+
+ case G_SEEK_END:
+ if (io->used + offset <= io->used)
+ position = io->position = io->used + offset;
+ break;
+ }
+ }
+
+ return (toff_t) position;
+}
+
+static gint
+tiff_io_close (thandle_t handle)
+{
+ TiffIO *io = (TiffIO *) handle;
+ GError *error = NULL;
+ gboolean closed = FALSE;
+
+ if (io->input)
+ {
+ closed = g_input_stream_close (io->input, NULL, &error);
+ }
+ else
+ {
+ if (! io->can_seek && io->buffer && io->allocated)
+ {
+ if (! g_output_stream_write_all (io->output,
+ (void *) io->buffer,
+ io->allocated,
+ NULL, NULL, &error))
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ closed = g_output_stream_close (io->output, NULL, &error);
+ }
+
+ if (! closed)
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ g_object_unref (io->stream);
+ io->stream = NULL;
+ io->input = NULL;
+ io->output = NULL;
+
+ g_free (io->buffer);
+ io->buffer = NULL;
+
+ io->allocated = 0;
+ io->used = 0;
+ io->position = 0;
+
+ return closed ? 0 : -1;
+}
+
+static toff_t
+tiff_io_get_file_size (thandle_t handle)
+{
+ TiffIO *io = (TiffIO *) handle;
+ GError *error = NULL;
+ GFileInfo *info;
+ goffset size = 0;
+
+ info = g_file_query_info (io->file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ if (! info)
+ {
+ g_printerr ("%s", error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ size = g_file_info_get_size (info);
+ g_object_unref (info);
+ }
+
+ return (toff_t) size;
+}
diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c
index cd88955..5135d13 100644
--- a/plug-ins/file-tiff/file-tiff.c
+++ b/plug-ins/file-tiff/file-tiff.c
@@ -145,6 +145,7 @@ query (void)
load_args, load_return_vals);
gimp_register_file_handler_mime (LOAD_PROC, "image/tiff");
+ gimp_register_file_handler_uri (LOAD_PROC);
gimp_register_magic_load_handler (LOAD_PROC,
"tif,tiff",
"",
@@ -165,6 +166,7 @@ query (void)
save_args_old, NULL);
gimp_register_file_handler_mime (SAVE_PROC, "image/tiff");
+ gimp_register_file_handler_uri (SAVE_PROC);
gimp_register_save_handler (SAVE_PROC, "tif,tiff", "");
gimp_install_procedure (SAVE2_PROC,
@@ -207,7 +209,7 @@ run (const gchar *name,
if (strcmp (name, LOAD_PROC) == 0)
{
- GFile *file = g_file_new_for_path (param[1].data.d_string);
+ GFile *file = g_file_new_for_uri (param[1].data.d_string);
TIFF *tif;
tif = tiff_open (file, "r", &error);
@@ -456,7 +458,7 @@ run (const gchar *name,
GFile *file;
gint saved_bpp;
- file = g_file_new_for_path (param[3].data.d_string);
+ file = g_file_new_for_uri (param[3].data.d_string);
if (save_image (file, &tsvals,
image, drawable, orig_image, image_comment,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]