[gtk/image-loading: 11/36] Redo tiff load/save without streams
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/image-loading: 11/36] Redo tiff load/save without streams
- Date: Tue, 14 Sep 2021 05:40:42 +0000 (UTC)
commit 3d41f25d434453eaf5b58ea3db89c69ad7deabdd
Author: Benjamin Otte <otte redhat com>
Date: Tue Sep 14 02:03:55 2021 +0200
Redo tiff load/save without streams
Less code.
gdk/loaders/gdktiff.c | 268 +++++++++++++++++---------------------------------
1 file changed, 88 insertions(+), 180 deletions(-)
---
diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c
index 74be02cbe5..3be4594acb 100644
--- a/gdk/loaders/gdktiff.c
+++ b/gdk/loaders/gdktiff.c
@@ -38,19 +38,16 @@
typedef struct
{
- GObject *stream;
- GInputStream *input;
- GOutputStream *output;
-
- gchar *buffer;
- gsize allocated;
- gsize used;
+ GBytes **out_bytes;
+ gchar *data;
+ gsize size;
gsize position;
} TiffIO;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-
+static void
+tiff_io_warning (const char *module,
+ const char *fmt,
+ va_list ap) G_GNUC_PRINTF(2, 0);
static void
tiff_io_warning (const char *module,
const char *fmt,
@@ -59,6 +56,10 @@ tiff_io_warning (const char *module,
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
}
+static void
+tiff_io_error (const char *module,
+ const char *fmt,
+ va_list ap) G_GNUC_PRINTF(2, 0);
static void
tiff_io_error (const char *module,
const char *fmt,
@@ -67,222 +68,144 @@ tiff_io_error (const char *module,
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
}
-#pragma GCC diagnostic pop
-
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;
- 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);
- }
+ gsize read;
- read = bytes_read;
+ read = MIN (size, io->size - io->position);
+
+ memcpy (buffer, io->data + io->position, read);
+ io->position += read;
return (tsize_t) read;
}
+static tsize_t
+tiff_io_no_write (thandle_t handle,
+ tdata_t buffer,
+ tsize_t size)
+{
+ errno = EINVAL;
+ return (tsize_t) -1;
+}
+
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;
- gsize bytes_written = 0;
-
- if (! g_output_stream_write_all (io->output,
- (void *) buffer, (gsize) size,
- &bytes_written,
- NULL, &error))
+
+ if (io->size - io->position < size)
{
- g_printerr ("%s", error->message);
- g_clear_error (&error);
+ io->size = io->position + size;
+ io->data = g_realloc (io->data, io->size);
}
- written = bytes_written;
+ memcpy (io->data + io->position, buffer, size);
+ io->position += size;
- return (tsize_t) written;
+ return (tsize_t) size;
}
-static GSeekType
-lseek_to_seek_type (int whence)
+static toff_t
+tiff_io_seek (thandle_t handle,
+ toff_t offset,
+ int whence)
{
+ TiffIO *io = (TiffIO *) handle;
+
switch (whence)
{
default:
+ errno = EINVAL;
+ return -1;
case SEEK_SET:
- return G_SEEK_SET;
+ break;
case SEEK_CUR:
- return G_SEEK_CUR;
+ offset += io->position;
+ break;
case SEEK_END:
- return G_SEEK_END;
+ offset += io->size;
+ break;
}
-}
-
-static toff_t
-tiff_io_seek (thandle_t handle,
- toff_t offset,
- int whence)
-{
- TiffIO *io = (TiffIO *) handle;
- GError *error = NULL;
- gboolean sought = FALSE;
- goffset position = -1;
-
- sought = g_seekable_seek (G_SEEKABLE (io->stream),
- (goffset) offset, lseek_to_seek_type (whence),
- NULL, &error);
- if (sought)
+ if (offset < 0)
{
- position = g_seekable_tell (G_SEEKABLE (io->stream));
+ errno = EINVAL;
+ return -1;
}
- else
+ if (offset > io->size)
{
- g_printerr ("%s", error->message);
- g_clear_error (&error);
+ /* Linux apparently can do that */
+ errno = EINVAL;
+ return -1;
}
- return (toff_t) position;
+ io->position = offset;
+
+ return offset;
}
static int
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->output)
- closed = g_output_stream_close (io->output, NULL, &error);
- if (!closed)
- {
- g_printerr ("%s", error->message);
- g_clear_error (&error);
- }
-
- g_clear_object (&io->stream);
- io->input = NULL;
- io->output = NULL;
-
- g_clear_pointer (&io->buffer, g_free);
-
- io->allocated = 0;
- io->used = 0;
- io->position = 0;
+ if (io->out_bytes)
+ *io->out_bytes = g_bytes_new_take (io->data, io->size);
g_free (io);
- return closed ? 0 : -1;
+ return 0;
}
-static goffset
-input_stream_query_size (GInputStream *stream)
+static toff_t
+tiff_io_get_file_size (thandle_t handle)
{
- goffset size = 0;
-
- while (G_IS_FILTER_INPUT_STREAM (stream))
- stream = g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (stream));
-
- if (G_IS_FILE_INPUT_STREAM (stream))
- {
- GFileInfo *info;
-
- info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (stream),
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- NULL,
- NULL);
- if (info)
- {
- size = g_file_info_get_size (info);
- g_object_unref (info);
- }
- }
+ TiffIO *io = (TiffIO *) handle;
- return size;
+ return io->size;
}
-static goffset
-output_stream_query_size (GOutputStream *stream)
+static TIFF *
+tiff_open_read (GBytes *bytes)
{
- goffset size = 0;
-
- while (G_IS_FILTER_OUTPUT_STREAM (stream))
- stream = g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream));
-
- if (G_IS_FILE_OUTPUT_STREAM (stream))
- {
- GFileInfo *info;
-
- info = g_file_output_stream_query_info (G_FILE_OUTPUT_STREAM (stream),
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- NULL,
- NULL);
- if (info)
- {
- size = g_file_info_get_size (info);
- g_object_unref (info);
- }
- }
+ TiffIO *io;
- return size;
-}
+ TIFFSetWarningHandler ((TIFFErrorHandler) tiff_io_warning);
+ TIFFSetErrorHandler ((TIFFErrorHandler) tiff_io_error);
-static toff_t
-tiff_io_get_file_size (thandle_t handle)
-{
- TiffIO *io = (TiffIO *) handle;
+ io = g_new0 (TiffIO, 1);
- if (io->input)
- return (toff_t) input_stream_query_size (io->input);
- else if (io->output)
- return (toff_t) output_stream_query_size (io->output);
+ io->data = (char *) g_bytes_get_data (bytes, &io->size);
- return (toff_t) 0;
+ return TIFFClientOpen ("GTK-read", "r",
+ (thandle_t) io,
+ tiff_io_read,
+ tiff_io_no_write,
+ tiff_io_seek,
+ tiff_io_close,
+ tiff_io_get_file_size,
+ NULL, NULL);
}
static TIFF *
-tiff_open (gpointer stream,
- const gchar *mode,
- GError **error)
+tiff_open_write (GBytes **result)
{
+ TiffIO *io;
+
TIFFSetWarningHandler ((TIFFErrorHandler) tiff_io_warning);
TIFFSetErrorHandler ((TIFFErrorHandler) tiff_io_error);
- TiffIO *io;
io = g_new0 (TiffIO, 1);
- if (strcmp (mode, "r") == 0)
- {
- io->input = G_INPUT_STREAM (stream);
- io->stream = g_object_ref (G_OBJECT (stream));
- }
- else if (strcmp (mode, "w") == 0)
- {
- io->output = G_OUTPUT_STREAM (stream);
- io->stream = g_object_ref (G_OBJECT (stream));
- }
- else
- {
- g_assert_not_reached ();
- }
+ io->out_bytes = result;
- return TIFFClientOpen ("GTK", mode,
+ return TIFFClientOpen ("GTK-write", "w",
(thandle_t) io,
tiff_io_read,
tiff_io_write,
@@ -338,7 +261,6 @@ static struct {
GBytes *
gdk_save_tiff (GdkTexture *texture)
{
- GOutputStream *stream;
TIFF *tif;
int width, height, stride;
guint16 bits_per_sample = 0;
@@ -347,17 +269,11 @@ gdk_save_tiff (GdkTexture *texture)
const guchar *line;
const guchar *data;
guchar *new_data = NULL;
- GBytes *bytes;
+ GBytes *result = NULL;
GdkTexture *memory_texture;
GdkMemoryFormat format;
- stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
- tif = tiff_open (stream, "w", NULL);
- if (!tif)
- {
- g_object_unref (stream);
- return NULL;
- }
+ tif = tiff_open_write (&result);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
@@ -422,7 +338,6 @@ gdk_save_tiff (GdkTexture *texture)
TIFFClose (tif);
g_free (new_data);
g_object_unref (memory_texture);
- g_object_unref (stream);
return NULL;
}
@@ -432,13 +347,12 @@ gdk_save_tiff (GdkTexture *texture)
TIFFFlushData (tif);
TIFFClose (tif);
+ g_assert (result);
+
g_free (new_data);
g_object_unref (memory_texture);
- bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (stream));
- g_object_unref (stream);
-
- return bytes;
+ return result;
}
static GdkTexture *
@@ -480,7 +394,6 @@ GdkTexture *
gdk_load_tiff (GBytes *input_bytes,
GError **error)
{
- GInputStream *stream;
TIFF *tif;
guint16 samples_per_pixel;
guint16 bits_per_sample;
@@ -496,12 +409,7 @@ gdk_load_tiff (GBytes *input_bytes,
GBytes *bytes;
GdkTexture *texture;
- stream = g_memory_input_stream_new_from_bytes (input_bytes);
- tif = tiff_open (stream, "r", error);
- g_object_unref (stream);
-
- if (!tif)
- return NULL;
+ tif = tiff_open_read (input_bytes);
TIFFSetDirectory (tif, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]