[gegl] jpg-load: Port to GIO, accept URI property
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] jpg-load: Port to GIO, accept URI property
- Date: Mon, 10 Nov 2014 05:24:20 +0000 (UTC)
commit 5f08df0a4bfc8ab2984bd59171d093f29cf5c813
Author: Jon Nordby <jononor gmail com>
Date: Mon Nov 10 02:46:08 2014 +0100
jpg-load: Port to GIO, accept URI property
operations/external/jpg-load.c | 154 ++++++++++++++++++++++++++++++++-------
1 files changed, 126 insertions(+), 28 deletions(-)
---
diff --git a/operations/external/jpg-load.c b/operations/external/jpg-load.c
index 3504d32..fd2737e 100644
--- a/operations/external/jpg-load.c
+++ b/operations/external/jpg-load.c
@@ -19,12 +19,14 @@
#include "config.h"
#include <glib/gi18n-lib.h>
-
#ifdef GEGL_PROPERTIES
property_file_path (path, _("File"), "")
description (_("Path of file to load"))
+property_string (uri, _("URI"), "") // TODO: use file_ui property type
+ description (_("URI of file to load"))
+
#else
#define GEGL_OP_SOURCE
@@ -33,6 +35,7 @@ property_file_path (path, _("File"), "")
#include "gegl-op.h"
#include <stdio.h>
#include <jpeglib.h>
+#include <gegl-gio-private.h>
static const gchar *
jpeg_colorspace_name(J_COLOR_SPACE space)
@@ -66,28 +69,120 @@ babl_from_jpeg_colorspace(J_COLOR_SPACE space)
return format;
}
+typedef struct {
+ GInputStream *stream;
+ gchar *buffer;
+ gsize buffer_size;
+} GioSource;
+
+static boolean
+gio_source_fill(j_decompress_ptr cinfo)
+{
+ struct jpeg_source_mgr* src = cinfo->src;
+ GioSource *self = (GioSource *)cinfo->client_data;
+ GError *err = NULL;
+
+ const gssize bytes_read = g_input_stream_read(self->stream, self->buffer,
+ self->buffer_size, NULL, &err);
+ if (!err)
+ {
+ src->next_input_byte = (JOCTET*)self->buffer;
+ src->bytes_in_buffer = bytes_read;
+ }
+ else
+ {
+ g_print("%s: %s\n", __PRETTY_FUNCTION__, err->message);
+ }
+
+
+ /* FIXME: needed for EOF?
+ static const JOCTET EOI_BUFFER[ 2 ] = { (JOCTET)0xFF, (JOCTET)JPEG_EOI };
+ src->next_input_byte = EOI_BUFFER;
+ src->bytes_in_buffer = sizeof( EOI_BUFFER );
+ */
+
+ return TRUE;
+}
+
+static void
+gio_source_skip(j_decompress_ptr cinfo, long num_bytes)
+{
+ struct jpeg_source_mgr* src = (struct jpeg_source_mgr*)cinfo->src;
+ GioSource *self = (GioSource *)cinfo->client_data;
+
+ if (num_bytes < src->bytes_in_buffer)
+ {
+ // just skip inside buffer
+ src->next_input_byte += (size_t)num_bytes;
+ src->bytes_in_buffer -= (size_t)num_bytes;
+ }
+ else
+ {
+ // skip in stream, discard whole buffer
+ GError *err = NULL;
+ const gssize bytes_to_skip = num_bytes-src->bytes_in_buffer;
+ const gssize skipped = g_input_stream_skip(self->stream, bytes_to_skip, NULL, &err);
+ if (err)
+ {
+ g_printerr("%s: skipped=%ld, err=%s\n", __PRETTY_FUNCTION__, skipped, err->message);
+ g_error_free(err);
+ }
+ src->bytes_in_buffer = 0;
+ src->next_input_byte = NULL;
+ }
+
+}
+
+static void
+gio_source_init(j_decompress_ptr cinfo)
+{
+ GioSource *self = (GioSource *)cinfo->client_data;
+ self->buffer = g_new(gchar, self->buffer_size);
+}
+
+static void
+gio_source_destroy(j_decompress_ptr cinfo)
+{
+ GioSource *self = (GioSource *)cinfo->client_data;
+ g_free(self->buffer);
+}
+
+static void
+gio_source_enable(j_decompress_ptr cinfo, struct jpeg_source_mgr* src, GioSource *data)
+{
+ src->resync_to_restart = jpeg_resync_to_restart;
+
+ src->init_source = gio_source_init;
+ src->fill_input_buffer = gio_source_fill;
+ src->skip_input_data = gio_source_skip;
+ src->term_source = gio_source_destroy;
+
+ // force fill at once
+ src->bytes_in_buffer = 0;
+ src->next_input_byte = (JOCTET*)NULL;
+
+ //g_assert(!cinfo->client_data);
+ cinfo->client_data = data;
+ cinfo->src = src;
+}
+
static gint
-gegl_jpg_load_query_jpg (const gchar *path,
+gegl_jpg_load_query_jpg (GInputStream *stream,
gint *width,
gint *height,
const Babl **out_format)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
- FILE *infile;
+ struct jpeg_source_mgr src;
gint status = 0;
const Babl *format = NULL;
-
- if ((infile = fopen (path, "rb")) == NULL)
- {
- /*g_warning ("unable to open %s for jpeg import", path);*/
- return -1;
- }
+ GioSource gio_source = { stream, NULL, 1024 };
jpeg_create_decompress (&cinfo);
cinfo.err = jpeg_std_error (&jerr);
- jpeg_stdio_src (&cinfo, infile);
+ gio_source_enable(&cinfo, &src, &gio_source);
(void) jpeg_read_header (&cinfo, TRUE);
@@ -107,34 +202,28 @@ gegl_jpg_load_query_jpg (const gchar *path,
jpeg_destroy_decompress (&cinfo);
- fclose (infile);
return status;
}
static gint
gegl_jpg_load_buffer_import_jpg (GeglBuffer *gegl_buffer,
- const gchar *path,
+ GInputStream *stream,
gint dest_x,
gint dest_y)
{
gint row_stride;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
- FILE *infile;
+ struct jpeg_source_mgr src;
JSAMPARRAY buffer;
const Babl *format;
GeglRectangle write_rect;
gboolean is_inverted_cmyk = FALSE;
-
- if ((infile = fopen (path, "rb")) == NULL)
- {
- g_warning ("unable to open %s for jpeg import", path);
- return -1;
- }
+ GioSource gio_source = { stream, NULL, 1024 };
jpeg_create_decompress (&cinfo);
cinfo.err = jpeg_std_error (&jerr);
- jpeg_stdio_src (&cinfo, infile);
+ gio_source_enable(&cinfo, &src, &gio_source);
(void) jpeg_read_header (&cinfo, TRUE);
(void) jpeg_start_decompress (&cinfo);
@@ -184,7 +273,6 @@ gegl_jpg_load_buffer_import_jpg (GeglBuffer *gegl_buffer,
}
jpeg_destroy_decompress (&cinfo);
- fclose (infile);
return 0;
}
@@ -195,12 +283,16 @@ gegl_jpg_load_get_bounding_box (GeglOperation *operation)
gint width, height;
GeglProperties *o = GEGL_PROPERTIES (operation);
const Babl *format = NULL;
- const gint status = gegl_jpg_load_query_jpg (o->path, &width, &height, &format);
+ GFile *file = NULL;
+ GError *err = NULL;
+ GInputStream *stream = gegl_gio_open_input_stream(o->uri, o->path, &file, &err);
+ const gint status = gegl_jpg_load_query_jpg (stream, &width, &height, &format);
if (format)
gegl_operation_set_format (operation, "output", format);
- if (status)
+ if (file) g_object_unref(file);
+ if (err || status)
return (GeglRectangle) {0, 0, 0, 0};
else
return (GeglRectangle) {0, 0, width, height};
@@ -213,12 +305,18 @@ gegl_jpg_load_process (GeglOperation *operation,
gint level)
{
GeglProperties *o = GEGL_PROPERTIES (operation);
-
- if (gegl_jpg_load_buffer_import_jpg (output, o->path, 0, 0))
+ GFile *file = NULL;
+ GError *err = NULL;
+ GInputStream *stream = gegl_gio_open_input_stream(o->uri, o->path, &file, &err);
+ const gint status = gegl_jpg_load_buffer_import_jpg(output, stream, 0, 0);
+ if (err)
+ {
+ g_warning ("%s failed to open file %s for reading: %s",
+ G_OBJECT_TYPE_NAME (operation), o->path, err->message);
+ return FALSE;
+ }
+ if (status)
{
- g_warning ("%s failed to open file %s for reading.",
- G_OBJECT_TYPE_NAME (operation), o->path);
-
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]