[gthumb] cairo_io: read images from a stream if possible
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] cairo_io: read images from a stream if possible
- Date: Sun, 19 Aug 2012 08:37:51 +0000 (UTC)
commit d36f5fc8866ad506f3aff426c1d03c2481c64906
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Aug 18 11:44:32 2012 +0200
cairo_io: read images from a stream if possible
extensions/cairo_io/cairo-image-surface-jpeg.c | 13 +-
extensions/cairo_io/cairo-image-surface-jpeg.h | 3 +-
extensions/cairo_io/cairo-image-surface-png.c | 9 +-
extensions/cairo_io/cairo-image-surface-png.h | 3 +-
extensions/cairo_io/cairo-image-surface-svg.c | 12 +-
extensions/cairo_io/cairo-image-surface-svg.h | 3 +-
extensions/flicker_utils/dlg-import-from-flickr.c | 3 +-
extensions/jpeg_utils/jmemorysrc.c | 2 +-
extensions/picasaweb/dlg-import-from-picasaweb.c | 3 +-
extensions/raw_files/main.c | 9 +-
gthumb/gio-utils.c | 60 +++--
gthumb/gio-utils.h | 5 +
gthumb/glib-utils.c | 102 +++++++++
gthumb/glib-utils.h | 4 +
gthumb/gth-file-data.c | 99 ++-------
gthumb/gth-image-loader.c | 251 ++++++++-------------
gthumb/gth-image-loader.h | 8 +
gthumb/gth-image.h | 3 +-
gthumb/gth-thumb-loader.c | 69 ++++--
gthumb/pixbuf-io.c | 105 +++++----
gthumb/pixbuf-io.h | 6 +-
21 files changed, 403 insertions(+), 369 deletions(-)
---
diff --git a/extensions/cairo_io/cairo-image-surface-jpeg.c b/extensions/cairo_io/cairo-image-surface-jpeg.c
index 51eeed8..562ded5 100644
--- a/extensions/cairo_io/cairo-image-surface-jpeg.c
+++ b/extensions/cairo_io/cairo-image-surface-jpeg.c
@@ -135,7 +135,8 @@ YCbCr_tables_init (void)
GthImage *
-_cairo_image_surface_create_from_jpeg (GthFileData *file_data,
+_cairo_image_surface_create_from_jpeg (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -171,11 +172,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
image = gth_image_new ();
- if (! _g_file_load_in_buffer (file_data->file,
- &in_buffer,
- &in_buffer_size,
- cancellable,
- error))
+ if (! _g_input_stream_read_all (istream,
+ &in_buffer,
+ &in_buffer_size,
+ cancellable,
+ error))
{
return image;
}
diff --git a/extensions/cairo_io/cairo-image-surface-jpeg.h b/extensions/cairo_io/cairo-image-surface-jpeg.h
index 5ab1ac1..23244a7 100644
--- a/extensions/cairo_io/cairo-image-surface-jpeg.h
+++ b/extensions/cairo_io/cairo-image-surface-jpeg.h
@@ -27,7 +27,8 @@
G_BEGIN_DECLS
-GthImage * _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
+GthImage * _cairo_image_surface_create_from_jpeg (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/extensions/cairo_io/cairo-image-surface-png.c b/extensions/cairo_io/cairo-image-surface-png.c
index 98e5828..6333654 100644
--- a/extensions/cairo_io/cairo-image-surface-png.c
+++ b/extensions/cairo_io/cairo-image-surface-png.c
@@ -39,7 +39,7 @@
#endif
typedef struct {
- GFileInputStream *stream;
+ GInputStream *stream;
GCancellable *cancellable;
GError **error;
png_struct *png_ptr;
@@ -88,7 +88,7 @@ cairo_png_read_data_func (png_structp png_ptr,
GError *error = NULL;
cairo_png_data = png_get_io_ptr (png_ptr);
- n = g_input_stream_read (G_INPUT_STREAM (cairo_png_data->stream),
+ n = g_input_stream_read (cairo_png_data->stream,
buffer,
size,
cairo_png_data->cancellable,
@@ -131,7 +131,8 @@ transform_to_argb32_format_func (png_structp png,
GthImage *
-_cairo_image_surface_create_from_png (GthFileData *file_data,
+_cairo_image_surface_create_from_png (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -154,7 +155,7 @@ _cairo_image_surface_create_from_png (GthFileData *file_data,
cairo_png_data = g_new0 (CairoPngData, 1);
cairo_png_data->cancellable = cancellable;
cairo_png_data->error = error;
- cairo_png_data->stream = g_file_read (file_data->file, cancellable, error);
+ cairo_png_data->stream = _g_object_ref (istream);
if (cairo_png_data->stream == NULL) {
_cairo_png_data_destroy (cairo_png_data);
return image;
diff --git a/extensions/cairo_io/cairo-image-surface-png.h b/extensions/cairo_io/cairo-image-surface-png.h
index c3bf73e..2ae9993 100644
--- a/extensions/cairo_io/cairo-image-surface-png.h
+++ b/extensions/cairo_io/cairo-image-surface-png.h
@@ -27,7 +27,8 @@
G_BEGIN_DECLS
-GthImage * _cairo_image_surface_create_from_png (GthFileData *file_data,
+GthImage * _cairo_image_surface_create_from_png (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/extensions/cairo_io/cairo-image-surface-svg.c b/extensions/cairo_io/cairo-image-surface-svg.c
index 93b47e3..c61eba5 100644
--- a/extensions/cairo_io/cairo-image-surface-svg.c
+++ b/extensions/cairo_io/cairo-image-surface-svg.c
@@ -164,7 +164,8 @@ gth_image_svg_set_handle (GthImageSvg *self,
GthImage *
-_cairo_image_surface_create_from_svg (GthFileData *file_data,
+_cairo_image_surface_create_from_svg (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -176,10 +177,11 @@ _cairo_image_surface_create_from_svg (GthFileData *file_data,
RsvgHandle *rsvg;
image = gth_image_svg_new ();
- rsvg = rsvg_handle_new_from_gfile_sync (file_data->file,
- RSVG_HANDLE_FLAGS_NONE,
- cancellable,
- error);
+ rsvg = rsvg_handle_new_from_stream_sync (istream,
+ (file_data != NULL ? file_data->file : NULL),
+ RSVG_HANDLE_FLAGS_NONE,
+ cancellable,
+ error);
if (rsvg != NULL) {
gth_image_svg_set_handle (GTH_IMAGE_SVG (image), rsvg);
g_object_unref (rsvg);
diff --git a/extensions/cairo_io/cairo-image-surface-svg.h b/extensions/cairo_io/cairo-image-surface-svg.h
index a85edf6..dc67431 100644
--- a/extensions/cairo_io/cairo-image-surface-svg.h
+++ b/extensions/cairo_io/cairo-image-surface-svg.h
@@ -27,7 +27,8 @@
G_BEGIN_DECLS
-GthImage * _cairo_image_surface_create_from_svg (GthFileData *file_data,
+GthImage * _cairo_image_surface_create_from_svg (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/extensions/flicker_utils/dlg-import-from-flickr.c b/extensions/flicker_utils/dlg-import-from-flickr.c
index 25bd953..c5da97a 100644
--- a/extensions/flicker_utils/dlg-import-from-flickr.c
+++ b/extensions/flicker_utils/dlg-import-from-flickr.c
@@ -417,7 +417,8 @@ photoset_combobox_changed_cb (GtkComboBox *widget,
static GthImage *
-flickr_thumbnail_loader (GthFileData *file_data,
+flickr_thumbnail_loader (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/extensions/jpeg_utils/jmemorysrc.c b/extensions/jpeg_utils/jmemorysrc.c
index b748eec..04e080b 100644
--- a/extensions/jpeg_utils/jmemorysrc.c
+++ b/extensions/jpeg_utils/jmemorysrc.c
@@ -63,7 +63,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
}
-void
+static void
skip_input_data (j_decompress_ptr cinfo,
long num_bytes)
{
diff --git a/extensions/picasaweb/dlg-import-from-picasaweb.c b/extensions/picasaweb/dlg-import-from-picasaweb.c
index 6ef4659..3a7f37d 100644
--- a/extensions/picasaweb/dlg-import-from-picasaweb.c
+++ b/extensions/picasaweb/dlg-import-from-picasaweb.c
@@ -883,7 +883,8 @@ album_combobox_changed_cb (GtkComboBox *widget,
GthImage *
-picasa_web_thumbnail_loader (GthFileData *file_data,
+picasa_web_thumbnail_loader (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/extensions/raw_files/main.c b/extensions/raw_files/main.c
index 493a784..aad7036 100644
--- a/extensions/raw_files/main.c
+++ b/extensions/raw_files/main.c
@@ -269,7 +269,8 @@ get_file_mtime (const char *path)
static GthImage *
-openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
+openraw_pixbuf_animation_new_from_file (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -289,6 +290,12 @@ openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
char *local_file_esc;
char *command = NULL;
+ if (file_data == NULL) {
+ if (error != NULL)
+ *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
+ return NULL;
+ }
+
is_thumbnail = requested_size > 0;
is_raw = _g_mime_type_is_raw (gth_file_data_get_mime_type (file_data));
is_hdr = _g_mime_type_is_hdr (gth_file_data_get_mime_type (file_data));
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 87d5b42..f7ef655 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1934,32 +1934,22 @@ _g_delete_files_async (GList *file_list,
gboolean
-_g_file_load_in_buffer (GFile *file,
- void **buffer,
- gsize *size,
- GCancellable *cancellable,
- GError **error)
-{
- GFileInputStream *istream;
- gboolean retval;
- void *local_buffer;
- gsize count;
- gssize n;
- char tmp_buffer[BUFFER_SIZE];
-
- istream = g_file_read (file, cancellable, error);
- if (istream == NULL)
- return FALSE;
-
- retval = FALSE;
- local_buffer = NULL;
+_g_input_stream_read_all (GInputStream *istream,
+ void **buffer,
+ gsize *size,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean retval = FALSE;
+ void *local_buffer = NULL;
+ char *tmp_buffer;
+ gsize count;
+ gssize n;
+
+ tmp_buffer = g_new (char, BUFFER_SIZE);
count = 0;
for (;;) {
- n = g_input_stream_read (G_INPUT_STREAM (istream),
- tmp_buffer,
- BUFFER_SIZE,
- cancellable,
- error);
+ n = g_input_stream_read (istream, tmp_buffer, BUFFER_SIZE, cancellable, error);
if (n < 0) {
g_free (local_buffer);
retval = FALSE;
@@ -1979,7 +1969,27 @@ _g_file_load_in_buffer (GFile *file,
count += n;
}
- g_object_unref (istream);
+ g_free (tmp_buffer);
+
+ return retval;
+}
+
+
+gboolean
+_g_file_load_in_buffer (GFile *file,
+ void **buffer,
+ gsize *size,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInputStream *istream;
+ gboolean retval = FALSE;
+
+ istream = (GInputStream *) g_file_read (file, cancellable, error);
+ if (istream != NULL) {
+ retval = _g_input_stream_read_all (istream, buffer, size, cancellable, error);
+ g_object_unref (istream);
+ }
return retval;
}
diff --git a/gthumb/gio-utils.h b/gthumb/gio-utils.h
index a8a3523..b96edfb 100644
--- a/gthumb/gio-utils.h
+++ b/gthumb/gio-utils.h
@@ -148,6 +148,11 @@ void _g_delete_files_async (GList *file_list,
/* -- load/write/create file -- */
+gboolean _g_input_stream_read_all (GInputStream *istream,
+ void **buffer,
+ gsize *size,
+ GCancellable *cancellable,
+ GError **error);
gboolean _g_file_load_in_buffer (GFile *file,
void **buffer,
gsize *size,
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index 80214a9..a25a3a7 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -31,6 +31,7 @@
#include "glib-utils.h"
#define MAX_PATTERNS 128
+#define BUFFER_SIZE_FOR_SNIFFING 32
/* gobject utils*/
@@ -2809,6 +2810,99 @@ _g_content_type_is_a (const char *type,
}
+/* -- _g_content_type_get_from_stream -- */
+
+
+static const char *
+get_mime_type_from_magic_numbers (void *buffer,
+ gsize buffer_size)
+{
+#if ENABLE_MAGIC
+
+ static magic_t magic = NULL;
+
+ if (magic == NULL) {
+ magic = magic_open (MAGIC_MIME_TYPE);
+ if (magic != NULL)
+ magic_load (magic, NULL);
+ else
+ g_warning ("unable to open magic database");
+ }
+
+ if (magic != NULL) {
+ const char * mime_type;
+
+ mime_type = magic_buffer (magic, buffer, buffer_size);
+ if (mime_type)
+ return mime_type;
+
+ g_warning ("unable to detect filetype from magic: %s", magic_error (magic));
+ }
+
+#else
+
+ static const struct magic {
+ const unsigned int off;
+ const unsigned int len;
+ const char * const id;
+ const char * const mime_type;
+ }
+ magic_ids [] = {
+ /* magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
+ { 0, 8, "\x89PNG\x0d\x0a\x1a\x0a", "image/png" },
+ { 0, 4, "MM\x00\x2a", "image/tiff" },
+ { 0, 4, "II\x2a\x00", "image/tiff" },
+ { 0, 4, "GIF8", "image/gif" },
+ { 0, 2, "\xff\xd8", "image/jpeg" },
+ };
+
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (magic_ids); i++) {
+ const struct magic * const magic = &magic_ids[i];
+
+ if ((magic->off + magic->len) > buffer_size)
+ g_warning ("buffer underrun for mime-type '%s' magic", magic->mime_type);
+ else if (! memcmp (buffer + magic->off, magic->id, magic->len))
+ return magic->mime_type;
+ }
+
+#endif
+
+ return NULL;
+}
+
+
+const char *
+_g_content_type_get_from_stream (GInputStream *istream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ guchar buffer[BUFFER_SIZE_FOR_SNIFFING];
+ gssize n = 0;
+ gboolean result_uncertain = FALSE;
+ const char *content_type;
+
+ n = g_input_stream_read (istream,
+ buffer,
+ BUFFER_SIZE_FOR_SNIFFING,
+ cancellable,
+ error);
+ if (n < 0)
+ return NULL;
+
+ content_type = get_mime_type_from_magic_numbers (buffer, n);
+ if (content_type == NULL)
+ content_type = g_content_type_guess (NULL, buffer, n, &result_uncertain);
+ if (result_uncertain)
+ content_type = NULL;
+
+ g_seekable_seek (G_SEEKABLE (istream), 0, G_SEEK_SET, cancellable, NULL);
+
+ return content_type;
+}
+
+
gboolean
_g_mime_type_is_image (const char *mime_type)
{
@@ -2963,3 +3057,11 @@ _g_list_prepend_link (GList *list,
if (list != NULL) list->prev = link;
return link;
}
+
+
+void
+_g_error_free (GError *error)
+{
+ if (error != NULL)
+ g_error_free (error);
+}
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index d195363..c647d0f 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -309,6 +309,9 @@ void _g_file_info_swap_attributes (GFileInfo *info,
const char *attr2);
gboolean _g_content_type_is_a (const char *type,
const char *supertype);
+const char * _g_content_type_get_from_stream (GInputStream *istream,
+ GCancellable *cancellable,
+ GError **error);
gboolean _g_mime_type_is_image (const char *mime_type);
gboolean _g_mime_type_is_video (const char *mime_type);
gboolean _g_mime_type_is_audio (const char *mime_type);
@@ -331,6 +334,7 @@ GList * _g_settings_get_string_list (GSettings *settings,
char * _g_format_duration_for_display (gint64 msecs);
GList * _g_list_prepend_link (GList *list,
GList *link);
+void _g_error_free (GError *error);
G_END_DECLS
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 1182e58..1f8b782 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -28,9 +28,6 @@
#include "gth-string-list.h"
-#define BUFFER_SIZE_FOR_SNIFFING 32
-
-
const char *FileDataDigitalizationTags[] = {
"Exif::Photo::DateTimeOriginal",
"Xmp::exif::DateTimeOriginal",
@@ -236,66 +233,6 @@ gth_file_data_get_mime_type (GthFileData *self)
}
-static const char *
-get_mime_type_from_magic_numbers (void *buffer,
- gsize buffer_size)
-{
-#if ENABLE_MAGIC
-
- static magic_t magic = NULL;
-
- if (magic == NULL) {
- magic = magic_open (MAGIC_MIME_TYPE);
- if (magic != NULL)
- magic_load (magic, NULL);
- else
- g_warning ("unable to open magic database");
- }
-
- if (magic != NULL) {
- const char * mime_type;
-
- mime_type = magic_buffer (magic, buffer, buffer_size);
- if (mime_type)
- return mime_type;
-
- g_warning ("unable to detect filetype from magic: %s", magic_error (magic));
- }
-
-#else
-
- static const struct magic {
- const unsigned int off;
- const unsigned int len;
- const char * const id;
- const char * const mime_type;
- }
- magic_ids [] = {
- /* magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
- { 0, 8, "\x89PNG\x0d\x0a\x1a\x0a", "image/png" },
- { 0, 4, "MM\x00\x2a", "image/tiff" },
- { 0, 4, "II\x2a\x00", "image/tiff" },
- { 0, 4, "GIF8", "image/gif" },
- { 0, 2, "\xff\xd8", "image/jpeg" },
- };
-
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (magic_ids); i++) {
- const struct magic * const magic = &magic_ids[i];
-
- if ((magic->off + magic->len) > buffer_size)
- g_warning ("buffer underrun for mime-type '%s' magic", magic->mime_type);
- else if (! memcmp (buffer + magic->off, magic->id, magic->len))
- return magic->mime_type;
- }
-
-#endif
-
- return NULL;
-}
-
-
const char *
gth_file_data_get_mime_type_from_content (GthFileData *self,
GCancellable *cancellable)
@@ -307,12 +244,11 @@ gth_file_data_get_mime_type_from_content (GthFileData *self,
content_type = g_file_info_get_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
if (content_type == NULL) {
- char *filename;
- GFileInputStream *istream;
- GError *error = NULL;
- guchar buffer[BUFFER_SIZE_FOR_SNIFFING];
- gssize n = 0;
- gboolean result_uncertain;
+ char *filename;
+ GInputStream *istream;
+ GError *error = NULL;
+
+
if (self->file == NULL)
return NULL;
@@ -321,28 +257,21 @@ gth_file_data_get_mime_type_from_content (GthFileData *self,
if (filename == NULL)
return NULL;
- istream = g_file_read (self->file, cancellable, &error);
- if (istream != NULL) {
- n = g_input_stream_read (G_INPUT_STREAM (istream),
- buffer,
- BUFFER_SIZE_FOR_SNIFFING,
- cancellable,
- NULL);
- g_object_unref (istream);
- }
- else {
+ istream = (GInputStream *) g_file_read (self->file, cancellable, &error);
+ if (istream == NULL) {
+ g_free (filename);
g_warning ("%s", error->message);
g_clear_error (&error);
+ return NULL;
}
- result_uncertain = FALSE;
- content_type = get_mime_type_from_magic_numbers (buffer, n);
- if (content_type == NULL)
- content_type = g_content_type_guess (NULL, buffer, n, &result_uncertain);
- if ((content_type == NULL) || (strcmp (content_type, "application/xml") == 0) || result_uncertain)
- content_type = g_content_type_guess (filename, NULL, n, NULL);
+ content_type = _g_content_type_get_from_stream (istream, cancellable, &error);
+ if ((content_type == NULL) || (strcmp (content_type, "application/xml") == 0))
+ content_type = g_content_type_guess (filename, NULL, 0, NULL);
+
g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, content_type);
+ g_object_unref (istream);
g_free (filename);
}
diff --git a/gthumb/gth-image-loader.c b/gthumb/gth-image-loader.c
index 3b8c2b6..63cdebc 100644
--- a/gthumb/gth-image-loader.c
+++ b/gthumb/gth-image-loader.c
@@ -29,10 +29,6 @@
#include "gth-main.h"
-#define USE_G_IO_SCHEDULER
-#define THREAD_STACK_SIZE (512*1024)
-
-
struct _GthImageLoaderPrivate {
gboolean as_animation; /* Whether to load the image in a
* GdkPixbufAnimation structure. */
@@ -114,6 +110,9 @@ typedef struct {
GthFileData *file_data;
int requested_size;
GCancellable *cancellable;
+ GthImage *image;
+ int original_width;
+ int original_height;
} LoadData;
@@ -125,7 +124,7 @@ load_data_new (GthFileData *file_data,
LoadData *load_data;
load_data = g_new0 (LoadData, 1);
- load_data->file_data = g_object_ref (file_data);
+ load_data->file_data = _g_object_ref (file_data);
load_data->requested_size = requested_size;
load_data->cancellable = _g_object_ref (cancellable);
@@ -136,31 +135,13 @@ load_data_new (GthFileData *file_data,
static void
load_data_unref (LoadData *load_data)
{
- g_object_unref (load_data->file_data);
+ _g_object_unref (load_data->file_data);
_g_object_unref (load_data->cancellable);
+ _g_object_unref (load_data->image);
g_free (load_data);
}
-typedef struct {
- GthImage *image;
- int original_width;
- int original_height;
-} LoadResult;
-
-
-static void
-load_result_unref (LoadResult *load_result)
-{
- if (load_result->image != NULL)
- g_object_unref (load_result->image);
- g_free (load_result);
-}
-
-
-#ifdef USE_G_IO_SCHEDULER
-
-
static void
load_pixbuf_thread (GSimpleAsyncResult *result,
GObject *object,
@@ -168,18 +149,26 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
{
GthImageLoader *self = GTH_IMAGE_LOADER (object);
LoadData *load_data;
- GthImage *image = NULL;
int original_width;
int original_height;
+ GInputStream *istream;
+ GthImage *image = NULL;
GError *error = NULL;
- LoadResult *load_result;
load_data = g_simple_async_result_get_op_res_gpointer (result);
original_width = -1;
original_height = -1;
+ istream = (GInputStream *) g_file_read (load_data->file_data->file, cancellable, &error);
+ if (istream == NULL) {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ return;
+ }
+
if (self->priv->loader_func != NULL) {
- image = (*self->priv->loader_func) (load_data->file_data,
+ image = (*self->priv->loader_func) (istream,
+ load_data->file_data,
load_data->requested_size,
&original_width,
&original_height,
@@ -193,7 +182,8 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
loader_func = gth_main_get_image_loader_func (gth_file_data_get_mime_type_from_content (load_data->file_data, cancellable),
self->priv->preferred_format);
if (loader_func != NULL)
- image = loader_func (load_data->file_data,
+ image = loader_func (istream,
+ load_data->file_data,
load_data->requested_size,
&original_width,
&original_height,
@@ -204,6 +194,8 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("No suitable loader available for this file type"));
}
+ _g_object_unref (istream);
+
if (error != NULL) {
_g_object_unref (image);
g_simple_async_result_set_from_error (result, error);
@@ -211,95 +203,12 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
return;
}
- load_result = g_new0 (LoadResult, 1);
- load_result->image = image;
- load_result->original_width = original_width;
- load_result->original_height = original_height;
- g_simple_async_result_set_op_res_gpointer (result, load_result, (GDestroyNotify) load_result_unref);
+ load_data->image = image;
+ load_data->original_width = original_width;
+ load_data->original_height = original_height;
}
-#else
-
-
-static gpointer
-load_image_thread (gpointer user_data)
-{
- GSimpleAsyncResult *result = user_data;
- LoadData *load_data;
- GthImageLoader *self;
- GthImage *image;
- int original_width;
- int original_height;
- GError *error = NULL;
- LoadResult *load_result;
-
- load_data = g_simple_async_result_get_op_res_gpointer (result);
-
- if (g_cancellable_is_cancelled (load_data->cancellable)) {
- g_simple_async_result_set_error (result,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- "%s",
- "");
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
- return NULL;
- }
-
- self = (GthImageLoader *) g_async_result_get_source_object (G_ASYNC_RESULT (result));
- image = NULL;
- original_width = -1;
- original_height = -1;
-
- if (self->priv->loader_func != NULL) {
- image = (*self->priv->loader_func) (load_data->file_data,
- load_data->requested_size,
- &original_width,
- &original_height,
- self->priv->loader_data,
- load_data->cancellable,
- &error);
- }
- else {
- GthImageLoaderFunc loader_func;
-
- loader_func = gth_main_get_image_loader_func (gth_file_data_get_mime_type (load_data->file_data),
- self->priv->preferred_format);
- if (loader_func != NULL)
- image = loader_func (load_data->file_data,
- load_data->requested_size,
- &original_width,
- &original_height,
- NULL,
- load_data->cancellable,
- &error);
- else
- error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("No suitable loader available for this file type"));
- }
-
- load_result = g_new0 (LoadResult, 1);
- load_result->image = image;
- load_result->original_width = original_width;
- load_result->original_height = original_height;
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- }
- else
- g_simple_async_result_set_op_res_gpointer (result, load_result, (GDestroyNotify) load_result_unref);
-
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-
- return NULL;
-}
-
-
-#endif
-
-
void
gth_image_loader_load (GthImageLoader *loader,
GthFileData *file_data,
@@ -310,10 +219,6 @@ gth_image_loader_load (GthImageLoader *loader,
gpointer user_data)
{
GSimpleAsyncResult *result;
-#ifndef USE_G_IO_SCHEDULER
- GThreadPriority thread_priority;
- GError *error = NULL;
-#endif
result = g_simple_async_result_new (G_OBJECT (loader),
callback,
@@ -324,52 +229,78 @@ gth_image_loader_load (GthImageLoader *loader,
requested_size,
cancellable),
(GDestroyNotify) load_data_unref);
-
-#ifdef USE_G_IO_SCHEDULER
-
g_simple_async_result_run_in_thread (result,
load_pixbuf_thread,
io_priority,
cancellable);
+
g_object_unref (result);
+}
-#else
-
- /* The g_thread_create function assigns a very large default stacksize for each
- thread (10 MB on FC6), which is probably excessive. 16k seems to be
- sufficient. To be conversative, we'll try 32k. Use g_thread_create_full to
- manually specify a small stack size. See Bug 310749 - Memory usage.
- This reduces the virtual memory requirements, and the "writeable/private"
- figure reported by "pmap -d". */
-
- /* Update: 32k caused crashes with svg images. Boosting to 512k. Bug 410827. */
-
- switch (io_priority) {
- case G_PRIORITY_HIGH:
- thread_priority = G_THREAD_PRIORITY_HIGH;
- break;
- case G_PRIORITY_LOW:
- thread_priority = G_THREAD_PRIORITY_LOW;
- break;
- default:
- thread_priority = G_THREAD_PRIORITY_NORMAL;
- break;
+
+gboolean
+gth_image_loader_load_stream_sync (GthImageLoader *self,
+ GInputStream *istream,
+ int requested_size,
+ GthImage **p_image,
+ int *p_original_width,
+ int *p_original_height,
+ GCancellable *cancellable,
+ GError **p_error)
+{
+ GthImage *image;
+ int original_width;
+ int original_height;
+ GError *error = NULL;
+ gboolean result;
+
+ if (self->priv->loader_func != NULL) {
+ image = (*self->priv->loader_func) (istream,
+ NULL,
+ requested_size,
+ &original_width,
+ &original_height,
+ self->priv->loader_data,
+ cancellable,
+ &error);
}
+ else {
+ const char *mime_type;
+ GthImageLoaderFunc loader_func;
- if (! g_thread_create_full (load_image_thread,
- result,
- THREAD_STACK_SIZE,
- FALSE,
- TRUE,
- thread_priority,
- &error))
- {
- g_simple_async_result_set_from_error (result, error);
- g_simple_async_result_complete_in_idle (result);
- g_error_free (error);
+ mime_type = _g_content_type_get_from_stream (istream, cancellable, &error);
+ loader_func = gth_main_get_image_loader_func (mime_type, self->priv->preferred_format);
+ if (loader_func != NULL)
+ image = loader_func (istream,
+ NULL,
+ requested_size,
+ &original_width,
+ &original_height,
+ NULL,
+ cancellable,
+ &error);
+ else
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("No suitable loader available for this file type"));
}
-#endif
+ result = (error == NULL);
+
+ if (p_error != NULL)
+ *p_error = error;
+ else
+ _g_error_free (error);
+
+ if (p_image != NULL)
+ *p_image = image;
+ else
+ g_object_unref (image);
+
+ if (p_original_width != NULL)
+ *p_original_width = original_width;
+ if (p_original_height != NULL)
+ *p_original_height = original_height;
+
+ return result;
}
@@ -382,7 +313,7 @@ gth_image_loader_load_finish (GthImageLoader *loader,
GError **error)
{
GSimpleAsyncResult *simple;
- LoadResult *load_result;
+ LoadData *load_data;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (loader), gth_image_loader_load), FALSE);
@@ -391,13 +322,13 @@ gth_image_loader_load_finish (GthImageLoader *loader,
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
- load_result = g_simple_async_result_get_op_res_gpointer (simple);
+ load_data = g_simple_async_result_get_op_res_gpointer (simple);
if (image != NULL)
- *image = _g_object_ref (load_result->image);
+ *image = _g_object_ref (load_data->image);
if (original_width != NULL)
- *original_width = load_result->original_width;
+ *original_width = load_data->original_width;
if (original_height != NULL)
- *original_height = load_result->original_height;
+ *original_height = load_data->original_height;
return TRUE;
}
diff --git a/gthumb/gth-image-loader.h b/gthumb/gth-image-loader.h
index 57252b8..ecf0494 100644
--- a/gthumb/gth-image-loader.h
+++ b/gthumb/gth-image-loader.h
@@ -64,6 +64,14 @@ void gth_image_loader_load (GthImageLoader
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
+gboolean gth_image_loader_load_stream_sync (GthImageLoader *loader,
+ GInputStream *istream,
+ int requested_size,
+ GthImage **image,
+ int *original_width,
+ int *original_height,
+ GCancellable *cancellable,
+ GError **error);
gboolean gth_image_loader_load_finish (GthImageLoader *loader,
GAsyncResult *res,
GthImage **image,
diff --git a/gthumb/gth-image.h b/gthumb/gth-image.h
index 81746c7..4338ef1 100644
--- a/gthumb/gth-image.h
+++ b/gthumb/gth-image.h
@@ -65,7 +65,8 @@ struct _GthImageClass
};
-typedef GthImage * (*GthImageLoaderFunc) (GthFileData *file_data,
+typedef GthImage * (*GthImageLoaderFunc) (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 73c21da..c924691 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -111,7 +111,8 @@ gth_thumb_loader_init (GthThumbLoader *self)
static GthImage *
-generate_thumbnail (GthFileData *file_data,
+generate_thumbnail (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -121,8 +122,15 @@ generate_thumbnail (GthFileData *file_data,
{
GthThumbLoader *self = user_data;
GdkPixbuf *pixbuf = NULL;
- GthImage *image;
+ GthImage *image = NULL;
char *uri;
+ const char *mime_type;
+
+ if (file_data == NULL) {
+ if (error != NULL)
+ *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
+ return NULL;
+ }
if (original_width != NULL)
*original_width = -1;
@@ -130,51 +138,55 @@ generate_thumbnail (GthFileData *file_data,
if (original_height != NULL)
*original_height = -1;
- image = NULL;
+ mime_type = _g_content_type_get_from_stream (istream, cancellable, error);
+ if (mime_type == NULL) {
+ if ((error != NULL) && (*error == NULL))
+ *error = g_error_new_literal (GTH_ERROR, 0, "Cannot generate the thumbnail: unknown file type");
+ return NULL;
+ }
+
uri = g_file_get_uri (file_data->file);
pixbuf = gnome_desktop_thumbnail_factory_generate_no_script (self->priv->thumb_factory,
uri,
- gth_file_data_get_mime_type_from_content (file_data, cancellable),
+ mime_type,
cancellable);
if (g_cancellable_is_cancelled (cancellable)) {
_g_object_unref (pixbuf);
+ g_free (uri);
if (error != NULL)
*error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
return NULL;
}
- if (pixbuf == NULL) {
- GthImageLoaderFunc thumbnailer;
-
- thumbnailer = gth_main_get_image_loader_func (gth_file_data_get_mime_type (file_data), GTH_IMAGE_FORMAT_GDK_PIXBUF);
- if (thumbnailer != NULL)
- image = thumbnailer (file_data,
- self->priv->cache_max_size,
- original_width,
- original_height,
- NULL,
- cancellable,
- error);
- }
-
if (pixbuf != NULL) {
+ image = gth_image_new_for_pixbuf (pixbuf);
if (original_width != NULL)
*original_width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf), "gnome-original-width"));
if (original_height != NULL)
*original_height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf), "gnome-original-height"));
-
if (error != NULL)
g_clear_error (error);
- image = gth_image_new_for_pixbuf (pixbuf);
-
g_object_unref (pixbuf);
}
+ else {
+ GthImageLoaderFunc thumbnailer;
- if (image == NULL)
- if (error != NULL)
- *error = g_error_new_literal (GTH_ERROR, 0, "Cannot generate the thumbnail");
+ thumbnailer = gth_main_get_image_loader_func (mime_type, GTH_IMAGE_FORMAT_GDK_PIXBUF);
+ if (thumbnailer != NULL)
+ image = thumbnailer (istream,
+ file_data,
+ self->priv->cache_max_size,
+ original_width,
+ original_height,
+ NULL,
+ cancellable,
+ error);
+ }
+
+ if ((image == NULL) && (error != NULL))
+ *error = g_error_new_literal (GTH_ERROR, 0, "Could not generate the thumbnail");
g_free (uri);
@@ -183,7 +195,8 @@ generate_thumbnail (GthFileData *file_data,
static GthImage *
-load_cached_thumbnail (GthFileData *file_data,
+load_cached_thumbnail (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -195,6 +208,12 @@ load_cached_thumbnail (GthFileData *file_data,
char *filename;
GdkPixbuf *pixbuf;
+ if (file_data == NULL) {
+ if (error != NULL)
+ *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
+ return NULL;
+ }
+
filename = g_file_get_path (file_data->file);
pixbuf = gdk_pixbuf_new_from_file (filename, error);
if (pixbuf != NULL) {
diff --git a/gthumb/pixbuf-io.c b/gthumb/pixbuf-io.c
index dc30a0d..eeb0919 100644
--- a/gthumb/pixbuf-io.c
+++ b/gthumb/pixbuf-io.c
@@ -33,7 +33,7 @@
#include "pixbuf-utils.h"
-#undef USE_PIXBUF_LOADER
+#define USE_PIXBUF_LOADER 1
char *
@@ -276,17 +276,18 @@ load_from_stream (GdkPixbufLoader *loader,
if (n_read == 0)
break;
- if (!gdk_pixbuf_loader_write (loader,
- buffer,
- n_read,
- error)) {
+ if (! gdk_pixbuf_loader_write (loader,
+ buffer,
+ n_read,
+ error))
+ {
res = FALSE;
error = NULL;
break;
}
}
- if (!gdk_pixbuf_loader_close (loader, error)) {
+ if (! gdk_pixbuf_loader_close (loader, error)) {
res = FALSE;
error = NULL;
}
@@ -335,7 +336,8 @@ pixbuf_loader_size_prepared_cb (GdkPixbufLoader *loader,
GthImage *
-gth_pixbuf_new_from_file (GthFileData *file_data,
+gth_pixbuf_new_from_file (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -351,18 +353,18 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
int original_w;
int original_h;
- if (original_width != NULL)
- *original_width = -1;
-
- if (original_height != NULL)
- *original_height = -1;
-
if (file_data == NULL) {
if (error != NULL)
*error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
return NULL;
}
+ if (original_width != NULL)
+ *original_width = -1;
+
+ if (original_height != NULL)
+ *original_height = -1;
+
path = g_file_get_path (file_data->file);
if (path == NULL) {
if (error != NULL)
@@ -418,23 +420,16 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
#else
- GdkPixbuf *pixbuf = NULL;
ScaleData scale_data;
- GInputStream *stream;
GdkPixbufLoader *pixbuf_loader;
+ GdkPixbuf *pixbuf;
+ GthImage *image;
if (original_width != NULL)
*original_width = -1;
if (original_height != NULL)
*original_height = -1;
- if (file_data == NULL)
- return NULL;
-
- stream = (GInputStream *) g_file_read (file_data->file, cancellable, error);
- if (stream == NULL)
- return NULL;
-
scale_data.requested_size = requested_size;
scale_data.original_width = -1;
scale_data.original_height = -1;
@@ -446,16 +441,14 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
"size-prepared",
G_CALLBACK (pixbuf_loader_size_prepared_cb),
&scale_data);
-
- pixbuf = load_from_stream (pixbuf_loader, stream, requested_size, cancellable, error);
+ pixbuf = load_from_stream (pixbuf_loader, istream, requested_size, cancellable, error);
g_object_unref (pixbuf_loader);
- g_object_unref (stream);
if ((pixbuf != NULL) && scale_to_original) {
GdkPixbuf *tmp;
- tmp = gdk_pixbuf_scale_simple (pixbuf, scale_data.original_width, scale_data.original_height, GDK_INTERP_NEAREST);
+ tmp = _gdk_pixbuf_scale_simple_safe (pixbuf, scale_data.original_width, scale_data.original_height, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
pixbuf = tmp;
}
@@ -472,19 +465,24 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
}
}
+ image = gth_image_new_for_pixbuf (pixbuf);
+
if (original_width != NULL)
*original_width = scale_data.original_width;
if (original_height != NULL)
*original_height = scale_data.original_height;
- return pixbuf;
+ _g_object_unref (pixbuf);
+
+ return image;
#endif
}
GthImage *
-gth_pixbuf_animation_new_from_file (GthFileData *file_data,
+gth_pixbuf_animation_new_from_file (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
@@ -492,35 +490,44 @@ gth_pixbuf_animation_new_from_file (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GthImage *image = NULL;
- const char *mime_type;
+ const char *mime_type;
+ GdkPixbufAnimation *animation;
+ char *path;
+ GthImage *image;
mime_type = gth_file_data_get_mime_type (file_data);
if (mime_type == NULL)
return NULL;
- if (g_content_type_equals (mime_type, "image/gif")) {
- GdkPixbufAnimation *animation;
- char *path;
-
- path = g_file_get_path (file_data->file);
- if (path != NULL)
- animation = gdk_pixbuf_animation_new_from_file (path, error);
+ if (! g_content_type_equals (mime_type, "image/gif"))
+ return gth_pixbuf_new_from_file (istream,
+ file_data,
+ requested_size,
+ original_width,
+ original_height,
+ FALSE,
+ cancellable,
+ error);
- image = gth_image_new ();
- gth_image_set_pixbuf_animation (image, animation);
+ if (file_data == NULL) {
+ if (error != NULL)
+ *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
+ return NULL;
+ }
- g_object_unref (animation);
- g_free (path);
+ path = g_file_get_path (file_data->file);
+ if (path == NULL) {
+ if (error != NULL)
+ *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
+ return NULL;
}
- else
- image = gth_pixbuf_new_from_file (file_data,
- requested_size,
- original_width,
- original_height,
- FALSE,
- cancellable,
- error);
+
+ animation = gdk_pixbuf_animation_new_from_file (path, error);
+ image = gth_image_new ();
+ gth_image_set_pixbuf_animation (image, animation);
+
+ g_object_unref (animation);
+ g_free (path);
return image;
}
diff --git a/gthumb/pixbuf-io.h b/gthumb/pixbuf-io.h
index d4bacc6..c2faaa3 100644
--- a/gthumb/pixbuf-io.h
+++ b/gthumb/pixbuf-io.h
@@ -63,14 +63,16 @@ void _gdk_pixbuf_save_async (GdkPixbuf *pixbuf,
gboolean replace,
GthFileDataFunc ready_func,
gpointer data);
-GthImage * gth_pixbuf_new_from_file (GthFileData *file,
+GthImage * gth_pixbuf_new_from_file (GInputStream *istream,
+ GthFileData *file,
int requested_size,
int *original_width,
int *original_height,
gboolean scale_to_original,
GCancellable *cancellable,
GError **error);
-GthImage * gth_pixbuf_animation_new_from_file (GthFileData *file_data,
+GthImage * gth_pixbuf_animation_new_from_file (GInputStream *istream,
+ GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]