Commit e4ab3810 authored by Matthias Clasen's avatar Matthias Clasen

Load-at-size functionality for gdk-pixbuf.

parent 09487ff9
2002-07-07 Matthias Clasen <maclas@gmx.de>
* gdk-pixbuf/gdk-pixbuf-sections.txt,
gdk-pixbuf/tmpl/gdk-pixbuf-loader.sgml,
gdk-pixbuf/tmpl/module_interface.sgml: Updates for
load-at-size functionality.
Tue Jun 18 17:02:48 2002 Owen Taylor <otaylor@redhat.com>
* gdk/gdk-sections.txt: Fix for cursor screen => display
......
......@@ -13,7 +13,7 @@ DOC_SOURCE_DIR=../../../gdk-pixbuf
SCAN_OPTIONS=--source-dir=../../../contrib/gdk-pixbuf-xlib --deprecated-guards="GDK_PIXBUF_ENABLE_BROKEN|GDK_PIXBUF_DISABLE_DEPRECATED"
# Extra options to supply to gtkdoc-mkdb
MKDB_OPTIONS=--sgml-mode --source-dir=../../../contrib/gdk-pixbuf-xlib --output-format=xml
MKDB_OPTIONS=--main-sgml-file=$(DOC_MAIN_SGML_FILE) --sgml-mode --source-dir=../../../contrib/gdk-pixbuf-xlib --output-format=xml
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=
......
......@@ -149,6 +149,7 @@ gdk_interp_type_get_type
gdk_pixbuf_loader_new
gdk_pixbuf_loader_new_with_type
gdk_pixbuf_loader_write
gdk_pixbuf_loader_set_size
gdk_pixbuf_loader_get_pixbuf
gdk_pixbuf_loader_get_animation
gdk_pixbuf_loader_close
......@@ -168,6 +169,7 @@ gdk_pixbuf_loader_get_type
<TITLE>Module Interface</TITLE>
<FILE>module_interface</FILE>
ModuleFillVtableFunc
ModuleSizeFunc
ModulePreparedNotifyFunc
ModuleUpdatedNotifyFunc
GdkPixbufModule
......
......@@ -21,21 +21,28 @@ Application-driven progressive image loading.
To use #GdkPixbufLoader to load an image, just create a new one,
and call gdk_pixbuf_loader_write() to send the data to it. When
done, gdk_pixbuf_loader_close() should be called to end the stream
and finalize everything. The loader will emit two important
and finalize everything. The loader will emit three important
signals throughout the process. The first, "<link
linkend="GdkPixbufLoader-area-prepared">area_prepared</link>",
linkend="GdkPixbufLoader-size-prepared">size_prepared</link>",
will be called as soon as the image has enough information to
determine the size of the image to be used. It will pass a
@GdkPixbuf in. If you want to use it, you can simply ref it. In
addition, no actual information will be passed in yet, so the
determine the size of the image to be used. If you want to scale
the image while loading it, you can call gdk_pixbuf_loader_set_size()
in response to this signal.
</para>
<para>The second signal, "<link
linkend="GdkPixbufLoader-area-prepared">area_prepared</link>",
will be called as soon as the pixbuf of the desired has been
allocated. You can obtain it by calling gdk_pixbuf_loader_get_pixbuf().
If you want to use it, simply ref it.
In addition, no actual information will be passed in yet, so the
pixbuf can be safely filled with any temporary graphics (or an
initial color) as needed. You can also call the
gdk_pixbuf_loader_get_pixbuf() once this signal has been emitted
and get the same pixbuf.
initial color) as needed. You can also call
gdk_pixbuf_loader_get_pixbuf() later and get the same pixbuf.
</para>
<para>
The other signal, "<link
The last signal, "<link
linkend="GdkPixbufLoader-area-updated">area_updated</link>" gets
called every time a region is updated. This way you can update a
partially completed image. Note that you do not know anything
......@@ -119,19 +126,23 @@ Application-driven progressive image loading.
@error:
@Returns:
<!-- ##### SIGNAL GdkPixbufLoader::area-prepared ##### -->
<!-- ##### SIGNAL GdkPixbufLoader::size-prepared ##### -->
<para>
This signal is emitted when the pixbuf loader has been fed the
initial amount of data that is required to figure out the size and
format of the image that it will create. After this signal is
emitted, applications can call gdk_pixbuf_loader_get_pixbuf() to
fetch the partially-loaded pixbuf.
initial amount of data that is required to figure out the size
of the image that it will create. Applications can call
gdk_pixbuf_loader_set_size() in response to this signal to set
the desired size to which the image should be scaled.
</para>
@width: the original width of the image
@height: the original height of the image
@gdkpixbufloader: the object which received the signal.
<!-- # Unused Parameters # -->
@loader: Loader which emitted the signal.
<!-- ##### SIGNAL GdkPixbufLoader::area-prepared ##### -->
<para>
This signal is emitted when the pixbuf loader has allocated the pixbuf
in the desired size. After this signal is emitted, applications can
call gdk_pixbuf_loader_get_pixbuf() to fetch the partially-loaded pixbuf.
</para>
<!-- ##### SIGNAL GdkPixbufLoader::area-updated ##### -->
<para>
......@@ -142,13 +153,7 @@ Application-driven progressive image loading.
areas of an image that is being loaded.
</para>
@gdkpixbufloader: the object which received the signal.
@arg1:
@arg2:
@arg3:
@arg4:
<!-- # Unused Parameters # -->
@loader: Loader which emitted the signal.
@gdkpixbufloader: Loader which emitted the signal.
@x: X offset of upper-left corner of the updated area.
@y: Y offset of upper-left corner of the updated area.
@width: Width of updated area.
......@@ -163,8 +168,6 @@ Application-driven progressive image loading.
</para>
@gdkpixbufloader: the object which received the signal.
<!-- # Unused Parameters # -->
@loader: Loader which emitted the signal.
<!--
Local variables:
......@@ -173,3 +176,4 @@ sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
End:
-->
......@@ -23,6 +23,24 @@ Defines the type of the function used to set the vtable of a
@module: a #GdkPixbufModule.
<!-- ##### USER_FUNCTION ModuleSizeFunc ##### -->
<para>
Defines the type of the function that gets called once the size
of the loaded image is known is done.
</para>
<para>
The function is expected to set @width and @height to the desired
size to which the image should be scaled. If a module has no efficient
way to achieve the desired scaling during the loading of the image, it may
either ignore the size request, or only approximate it -- the loader will
then perform the required scaling on the completely loaded image.
</para>
@width: pointer to a location containing the current image width
@height: pointer to a location containing the current image height
@user_data: the loader.
<!-- ##### USER_FUNCTION ModulePreparedNotifyFunc ##### -->
<para>
Defines the type of the function that gets called once the initial
......
2002-07-07 Matthias Clasen <maclas@gmx.de>
Load-at-size functionality (#53726):
* gdk-pixbuf-io.h (ModuleSizeFunc): New.
(_GdkPixbufModule): Prepend a ModuleSizeFunc to the
begin_load arguments. Adjust all modules.
* gdk-pixbuf-loader.c (struct GdkPixbufLoaderPrivate): Add
fields width, height, size_fixed, need_scale.
(gdk_pixbuf_loader_class_init): Add size_prepared signal.
(gdk_pixbuf_loader_set_size): New function.
(gdk_pixbuf_loader_size_func): ModuleSizeFunc which gets
passed to the module, emits size_prepared.
(gdk_pixbuf_loader_prepare): Call gdk_pixbuf_loader_size_func
if necessary, only emit area_prepared if no separate scaling
is required.
(gdk_pixbuf_loader_update): Only emit area_updated if no
separate scaling is required.
(gdk_pixbuf_loader_load_module): Add size_func as first argument.
(gdk_pixbuf_loader_close): If necessary scale the image
to the desired size and emit area_prepared and area_updated.
* gdk-pixbuf-loader.h (struct _GdkPixbufLoaderClass): Add
size_prepared signal.
(gdk_pixbuf_loader_set_size) New API.
* gdk-pixbuf-marshal.list: Add VOID:INT,INT.
* io-jpeg.c: User cinfo->output_width/height instead of
cinfo->image_width/height throughout when adressing the pixbuf.
(gdk_pixbuf__jpeg_image_load_increment): Call size_func, and
find the nearest possible output size which libjpeg can produce
that is still larger than the desired size.
2002-07-06 Matthias Clasen <maclas@gmx.de>
* io-tiff.c (tiff_set_error): Handle global_error == NULL
......
......@@ -37,6 +37,10 @@ G_BEGIN_DECLS
typedef void (* ModuleSizeFunc) (gint *width,
gint *height,
gpointer user_data);
typedef void (* ModulePreparedNotifyFunc) (GdkPixbuf *pixbuf,
GdkPixbufAnimation *anim,
gpointer user_data);
......@@ -58,7 +62,8 @@ struct _GdkPixbufModule {
/* Incremental loading */
gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func,
gpointer (* begin_load) (ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepare_func,
ModuleUpdatedNotifyFunc update_func,
gpointer user_data,
GError **error);
......
......@@ -31,8 +31,9 @@
#include "gdk-pixbuf-marshal.h"
enum {
AREA_UPDATED,
SIZE_PREPARED,
AREA_PREPARED,
AREA_UPDATED,
CLOSED,
LAST_SIGNAL
};
......@@ -58,6 +59,10 @@ typedef struct
gint header_buf_offset;
GdkPixbufModule *image_module;
gpointer context;
gint width;
gint height;
gboolean size_fixed;
gboolean needs_scale;
} GdkPixbufLoaderPrivate;
......@@ -109,6 +114,17 @@ gdk_pixbuf_loader_class_init (GdkPixbufLoaderClass *class)
object_class->finalize = gdk_pixbuf_loader_finalize;
pixbuf_loader_signals[SIZE_PREPARED] =
g_signal_new ("size_prepared",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkPixbufLoaderClass, size_prepared),
NULL, NULL,
gdk_pixbuf_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
pixbuf_loader_signals[AREA_PREPARED] =
g_signal_new ("area_prepared",
G_TYPE_FROM_CLASS (object_class),
......@@ -170,14 +186,73 @@ gdk_pixbuf_loader_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* gdk_pixbuf_loader_set_size:
* @loader: A pixbuf loader.
* @width: The desired width of the image being loaded.
* @height: The desired height of the image being loaded.
*
* Causes the image to be scaled while it is loaded. The desired
* image size can be determined relative to the original size of
* the image by calling gdk_pixbuf_loader_set_size() from a
* signal handler for the ::size_prepared signal.
*
* Attempts to set the desired image size are ignored after the
* emission of the ::size_prepared signal.
*/
void
gdk_pixbuf_loader_set_size (GdkPixbufLoader *loader,
gint width,
gint height)
{
GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
g_return_if_fail (width > 0 && height > 0);
if (!priv->size_fixed) {
priv->width = width;
priv->height = height;
}
}
static void
gdk_pixbuf_loader_size_func (gint *width, gint *height, gpointer loader)
{
GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
/* allow calling gdk_pixbuf_loader_set_size() before the signal */
if (priv->width == 0 && priv->height == 0) {
priv->width = *width;
priv->height = *height;
}
g_signal_emit (loader, pixbuf_loader_signals[SIZE_PREPARED], 0, *width, *height);
priv->size_fixed = TRUE;
*width = priv->width;
*height = priv->height;
}
static void
gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf,
GdkPixbufAnimation *anim,
gpointer loader)
{
GdkPixbufLoaderPrivate *priv = NULL;
priv = GDK_PIXBUF_LOADER (loader)->priv;
GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
g_return_if_fail (pixbuf != NULL);
if (!priv->size_fixed) {
/* Defend against lazy loaders which don't call size_func */
gint width = gdk_pixbuf_get_width (pixbuf);
gint height = gdk_pixbuf_get_height (pixbuf);
gdk_pixbuf_loader_size_func (&width, &height, loader);
}
priv->needs_scale = FALSE;
if (priv->width > 0 && priv->height > 0 &&
(priv->width != gdk_pixbuf_get_width (pixbuf) ||
priv->height != gdk_pixbuf_get_height (pixbuf)))
priv->needs_scale = TRUE;
if (anim)
g_object_ref (anim);
......@@ -186,7 +261,8 @@ gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf,
priv->animation = anim;
g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0);
if (!priv->needs_scale)
g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0);
}
static void
......@@ -197,17 +273,16 @@ gdk_pixbuf_loader_update (GdkPixbuf *pixbuf,
gint height,
gpointer loader)
{
GdkPixbufLoaderPrivate *priv = NULL;
priv = GDK_PIXBUF_LOADER (loader)->priv;
g_signal_emit (loader,
pixbuf_loader_signals[AREA_UPDATED],
0,
x, y,
/* sanity check in here. Defend against an errant loader */
MIN (width, gdk_pixbuf_animation_get_width (priv->animation)),
MIN (height, gdk_pixbuf_animation_get_height (priv->animation)));
GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv;
if (!priv->needs_scale)
g_signal_emit (loader,
pixbuf_loader_signals[AREA_UPDATED],
0,
x, y,
/* sanity check in here. Defend against an errant loader */
MIN (width, gdk_pixbuf_animation_get_width (priv->animation)),
MIN (height, gdk_pixbuf_animation_get_height (priv->animation)));
}
static gint
......@@ -253,10 +328,11 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader,
return 0;
}
priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_prepare,
gdk_pixbuf_loader_update,
loader,
error);
priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_size_func,
gdk_pixbuf_loader_prepare,
gdk_pixbuf_loader_update,
loader,
error);
if (priv->context == NULL)
{
......@@ -536,12 +612,33 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader,
retval = FALSE;
}
}
if (priv->image_module && priv->image_module->stop_load && priv->context) {
if (!priv->image_module->stop_load (priv->context, error))
retval = FALSE;
}
priv->closed = TRUE;
if (priv->needs_scale) {
GdkPixbuf *tmp, *pixbuf;
tmp = gdk_pixbuf_animation_get_static_image (priv->animation);
g_object_ref (tmp);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, tmp->has_alpha, 8, priv->width, priv->height);
g_object_unref (priv->animation);
priv->animation = gdk_pixbuf_non_anim_new (pixbuf);
g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0);
gdk_pixbuf_scale (tmp, pixbuf, 0, 0, priv->width, priv->height, 0, 0,
(double) priv->width / tmp->width,
(double) priv->height / tmp->height,
GDK_INTERP_BILINEAR);
g_object_unref (tmp);
g_signal_emit (loader, pixbuf_loader_signals[AREA_UPDATED], 0,
0, 0, priv->width, priv->height);
}
g_signal_emit (loader, pixbuf_loader_signals[CLOSED], 0);
......@@ -549,3 +646,7 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader,
}
......@@ -50,6 +50,10 @@ struct _GdkPixbufLoaderClass
{
GObjectClass parent_class;
void (*size_prepared) (GdkPixbufLoader *loader,
int width,
int height);
void (*area_prepared) (GdkPixbufLoader *loader);
/* Last known frame needs a redraw for x, y, width, height */
......@@ -62,11 +66,13 @@ struct _GdkPixbufLoaderClass
void (*closed) (GdkPixbufLoader *loader);
};
GType gdk_pixbuf_loader_get_type (void) G_GNUC_CONST;
GdkPixbufLoader * gdk_pixbuf_loader_new (void);
GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type,
GError **error);
void gdk_pixbuf_loader_set_size (GdkPixbufLoader *loader,
int width,
int height);
gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader,
const guchar *buf,
gsize count,
......@@ -80,3 +86,5 @@ gboolean gdk_pixbuf_loader_close (GdkPixbufLoader *loader,
G_END_DECLS
#endif
......@@ -25,3 +25,4 @@
VOID:VOID
VOID:INT,INT,INT,INT
VOID:POINTER
VOID:INT,INT
......@@ -181,7 +181,8 @@ struct bmp_progressive_state {
};
static gpointer
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
gdk_pixbuf__bmp_image_begin_load(ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gpointer user_data,
GError **error);
......@@ -205,7 +206,7 @@ static GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f, GError **error)
GdkPixbuf *pb;
State =
gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL,
gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL, NULL,
error);
if (State == NULL)
......@@ -512,7 +513,8 @@ decode_bitmasks (guchar *buf,
*/
static gpointer
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
gdk_pixbuf__bmp_image_begin_load(ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gpointer user_data,
GError **error)
......
......@@ -1396,7 +1396,8 @@ gdk_pixbuf__gif_image_load (FILE *file, GError **error)
}
static gpointer
gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func,
gdk_pixbuf__gif_image_begin_load (ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepare_func,
ModuleUpdatedNotifyFunc update_func,
gpointer user_data,
GError **error)
......
......@@ -158,7 +158,8 @@ struct ico_progressive_state {
};
static gpointer
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
gdk_pixbuf__ico_image_begin_load(ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gpointer user_data,
GError **error);
......@@ -193,7 +194,7 @@ gdk_pixbuf__ico_image_load(FILE * f, GError **error)
GdkPixbuf *pb;
State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL, error);
State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL, NULL, error);
if (State == NULL)
return NULL;
......@@ -478,7 +479,8 @@ static void DecodeHeader(guchar *Data, gint Bytes,
*/
static gpointer
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
gdk_pixbuf__ico_image_begin_load(ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gpointer user_data,
GError **error)
......
/* -*- mode: C; c-file-style: "linux" -*- */
/* GdkPixbuf library - JPEG image loader
*
* Copyright (C) 1999 Michael Zucchi
......@@ -50,7 +51,7 @@ typedef struct {
JOCTET buffer[JPEG_PROG_BUF_SIZE]; /* start of buffer */
long skip_next; /* number of bytes to skip next read */
} my_source_mgr;
typedef my_source_mgr * my_src_ptr;
......@@ -64,6 +65,7 @@ struct error_handler_data {
/* progressive loader context */
typedef struct {
ModuleSizeFunc size_func;
ModuleUpdatedNotifyFunc updated_func;
ModulePreparedNotifyFunc prepared_func;
gpointer user_data;
......@@ -80,7 +82,8 @@ typedef struct {
} JpegProgContext;
static GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error);
static gpointer gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc func,
static gpointer gdk_pixbuf__jpeg_image_begin_load (ModuleSizeFunc func0,
ModulePreparedNotifyFunc func1,
ModuleUpdatedNotifyFunc func2,
gpointer user_data,
GError **error);
......@@ -140,7 +143,7 @@ explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
/* Expand grey->colour. Expand from the end of the
* memory down, so we can use the same buffer.
*/
w = cinfo->image_width;
w = cinfo->output_width;
for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
guchar *from, *to;
......@@ -171,7 +174,7 @@ convert_cmyk_to_rgb (struct jpeg_decompress_struct *cinfo,
guchar *p;
p = lines[i];
for (j = 0; j < cinfo->image_width; j++) {
for (j = 0; j < cinfo->output_width; j++) {
int c, m, y, k;
c = p[0];
m = p[1];
......@@ -446,8 +449,9 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
*/
gpointer
gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gdk_pixbuf__jpeg_image_begin_load (ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepared_func,
ModuleUpdatedNotifyFunc updated_func,
gpointer user_data,
GError **error)
{
......@@ -455,6 +459,7 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
my_source_mgr *src;
context = g_new0 (JpegProgContext, 1);
context->size_func = size_func;
context->prepared_func = prepared_func;
context->updated_func = updated_func;
context->user_data = user_data;
......@@ -469,11 +474,11 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
context->cinfo.src = (struct jpeg_source_mgr *) g_try_malloc (sizeof (my_source_mgr));
if (!context->cinfo.src) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Couldn't allocate memory for loading JPEG file"));
return NULL;
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Couldn't allocate memory for loading JPEG file"));
return NULL;
}
memset (context->cinfo.src, 0, sizeof (my_source_mgr));
......@@ -509,14 +514,14 @@ gdk_pixbuf__jpeg_image_stop_load (gpointer data, GError **error)
JpegProgContext *context = (JpegProgContext *) data;
g_return_val_if_fail (context != NULL, TRUE);
/* FIXME this thing needs to report errors if
* we have unused image data
*/
if (context->pixbuf)
g_object_unref (context->pixbuf);
/* if we have an error? */
if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
jpeg_destroy_decompress (&context->cinfo);
......@@ -559,6 +564,7 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
guint spinguard;
gboolean first;
const guchar *bufhd;
gint width, height;
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (buf != NULL, FALSE);
......@@ -569,10 +575,6 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
context->jerr.error = error;
/* XXXXXXX (drmike) - loop(s) below need to be recoded now I
* have a grasp of what the flow needs to be!
*/
/* check for fatal error */
if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
return FALSE;
......@@ -636,29 +638,32 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
/* try to load jpeg header */
if (!context->got_header) {
int rc;
rc = jpeg_read_header (cinfo, TRUE);
context->src_initialized = TRUE;
if (rc == JPEG_SUSPENDED)
continue;
context->got_header = TRUE;
} else if (!context->did_prescan) {
int rc;
/* start decompression */
cinfo->buffered_image = TRUE;
rc = jpeg_start_decompress (cinfo);
cinfo->do_fancy_upsampling = FALSE;
cinfo->do_block_smoothing = FALSE;
context->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
cinfo->output_components == 4 ? TRUE : FALSE,
8,
cinfo->image_width,
cinfo->image_height);
width = cinfo->image_width;
height = cinfo->image_height;
(* context->size_func) (&width, &height, context->user_data);
for (cinfo->scale_denom = 2; cinfo->scale_denom <= 8; cinfo->scale_denom *= 2) {
jpeg_calc_output_dimensions (cinfo);
if (cinfo->output_width < width || cinfo->output_height < height) {
cinfo->scale_denom /= 2;
break;
}
}
jpeg_calc_output_dimensions (cinfo);
context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
cinfo->output_components == 4 ? TRUE : FALSE,
8,
cinfo->output_width,
cinfo->output_height);
if (context->pixbuf == NULL) {
g_set_error (error,
......@@ -667,16 +672,24 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
_("Couldn't allocate memory for loading JPEG file"));
return FALSE;
}
/* Use pixbuf buffer to store decompressed data */
context->dptr = context->pixbuf->pixels;
/* Notify the client that we are ready to go */
(* context->prepared_func) (context->pixbuf,
NULL,
context->user_data);
} else if (!context->did_prescan) {
int rc;
/* start decompression */
cinfo->buffered_image = TRUE;
rc = jpeg_start_decompress (cinfo);
cinfo->do_fancy_upsampling = FALSE;
cinfo->do_block_smoothing = FALSE;
if (rc == JPEG_SUSPENDED)
continue;
......
......@@ -386,7 +386,8 @@ struct _LoadContext {
};
static gpointer
gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func,
gdk_pixbuf__png_image_begin_load (ModuleSizeFunc size_func,
ModulePreparedNotifyFunc prepare_func,
ModuleUpdatedNotifyFunc update_func,
gpointer user_data,
GError **error)
......
......@@ -81,7 +81,8 @@ typedef struct {
} PnmLoaderContext;
static GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f, GError **error);
static gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func,