summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2000-10-09 17:22:20 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-10-09 17:22:20 +0000
commitfb1c7333ba85a56dc33cc4125b7f3afe0438789a (patch)
treee2e86b572dcf4e5dc245881de46d32b9271f6ec8
parentfce6e0712dfc0dd1477d9d61cd0512316f9660c4 (diff)
downloadgdk-pixbuf-fb1c7333ba85a56dc33cc4125b7f3afe0438789a.tar.gz
contrib subdir
2000-10-06 Havoc Pennington <hp@redhat.com> * Makefile.am (SRC_SUBDIRS): contrib subdir * gdk/gdkpixbuf.h: Move GdkPixbufAlphaMode to gdk-pixbuf library, so it can be used in Xlib version * demos/testpixbuf.c (update_timeout): error checking from 1.0 tree * gtk/gdk-pixbuf-loader.c (gdk_pixbuf_loader_get_pixbuf): Sync change from 1.0 tree that returns first frame of animation if the loaded file is an animation. * contrib: add new directory to hold stuff that comes with GTK+ but isn't really part of GTK+ (for now, gdk-pixbuf-xlib) * configure.in: add contrib/* 2000-10-06 Havoc Pennington <hp@redhat.com> * gdk-pixbuf.h: add GdkPixbufAlphaMode 2000-10-06 Havoc Pennington <hp@redhat.com> This entry is a summary of the merged-in changes from 1.0. Relevant original ChangeLog entries are spliced in after this entry; the files they refer to are from the 1.0 gdk-pixbuf sources. * pixops/pixops.c (pixops_composite_nearest): sync a small fix from 1.0 * io-xpm.c (xpm_seek_string): add fscanf error check from 1.0 Add progressive loader from 1.0 * io-tiff.c (gdk_pixbuf__tiff_image_begin_load): mem leak fixes from 1.0 tree * io-pnm.c: new version from 1.0 tree * io-jpeg.c (gdk_pixbuf__jpeg_image_load): sync from 1.0, use malloc not g_malloc * io-gif.c (lzw_read_byte): sync from 1.0, change a g_error to g_warning (gif_get_next_step): return 0 here, sync from 1.0 * gdk-pixbuf-util.c: sync email address change for Cody Russell 2000-09-11 Jeffrey Stedfast <fejj@helixcode.com> * gdk-pixbuf/io-pnm.c: Pretty much totally rewrote again because last nights code was still "broken". Should now properly handle all error conditions gracefully. 2000-09-10 Jeffrey Stedfast <fejj@helixcode.com> * gdk-pixbuf/io-pnm.c: Rewrote. 2000-09-09 Federico Mena Quintero <federico@helixcode.com> * gdk-pixbuf/pixops/pixops.c (pixops_composite_nearest): Compute the correct dest offset. 2000-08-25 Federico Mena Quintero <federico@helixcode.com> * gdk-pixbuf/io-xpm.c: #include <unistd.h> 2000-08-05 Larry Ewing <lewing@helixcode.com> * gdk-pixbuf/io-tiff.c: stop leaking context->tempname. * gdk-pixbuf/io-xpm.c: same as above. 2000-07-26 Michael Meeks <michael@helixcode.com> * gdk-pixbuf/io-jpeg.c (gdk_pixbuf__jpeg_image_load): make g_malloc a malloc. 2000-07-21 Larry Ewing <lewing@helixcode.com> * gdk-pixbuf/io-xpm.c: add a fake progressive loader so that xpm at least supports the progressive interface like the one in io-tiff.c. This should be reimplemented as an actual progressive loader. 2000-07-19 Jonathan Blandford <jrb@redhat.com> * demo/pixbuf-demo.c (update_timeout): changed scaling level to make it look better. * gdk-pixbuf/testpixbuf.c (update_timeout): Patch from michael meeks to handle errors better.
-rw-r--r--Makefile.am2
-rw-r--r--docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt48
-rw-r--r--docs/reference/gdk-pixbuf/gdk-pixbuf.sgml106
-rw-r--r--gdk-pixbuf/gdk-pixbuf-loader.c32
-rw-r--r--gdk-pixbuf/gdk-pixbuf-util.c2
-rw-r--r--gdk-pixbuf/gdk-pixbuf.h7
-rw-r--r--gdk-pixbuf/io-gif.c4
-rw-r--r--gdk-pixbuf/io-jpeg.c2
-rw-r--r--gdk-pixbuf/io-pnm.c817
-rw-r--r--gdk-pixbuf/io-tiff.c2
-rw-r--r--gdk-pixbuf/io-xpm.c98
-rw-r--r--gdk-pixbuf/pixops/pixops.c3
12 files changed, 687 insertions, 436 deletions
diff --git a/Makefile.am b/Makefile.am
index eb9a24f29..42577a920 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Makefile.am for GTK+
-SRC_SUBDIRS = gdk-pixbuf gdk modules gtk demos
+SRC_SUBDIRS = gdk-pixbuf gdk modules gtk demos contrib
SUBDIRS = po $(SRC_SUBDIRS) docs build
bin_SCRIPTS = gtk-config-2.0
diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt
index 51192a064..39fc15ddc 100644
--- a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt
+++ b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt
@@ -140,4 +140,50 @@ GdkPixbufModule
gdk_pixbuf_get_module
gdk_pixbuf_get_named_module
gdk_pixbuf_load_module
-</SECTION> \ No newline at end of file
+</SECTION>
+
+<SECTION>
+<FILE>gdk-pixbuf-xlib-init</FILE>
+gdk_pixbuf_xlib_init
+gdk_pixbuf_xlib_init_with_depth
+</SECTION>
+
+<SECTION>
+<FILE>gdk-pixbuf-xlib-rendering</FILE>
+gdk_pixbuf_xlib_render_threshold_alpha
+gdk_pixbuf_xlib_render_to_drawable
+gdk_pixbuf_xlib_render_to_drawable_alpha
+gdk_pixbuf_xlib_render_pixmap_and_mask
+</SECTION>
+
+<SECTION>
+<FILE>gdk-pixbuf-xlib-from-drawables</FILE>
+gdk_pixbuf_xlib_get_from_drawable
+</SECTION>
+
+<SECTION>
+<FILE>gdk-pixbuf-xlib-rgb</FILE>
+XlibRgbCmap
+XlibRgbDither
+xlib_rgb_init
+xlib_rgb_init_with_depth
+xlib_rgb_gc_set_foreground
+xlib_rgb_gc_set_background
+xlib_draw_rgb_image
+xlib_draw_rgb_image_dithalign
+xlib_draw_rgb_32_image
+xlib_draw_gray_image
+xlib_rgb_cmap_new
+xlib_rgb_cmap_free
+xlib_draw_indexed_image
+xlib_rgb_ditherable
+xlib_rgb_set_verbose
+xlib_rgb_set_install
+xlib_rgb_set_min_colors
+xlib_rgb_get_cmap
+xlib_rgb_get_visual
+xlib_rgb_get_visual_info
+xlib_rgb_get_depth
+xlib_rgb_get_display
+xlib_rgb_get_screen
+</SECTION>
diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml b/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml
index 16252c70a..60907f135 100644
--- a/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml
+++ b/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml
@@ -1,23 +1,28 @@
-<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
-<!entity gdk-pixbuf-Initialization-and-Versions SYSTEM "sgml/initialization_versions.sgml">
+<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN"[
+
<!entity gdk-pixbuf-gdk-pixbuf SYSTEM "sgml/gdk-pixbuf.sgml">
<!entity gdk-pixbuf-refcounting SYSTEM "sgml/refcounting.sgml">
<!entity gdk-pixbuf-file-loading SYSTEM "sgml/file-loading.sgml">
<!entity gdk-pixbuf-creating SYSTEM "sgml/creating.sgml">
-<!entity gdk-pixbuf-rendering SYSTEM "sgml/rendering.sgml">
<!entity gdk-pixbuf-scaling SYSTEM "sgml/scaling.sgml">
-<!entity gdk-pixbuf-from-drawables SYSTEM "sgml/from-drawables.sgml">
<!entity gdk-pixbuf-util SYSTEM "sgml/util.sgml">
<!entity gdk-pixbuf-animation SYSTEM "sgml/animation.sgml">
-<!entity gdk-pixbuf-Module-Interface SYSTEM "sgml/module_interface.sgml">
<!entity GdkPixbufLoader SYSTEM "sgml/gdk-pixbuf-loader.sgml">
-<!entity GnomeCanvasPixbuf SYSTEM "sgml/gnome-canvas-pixbuf.sgml">
+<!entity gdk-pixbuf-gdk-pixbuf-xlib-init SYSTEM "sgml/gdk-pixbuf-xlib-init.sgml">
+<!entity gdk-pixbuf-gdk-pixbuf-xlib-rendering SYSTEM "sgml/gdk-pixbuf-xlib-rendering.sgml">
+<!entity gdk-pixbuf-gdk-pixbuf-xlib-from-drawables SYSTEM "sgml/gdk-pixbuf-xlib-from-drawables.sgml">
+<!entity gdk-pixbuf-gdk-pixbuf-xlib-rgb SYSTEM "sgml/gdk-pixbuf-xlib-rgb.sgml">
+
+<!entity Porting-From-Imlib SYSTEM "porting-from-imlib.sgml">
<!entity Compiling SYSTEM "compiling.sgml">
+
+<!entity gdk-pixbuf "<application>gdk-pixbuf</application>">
+<!entity Imlib "<application>Imlib</application>">
]>
<book id="index">
<bookinfo>
- <title>The <application>gdk-pixbuf</application> Library</title>
+ <title>The &gdk-pixbuf; Library</title>
<authorgroup>
<author>
@@ -32,24 +37,53 @@
</authorgroup>
<copyright>
- <year>1999</year>
+ <year>2000</year>
<holder>The Free Software Foundation</holder>
</copyright>
+
+ <legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the <citetitle>GNU Free
+ Documentation License</citetitle>, Version 1.1 or any later
+ version published by the Free Software Foundation with no
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. You may obtain a copy of the <citetitle>GNU Free
+ Documentation License</citetitle> from the Free Software
+ Foundation by visiting <ulink type="http"
+ url="http://www.fsf.org">their Web site</ulink> or by writing
+ to:
+
+ <address>
+ The Free Software Foundation, Inc.,
+ <street>59 Temple Place</street> - Suite 330,
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
+ <country>USA</country>
+ </address>
+ </para>
+
+ <para>
+ Many of the names used by companies to distinguish their
+ products and services are claimed as trademarks. Where those
+ names appear in any GNOME documentation, and those trademarks
+ are made aware to the members of the GNOME Documentation
+ Project, the names have been printed in caps or initial caps.
+ </para>
+ </legalnotice>
</bookinfo>
- <reference id="api">
+ <reference>
<title>API Reference</title>
<partintro>
<para>
This part presents the class and function reference for the
- <application>gdk-pixbuf</application> library. Classes are
- described together with their methods; individual functions
- are grouped by functional group.
+ &gdk-pixbuf; library. Classes are described together with
+ their methods; individual functions are grouped by functional
+ group.
</para>
</partintro>
- &gdk-pixbuf-Initialization-and-Versions;
&gdk-pixbuf-gdk-pixbuf;
&gdk-pixbuf-refcounting;
&gdk-pixbuf-file-loading;
@@ -57,15 +91,51 @@
&gdk-pixbuf-scaling;
&gdk-pixbuf-util;
&gdk-pixbuf-animation;
+
&GdkPixbufLoader;
- &GnomeCanvasPixbuf;
- </reference>
- <reference id="internals">
- <title>Internals</title>
- &gdk-pixbuf-Module-Interface;
+ &gdk-pixbuf-gdk-pixbuf-xlib-init;
+ &gdk-pixbuf-gdk-pixbuf-xlib-rendering;
+ &gdk-pixbuf-gdk-pixbuf-xlib-from-drawables;
+ &gdk-pixbuf-gdk-pixbuf-xlib-rgb;
</reference>
+ &Porting-From-Imlib;
&Compiling;
+ <!-- License -->
+
+ <appendix id="license">
+ <title>License</title>
+
+ <para>
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the <citetitle>GNU Library General
+ Public License</citetitle> as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option)
+ any later version.
+ </para>
+
+ <para>
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ <citetitle>GNU Library General Public License</citetitle> for
+ more details.
+ </para>
+
+ <para>
+ You may obtain a copy of the <citetitle>GNU Library General
+ Public License</citetitle> from the Free Software Foundation by
+ visiting <ulink type="http" url="http://www.fsf.org">their Web
+ site</ulink> or by writing to:
+
+ <address>
+ Free Software Foundation, Inc.
+ <street>59 Temple Place</street> - Suite 330
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country>
+ </address>
+ </para>
+ </appendix>
</book>
diff --git a/gdk-pixbuf/gdk-pixbuf-loader.c b/gdk-pixbuf/gdk-pixbuf-loader.c
index c6ae8e2f2..5f4320f22 100644
--- a/gdk-pixbuf/gdk-pixbuf-loader.c
+++ b/gdk-pixbuf/gdk-pixbuf-loader.c
@@ -492,14 +492,17 @@ gdk_pixbuf_loader_new_with_type (const char *image_type)
* gdk_pixbuf_loader_get_pixbuf:
* @loader: A pixbuf loader.
*
- * Queries the GdkPixbuf that a pixbuf loader is currently creating. In general
- * it only makes sense to call this function afer the "area_prepared" signal has
- * been emitted by the loader; this means that enough data has been read to know
- * the size of the image that will be allocated. If the loader has not received
- * enough data via gdk_pixbuf_loader_write(), then this function returns NULL.
- * The returned pixbuf will be the same in all future calls to the loader, so
- * simply calling gdk_pixbuf_ref() should be sufficient to continue using it.
- *
+ * Queries the GdkPixbuf that a pixbuf loader is currently creating.
+ * In general it only makes sense to call this function afer the
+ * "area_prepared" signal has been emitted by the loader; this means
+ * that enough data has been read to know the size of the image that
+ * will be allocated. If the loader has not received enough data via
+ * gdk_pixbuf_loader_write(), then this function returns NULL. The
+ * returned pixbuf will be the same in all future calls to the loader,
+ * so simply calling gdk_pixbuf_ref() should be sufficient to continue
+ * using it. Additionally, if the loader is an animation, it will
+ * return the first frame of the animation.
+ *
* Return value: The GdkPixbuf that the loader is creating, or NULL if not
* enough data has been read to determine how to create the image buffer.
**/
@@ -512,6 +515,19 @@ gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader)
g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL);
priv = loader->private;
+
+ if (priv->animation)
+ {
+ GList *list;
+
+ list = gdk_pixbuf_animation_get_frames (priv->animation);
+ if (list != NULL)
+ {
+ GdkPixbufFrame *frame = list->data;
+
+ return gdk_pixbuf_frame_get_pixbuf (frame);
+ }
+ }
return priv->pixbuf;
}
diff --git a/gdk-pixbuf/gdk-pixbuf-util.c b/gdk-pixbuf/gdk-pixbuf-util.c
index db8ca758e..36fc29750 100644
--- a/gdk-pixbuf/gdk-pixbuf-util.c
+++ b/gdk-pixbuf/gdk-pixbuf-util.c
@@ -3,7 +3,7 @@
* Copyright (C) 1999 The Free Software Foundation
*
* Authors: Federico Mena-Quintero <federico@gimp.org>
- * Cody Russell <bratsche@dfw.net>
+ * Cody Russell <bratsche@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h
index 82f0551ba..a61dc9366 100644
--- a/gdk-pixbuf/gdk-pixbuf.h
+++ b/gdk-pixbuf/gdk-pixbuf.h
@@ -36,6 +36,13 @@ extern "C" {
+/* Alpha compositing mode */
+typedef enum
+{
+ GDK_PIXBUF_ALPHA_BILEVEL,
+ GDK_PIXBUF_ALPHA_FULL
+} GdkPixbufAlphaMode;
+
/* Color spaces; right now only RGB is supported.
* Note that these values are encoded in inline pixbufs
* as ints, so don't reorder them
diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
index 57e2af3a3..681e915da 100644
--- a/gdk-pixbuf/io-gif.c
+++ b/gdk-pixbuf/io-gif.c
@@ -537,7 +537,7 @@ lzw_read_byte (GifContext *context)
unsigned char buf[260];
/*g_error (" DID WE EVER EVER GET HERE\n");*/
- g_error ("Unhandled Case. If you have an image that causes this, let me <jrb@redhat.com> know.\n");
+ g_warning ("Unhandled Case. If you have an image that causes this, let me <jrb@redhat.com> know.\n");
if (ZeroDataBlock) {
return -2;
@@ -982,7 +982,7 @@ gif_get_next_step (GifContext *context)
/* hmm. Not 100% sure what to do about this. Should
* i try to return a blank image instead? */
context->state = GIF_DONE;
- return -2;
+ return 0;
}
if (c == '!') {
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index 89ca8d201..623077738 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -196,7 +196,7 @@ gdk_pixbuf__jpeg_image_load (FILE *f)
w = cinfo.output_width;
h = cinfo.output_height;
- pixels = g_malloc (h * w * 3);
+ pixels = malloc (h * w * 3);
if (!pixels) {
jpeg_destroy_decompress (&cinfo);
return NULL;
diff --git a/gdk-pixbuf/io-pnm.c b/gdk-pixbuf/io-pnm.c
index aa1b19391..c91658cfd 100644
--- a/gdk-pixbuf/io-pnm.c
+++ b/gdk-pixbuf/io-pnm.c
@@ -1,20 +1,22 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* GdkPixbuf library - PNM image loader
*
* Copyright (C) 1999 Red Hat, Inc.
*
- * Authors: Michael Fulbright <drmike@redhat.com>
+ * Authors: Jeffrey Stedfast <fejj@helixcode.com>
+ * Michael Fulbright <drmike@redhat.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
+ * modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
@@ -29,16 +31,15 @@
#include "gdk-pixbuf-private.h"
#include "gdk-pixbuf-io.h"
-
#define PNM_BUF_SIZE 4096
-#define PNM_SUSPEND 0
-#define PNM_OK 1
#define PNM_FATAL_ERR -1
+#define PNM_SUSPEND 0
+#define PNM_OK 1
typedef enum {
- PNM_FORMAT_PGM,
+ PNM_FORMAT_PGM = 1,
PNM_FORMAT_PGM_RAW,
PNM_FORMAT_PPM,
PNM_FORMAT_PPM_RAW,
@@ -47,51 +48,54 @@ typedef enum {
} PnmFormat;
typedef struct {
- guchar buffer[PNM_BUF_SIZE];
- guchar *next_byte;
- guint bytes_left;
+ guchar buffer[PNM_BUF_SIZE];
+ guchar *byte;
+ guint nbytes;
} PnmIOBuffer;
typedef struct {
- ModuleUpdatedNotifyFunc updated_func;
+ ModuleUpdatedNotifyFunc updated_func;
ModulePreparedNotifyFunc prepared_func;
- gpointer user_data;
+ gpointer user_data;
+
+ GdkPixbuf *pixbuf;
+ guchar *pixels; /* incoming pixel data buffer */
+ guchar *dptr; /* current position in pixbuf */
+
+ PnmIOBuffer inbuf;
+
+ guint width;
+ guint height;
+ guint maxval;
+ guint rowstride;
+ PnmFormat type;
+
+ guint output_row; /* last row to be completed */
+ guint output_col;
+ gboolean did_prescan; /* are we in image data yet? */
+ gboolean got_header; /* have we loaded pnm header? */
+
+ guint scan_state;
- GdkPixbuf *pixbuf;
- guchar *pixels; /* incoming pixel data buffer */
- guchar *dptr; /* current position in pixbuf */
-
- PnmIOBuffer inbuf;
-
- guint width;
- guint height;
- guint maxval;
- guint rowstride;
- PnmFormat type;
-
- guint output_row; /* last row to be completed */
- guint output_col;
- gboolean did_prescan; /* are we in image data yet? */
- gboolean got_header; /* have we loaded jpeg header? */
} PnmLoaderContext;
-GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f);
-gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func,
- ModuleUpdatedNotifyFunc func2,
- ModuleFrameDoneNotifyFunc frame_done_func,
- ModuleAnimationDoneNotifyFunc anim_done_func,
- gpointer user_data);
-void gdk_pixbuf__pnm_image_stop_load (gpointer context);
-gboolean gdk_pixbuf__pnm_image_load_increment(gpointer context, guchar *buf, guint size);
+GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f);
+gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func,
+ ModuleUpdatedNotifyFunc func2,
+ ModuleFrameDoneNotifyFunc frame_done_func,
+ ModuleAnimationDoneNotifyFunc anim_done_func,
+ gpointer user_data);
+void gdk_pixbuf__pnm_image_stop_load (gpointer context);
+gboolean gdk_pixbuf__pnm_image_load_increment (gpointer context, guchar *buf, guint size);
-static void explode_bitmap_into_buf (PnmLoaderContext *context);
-static void explode_gray_into_buf (PnmLoaderContext *context);
+static void explode_bitmap_into_buf (PnmLoaderContext *context);
+static void explode_gray_into_buf (PnmLoaderContext *context);
/* Destroy notification function for the pixbuf */
static void
free_buffer (guchar *pixels, gpointer data)
{
- free (pixels);
+ g_free (pixels);
}
@@ -108,33 +112,32 @@ explode_bitmap_into_buf (PnmLoaderContext *context)
gint bit;
guchar *dptr;
gint wid, x, y;
-
+
g_return_if_fail (context != NULL);
g_return_if_fail (context->dptr != NULL);
-
+
/* I'm no clever bit-hacker so I'm sure this can be optimized */
dptr = context->dptr;
y = context->output_row;
wid = context->width;
-
- from = dptr + (wid - 1)/8;
+
+ from = dptr + ((wid - 1) / 8);
to = dptr + (wid - 1) * 3;
/* bit = 7 - (((y+1)*wid-1) % 8); */
- bit = 7 - ((wid-1) % 8);
-
+ bit = 7 - ((wid-1) % 8);
+
/* get first byte and align properly */
data = from[0];
for (j = 0; j < bit; j++, data >>= 1);
-
+
for (x = wid-1; x >= 0; x--) {
-
/* g_print ("%c", (data & 1) ? '*' : ' '); */
-
- to[0] = to[1] = to[2] = (data & 1) ? 0x00 : 0xff;
-
+
+ to[0] = to[1] = to[2] = (data & 0x01) ? 0x00 : 0xff;
+
to -= 3;
bit++;
-
+
if (bit > 7) {
from--;
data = from[0];
@@ -143,7 +146,7 @@ explode_bitmap_into_buf (PnmLoaderContext *context)
data >>= 1;
}
}
-
+
/* g_print ("\n"); */
}
@@ -154,10 +157,10 @@ explode_gray_into_buf (PnmLoaderContext *context)
gint j;
guchar *from, *to;
guint w;
-
+
g_return_if_fail (context != NULL);
g_return_if_fail (context->dptr != NULL);
-
+
/* Expand grey->colour. Expand from the end of the
* memory down, so we can use the same buffer.
*/
@@ -173,221 +176,203 @@ explode_gray_into_buf (PnmLoaderContext *context)
}
}
-/* skip over whitespace in file from current pos. */
-/* also skips comments */
-/* returns pointer to first non-whitespace char hit or, or NULL if */
-/* we ran out of data w/o hitting a whitespace */
-/* internal pointer in inbuf isnt moved ahead in this case */
-static guchar *
-skip_ahead_whitespace (PnmIOBuffer *inbuf)
-{
- gboolean in_comment;
- guchar *ptr;
- guint num_left;
-
- g_return_val_if_fail (inbuf != NULL, NULL);
- g_return_val_if_fail (inbuf->next_byte != NULL, NULL);
-
- in_comment = FALSE;
- num_left = inbuf->bytes_left;
- ptr = inbuf->next_byte;
- while (num_left > 0) {
- if (in_comment) {
- if (*ptr == '\n')
- in_comment = FALSE;
- } else if (*ptr == '#') {
- in_comment = TRUE;
- } else if (!isspace (*ptr)) {
- inbuf->bytes_left -= (ptr-inbuf->next_byte);
- inbuf->next_byte = ptr;
- return ptr;
- }
- ptr ++;
- num_left--;
- }
- return NULL;
-}
-
-/* reads into buffer until we hit whitespace in file from current pos, */
-/* return NULL if ran out of data */
-/* advances inbuf if successful */
-static guchar *
-read_til_whitespace (PnmIOBuffer *inbuf, guchar *buf, guint size)
+/* skip over whitespace and comments in input buffer */
+static gint
+pnm_skip_whitespace (PnmIOBuffer *inbuf)
{
- guchar *p;
- guchar *ptr;
- guint num_left;
-
- g_return_val_if_fail (inbuf != NULL, NULL);
- g_return_val_if_fail (inbuf->next_byte != NULL, NULL);
-
- p = buf;
- num_left = inbuf->bytes_left;
- ptr = inbuf->next_byte;
- while (num_left > 0 && (p-buf)+1 < size) {
- if (isspace (*ptr)) {
- *p = '\0';
- inbuf->bytes_left = num_left;
- inbuf->next_byte = ptr;
- return ptr;
- } else {
- *p = *ptr;
- p++;
- ptr++;
- num_left--;
+ register guchar *inptr;
+ guchar *inend;
+
+ g_return_val_if_fail (inbuf != NULL, PNM_FATAL_ERR);
+ g_return_val_if_fail (inbuf->byte != NULL, PNM_FATAL_ERR);
+
+ inend = inbuf->byte + inbuf->nbytes;
+ inptr = inbuf->byte;
+
+ for ( ; inptr < inend; inptr++) {
+ if (*inptr == '#') {
+ /* in comment - skip to the end of this line */
+ for ( ; *inptr != '\n' && inptr < inend; inptr++);
+ } else if (!isspace (*inptr)) {
+ inbuf->byte = inptr;
+ inbuf->nbytes = (guint) (inend - inptr);
+ return PNM_OK;
}
}
- return NULL;
+
+ inbuf->byte = inptr;
+ inbuf->nbytes = (guint) (inend - inptr);
+
+ return PNM_SUSPEND;
}
-/* read next number from buffer */
-/* -1 if failed, 0 if successful */
+/* read next number from buffer */
static gint
-read_next_number (PnmIOBuffer *inbuf, guint *value)
+pnm_read_next_value (PnmIOBuffer *inbuf, guint *value)
{
- guchar *tmpptr;
- guchar *old_next_byte;
- gchar *errptr;
- guint old_bytes_left;
- guchar buf[128];
-
- g_return_val_if_fail (inbuf != NULL, -1);
- g_return_val_if_fail (inbuf->next_byte != NULL, -1);
- g_return_val_if_fail (value != NULL, -1);
-
- old_next_byte = inbuf->next_byte;
- old_bytes_left = inbuf->bytes_left;
-
- if ((tmpptr = skip_ahead_whitespace (inbuf)) == NULL)
- return -1;
-
- if ((tmpptr = read_til_whitespace (inbuf, buf, 128)) == NULL) {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return -1;
- }
+ register guchar *inptr, *word, *p;
+ guchar *inend, buf[128];
+ gchar *endptr;
+ gint retval;
- *value = strtol (buf, &errptr, 10);
-
- if (*errptr != '\0') {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return -1;
- }
-
- return 0;
+ g_return_val_if_fail (inbuf != NULL, PNM_FATAL_ERR);
+ g_return_val_if_fail (inbuf->byte != NULL, PNM_FATAL_ERR);
+ g_return_val_if_fail (value != NULL, PNM_FATAL_ERR);
+
+ /* skip white space */
+ if ((retval = pnm_skip_whitespace (inbuf)) != PNM_OK)
+ return retval;
+
+ inend = inbuf->byte + inbuf->nbytes;
+ inptr = inbuf->byte;
+
+ /* copy this pnm 'word' into a temp buffer */
+ for (p = inptr, word = buf; (p < inend) && !isspace (*p) && (p - inptr < 128); p++, word++)
+ *word = *p;
+ *word = '\0';
+
+ /* hmmm, there must be more data to this 'word' */
+ if (!isspace (*p))
+ return PNM_SUSPEND;
+
+ /* get the value */
+ *value = strtol (buf, &endptr, 10);
+ if (*endptr != '\0')
+ return PNM_FATAL_ERR;
+
+ inbuf->byte = p;
+ inbuf->nbytes = (guint) (inend - p);
+
+ return PNM_OK;
}
/* returns PNM_OK, PNM_SUSPEND, or PNM_FATAL_ERR */
static gint
pnm_read_header (PnmLoaderContext *context)
{
- guchar *old_next_byte;
- guint old_bytes_left;
PnmIOBuffer *inbuf;
- guint w, h;
- gint rc;
- PnmFormat type;
-
- g_return_val_if_fail (context != NULL, PNM_FATAL_ERR);
-
- inbuf = &context->inbuf;
- old_bytes_left = inbuf->bytes_left;
- old_next_byte = inbuf->next_byte;
+ gint retval;
- /* file must start with a 'P' followed by a numeral */
- /* so loop till we get enough data to determine type*/
- if (inbuf->bytes_left < 2)
- return PNM_SUSPEND;
+ g_return_val_if_fail (context != NULL, PNM_FATAL_ERR);
- if (*inbuf->next_byte != 'P')
- return PNM_FATAL_ERR;
+ inbuf = &context->inbuf;
- switch (*(inbuf->next_byte+1)) {
- case '1':
- type = PNM_FORMAT_PBM;
- break;
- case '2':
- type = PNM_FORMAT_PGM;
- break;
- case '3':
- type = PNM_FORMAT_PPM;
- break;
- case '4':
- type = PNM_FORMAT_PBM_RAW;
- break;
- case '5':
- type = PNM_FORMAT_PGM_RAW;
- break;
- case '6':
- type = PNM_FORMAT_PPM_RAW;
- break;
- default:
- return PNM_FATAL_ERR;
+ if (!context->type) {
+ /* file must start with a 'P' followed by a numeral */
+ /* so loop till we get enough data to determine type */
+ if (inbuf->nbytes < 2)
+ return PNM_SUSPEND;
+
+ if (*inbuf->byte != 'P')
+ return PNM_FATAL_ERR;
+
+ inbuf->byte++;
+ inbuf->nbytes--;
+
+ switch (*inbuf->byte) {
+ case '1':
+ context->type = PNM_FORMAT_PBM;
+ break;
+ case '2':
+ context->type = PNM_FORMAT_PGM;
+ break;
+ case '3':
+ context->type = PNM_FORMAT_PPM;
+ break;
+ case '4':
+ context->type = PNM_FORMAT_PBM_RAW;
+ break;
+ case '5':
+ context->type = PNM_FORMAT_PGM_RAW;
+ break;
+ case '6':
+ context->type = PNM_FORMAT_PPM_RAW;
+ break;
+ default:
+ return PNM_FATAL_ERR;
+ }
+
+ if (!inbuf->nbytes)
+ return PNM_SUSPEND;
+
+ inbuf->byte++;
+ inbuf->nbytes--;
}
- context->type = type;
-
- inbuf->next_byte += 2;
- inbuf->bytes_left -= 2;
-
- /* now read remainder of header */
- if ((rc = read_next_number (inbuf, &w))) {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return PNM_SUSPEND;
+ if (!context->width) {
+ /* read the pixmap width */
+ guint width = 0;
+
+ retval = pnm_read_next_value (inbuf, &width);
+
+ if (retval != PNM_OK)
+ return retval;
+
+ if (!width)
+ return PNM_FATAL_ERR;
+
+ context->width = width;
}
- if ((rc = read_next_number (inbuf, &h))) {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return PNM_SUSPEND;
+ if (!context->height) {
+ /* read the pixmap height */
+ guint height = 0;
+
+ retval = pnm_read_next_value (inbuf, &height);
+
+ if (retval != PNM_OK)
+ return retval;
+
+ if (!height)
+ return PNM_FATAL_ERR;
+
+ context->height = height;
}
- context->width = w;
- context->height = h;
-
- switch (type) {
+ switch (context->type) {
case PNM_FORMAT_PPM:
case PNM_FORMAT_PPM_RAW:
case PNM_FORMAT_PGM:
case PNM_FORMAT_PGM_RAW:
- if ((rc = read_next_number (inbuf, &context->maxval)) < 0) {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return PNM_SUSPEND;
+ if (!context->maxval) {
+ retval = pnm_read_next_value (inbuf, &context->maxval);
+
+ if (retval != PNM_OK)
+ return retval;
+
+ if (context->maxval == 0)
+ return PNM_FATAL_ERR;
}
break;
default:
break;
}
-
+
return PNM_OK;
}
-
static gint
pnm_read_raw_scanline (PnmLoaderContext *context)
{
- guint numpix;
- guint numbytes, offset;
PnmIOBuffer *inbuf;
-
+ guint numbytes, offset;
+ guint numpix = 0;
+ guchar *dest;
+ guint i;
+
g_return_val_if_fail (context != NULL, PNM_FATAL_ERR);
-
-/*G_BREAKPOINT(); */
-
+
inbuf = &context->inbuf;
-
+
switch (context->type) {
case PNM_FORMAT_PBM_RAW:
- numpix = inbuf->bytes_left * 8;
+ numpix = inbuf->nbytes * 8;
break;
case PNM_FORMAT_PGM_RAW:
- numpix = inbuf->bytes_left;
+ numpix = inbuf->nbytes;
break;
case PNM_FORMAT_PPM_RAW:
- numpix = inbuf->bytes_left/3;
+ numpix = inbuf->nbytes / 3;
break;
default:
g_warning ("io-pnm.c: Illegal raw pnm type!\n");
@@ -395,79 +380,100 @@ pnm_read_raw_scanline (PnmLoaderContext *context)
}
numpix = MIN (numpix, context->width - context->output_col);
-
- if (numpix == 0)
+
+ if (!numpix)
return PNM_SUSPEND;
- context->dptr = context->pixels +
- context->output_row * context->rowstride;
+ context->dptr = context->pixels + context->output_row * context->rowstride;
switch (context->type) {
case PNM_FORMAT_PBM_RAW:
- numbytes = numpix/8 + ((numpix % 8) ? 1 : 0);
- offset = context->output_col/8;
+ numbytes = (numpix / 8) + ((numpix % 8) ? 1 : 0);
+ offset = context->output_col / 8;
break;
case PNM_FORMAT_PGM_RAW:
numbytes = numpix;
offset = context->output_col;
break;
case PNM_FORMAT_PPM_RAW:
- numbytes = numpix*3;
- offset = context->output_col*3;
+ numbytes = numpix * 3;
+ offset = context->output_col * 3;
break;
default:
g_warning ("io-pnm.c: Illegal raw pnm type!\n");
return PNM_FATAL_ERR;
}
- memcpy (context->dptr + offset, inbuf->next_byte, numbytes);
-
- inbuf->next_byte += numbytes;
- inbuf->bytes_left -= numbytes;
-
+ switch (context->type) {
+ case PNM_FORMAT_PBM_RAW:
+ dest = context->dptr + offset;
+ memcpy (dest, inbuf->byte, numbytes);
+ break;
+ case PNM_FORMAT_PGM_RAW:
+ case PNM_FORMAT_PPM_RAW:
+ dest = context->dptr + offset;
+
+ if (context->maxval == 255) {
+ /* special-case optimization */
+ memcpy (dest, inbuf->byte, numbytes);
+ } else {
+ for (i = 0; i < numbytes; i++) {
+ guchar *byte = inbuf->byte + i;
+
+ /* scale the color to an 8-bit color depth */
+ if (*byte > context->maxval)
+ *dest++ = 255;
+ else
+ *dest++ = (guchar) (255 * *byte / context->maxval);
+ }
+ }
+ break;
+ default:
+ g_warning ("Invalid raw pnm format!");
+ }
+
+ inbuf->byte += numbytes;
+ inbuf->nbytes -= numbytes;
+
context->output_col += numpix;
if (context->output_col == context->width) {
- if ( context->type == PNM_FORMAT_PBM_RAW )
- explode_bitmap_into_buf(context);
- else if ( context->type == PNM_FORMAT_PGM_RAW )
+ if (context->type == PNM_FORMAT_PBM_RAW)
+ explode_bitmap_into_buf (context);
+ else if (context->type == PNM_FORMAT_PGM_RAW)
explode_gray_into_buf (context);
context->output_col = 0;
context->output_row++;
-
} else {
return PNM_SUSPEND;
}
-
+
return PNM_OK;
}
-
static gint
pnm_read_ascii_scanline (PnmLoaderContext *context)
{
- guint offset;
- gint rc;
- guint value, numval, i;
+ PnmIOBuffer *inbuf;
+ guint offset;
+ guint value, numval, i;
guchar data;
guchar mask;
- guchar *old_next_byte, *dptr;
- guint old_bytes_left;
- PnmIOBuffer *inbuf;
-
+ guchar *dptr;
+ gint retval;
+
g_return_val_if_fail (context != NULL, PNM_FATAL_ERR);
-
+
data = mask = 0;
-
+
inbuf = &context->inbuf;
-
- context->dptr = context->pixels +
- context->output_row * context->rowstride;
-
+
+ context->dptr = context->pixels + context->output_row * context->rowstride;
+
switch (context->type) {
case PNM_FORMAT_PBM:
numval = MIN (8, context->width - context->output_col);
- offset = context->output_col/8;
+ offset = context->output_col / 8;
break;
case PNM_FORMAT_PGM:
numval = 1;
@@ -475,32 +481,31 @@ pnm_read_ascii_scanline (PnmLoaderContext *context)
break;
case PNM_FORMAT_PPM:
numval = 3;
- offset = context->output_col*3;
+ offset = context->output_col * 3;
break;
default:
g_warning ("Can't happen\n");
return PNM_FATAL_ERR;
}
-
- dptr = context->dptr + offset;
-
+
+ dptr = context->dptr + offset + context->scan_state;
+
while (TRUE) {
if (context->type == PNM_FORMAT_PBM) {
mask = 0x80;
data = 0;
numval = MIN (8, context->width - context->output_col);
}
-
- old_next_byte = inbuf->next_byte;
- old_bytes_left = inbuf->bytes_left;
-
- for (i=0; i<numval; i++) {
- if ((rc = read_next_number (inbuf, &value))) {
- inbuf->next_byte = old_next_byte;
- inbuf->bytes_left = old_bytes_left;
- return PNM_SUSPEND;
+
+ for (i = context->scan_state; i < numval; i++) {
+ retval = pnm_read_next_value (inbuf, &value);
+ if (retval != PNM_OK) {
+ /* save state and return */
+ context->scan_state = i;
+ return retval;
}
+
switch (context->type) {
case PNM_FORMAT_PBM:
if (value)
@@ -509,72 +514,73 @@ pnm_read_ascii_scanline (PnmLoaderContext *context)
break;
case PNM_FORMAT_PGM:
- *dptr++ = (guchar)(255.0*((double)value/(double)context->maxval));
- break;
case PNM_FORMAT_PPM:
- *dptr++ = (guchar)(255.0*((double)value/(double)context->maxval));
+ /* scale the color to an 8-bit color depth */
+ if (value > context->maxval)
+ *dptr++ = 255;
+ else
+ *dptr++ = (guchar)(255 * value / context->maxval);
break;
default:
- g_warning ("io-pnm.c: Illegal raw pnm type!\n");
+ g_warning ("io-pnm.c: Illegal ascii pnm type!\n");
break;
}
}
+ context->scan_state = 0;
+
if (context->type == PNM_FORMAT_PBM) {
*dptr++ = data;
context->output_col += numval;
} else {
context->output_col++;
}
-
+
if (context->output_col == context->width) {
- if ( context->type == PNM_FORMAT_PBM )
- explode_bitmap_into_buf(context);
- else if ( context->type == PNM_FORMAT_PGM )
+ if (context->type == PNM_FORMAT_PBM)
+ explode_bitmap_into_buf (context);
+ else if (context->type == PNM_FORMAT_PGM)
explode_gray_into_buf (context);
-
+
context->output_col = 0;
context->output_row++;
break;
}
-
}
-
+
return PNM_OK;
}
-/* returns 1 if a scanline was converted, 0 means we ran out of data */
+/* returns 1 if a scanline was converted, 0 means we ran out of data */
static gint
pnm_read_scanline (PnmLoaderContext *context)
{
- gint rc;
-
+ gint retval;
+
g_return_val_if_fail (context != NULL, PNM_FATAL_ERR);
-
+
/* read in image data */
/* for raw formats this is trivial */
switch (context->type) {
case PNM_FORMAT_PBM_RAW:
case PNM_FORMAT_PGM_RAW:
case PNM_FORMAT_PPM_RAW:
- rc = pnm_read_raw_scanline (context);
- if (rc == PNM_SUSPEND)
- return rc;
+ retval = pnm_read_raw_scanline (context);
+ if (retval != PNM_OK)
+ return retval;
break;
-
case PNM_FORMAT_PBM:
case PNM_FORMAT_PGM:
case PNM_FORMAT_PPM:
- rc = pnm_read_ascii_scanline (context);
- if (rc == PNM_SUSPEND)
- return rc;
+ retval = pnm_read_ascii_scanline (context);
+ if (retval != PNM_OK)
+ return retval;
break;
-
default:
g_warning ("Cannot load these image types (yet)\n");
return PNM_FATAL_ERR;
}
-
+
return PNM_OK;
}
@@ -582,99 +588,104 @@ pnm_read_scanline (PnmLoaderContext *context)
GdkPixbuf *
gdk_pixbuf__pnm_image_load (FILE *f)
{
- gint nbytes;
- gint rc;
-
PnmLoaderContext context;
PnmIOBuffer *inbuf;
-
+ gint nbytes;
+ gint retval;
+
/* pretend to be doing progressive loading */
context.updated_func = NULL;
context.prepared_func = NULL;
context.user_data = NULL;
- context.inbuf.bytes_left = 0;
- context.inbuf.next_byte = NULL;
+ context.type = 0;
+ context.inbuf.nbytes = 0;
+ context.inbuf.byte = NULL;
+ context.width = 0;
+ context.height = 0;
+ context.maxval = 0;
context.pixels = NULL;
context.pixbuf = NULL;
- context.got_header = context.did_prescan = FALSE;
-
+ context.got_header = FALSE;
+ context.did_prescan = FALSE;
+ context.scan_state = 0;
+
inbuf = &context.inbuf;
-
- while (TRUE) {
- guint num_to_read;
-
+
+ while (!feof (f)) {
+ guint num_to_read;
+
/* keep buffer as full as possible */
- num_to_read = PNM_BUF_SIZE - inbuf->bytes_left;
-
- if (inbuf->next_byte != NULL && inbuf->bytes_left > 0)
- memmove (inbuf->buffer, inbuf->next_byte,
- inbuf->bytes_left);
-
- nbytes = fread (inbuf->buffer+inbuf->bytes_left,
- 1, num_to_read, f);
- inbuf->bytes_left += nbytes;
- inbuf->next_byte = inbuf->buffer;
-
- /* ran out of data and we haven't exited main loop */
- if (inbuf->bytes_left == 0) {
+ num_to_read = PNM_BUF_SIZE - inbuf->nbytes;
+
+ if (inbuf->byte != NULL && inbuf->nbytes > 0)
+ memmove (inbuf->buffer, inbuf->byte, inbuf->nbytes);
+
+ nbytes = fread (inbuf->buffer + inbuf->nbytes, 1, num_to_read, f);
+
+ /* error checking */
+ if (nbytes == 0 && ferror (f)) {
+ /* we ran out of data? */
if (context.pixbuf)
gdk_pixbuf_unref (context.pixbuf);
- g_warning ("io-pnm.c: Ran out of data...\n");
+ g_warning ("io-pnm.c: Ran out of data.\n");
return NULL;
}
-
+
+ inbuf->nbytes += nbytes;
+ inbuf->byte = inbuf->buffer;
+
/* get header if needed */
if (!context.got_header) {
-
- rc = pnm_read_header (&context);
- if (rc == PNM_FATAL_ERR)
+ retval = pnm_read_header (&context);
+ if (retval == PNM_FATAL_ERR)
return NULL;
- else if (rc == PNM_SUSPEND)
+ else if (retval == PNM_SUSPEND)
continue;
-
+
context.got_header = TRUE;
}
-
+
/* scan until we hit image data */
if (!context.did_prescan) {
-
- if (skip_ahead_whitespace (inbuf) == NULL)
+ retval = pnm_skip_whitespace (inbuf);
+ if (retval == PNM_FATAL_ERR)
+ return NULL;
+ else if (retval == PNM_SUSPEND)
continue;
-
+
context.did_prescan = TRUE;
context.output_row = 0;
context.output_col = 0;
-
+
context.rowstride = context.width * 3;
- context.pixels = g_malloc (context.height *
- context.width * 3);
+ context.pixels = g_malloc (context.height * context.width * 3);
+
if (!context.pixels) {
/* Failed to allocate memory */
- g_error ("Couldn't allocate pixel buf");
+ g_warning ("Couldn't allocate pixel buf");
}
}
-
+
/* if we got here we're reading image data */
while (context.output_row < context.height) {
-
- rc = pnm_read_scanline (&context);
-
- if (rc == PNM_SUSPEND) {
+ retval = pnm_read_scanline (&context);
+
+ if (retval == PNM_SUSPEND) {
break;
- } else if (rc == PNM_FATAL_ERR) {
+ } else if (retval == PNM_FATAL_ERR) {
if (context.pixbuf)
gdk_pixbuf_unref (context.pixbuf);
g_warning ("io-pnm.c: error reading rows..\n");
return NULL;
}
}
-
+
if (context.output_row < context.height)
continue;
else
break;
}
-
+
return gdk_pixbuf_new_from_data (context.pixels, GDK_COLORSPACE_RGB, FALSE, 8,
context.width, context.height,
context.width * 3, free_buffer, NULL);
@@ -695,19 +706,23 @@ gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func,
gpointer user_data)
{
PnmLoaderContext *context;
-
+
context = g_new0 (PnmLoaderContext, 1);
context->prepared_func = prepared_func;
context->updated_func = updated_func;
context->user_data = user_data;
+ context->width = 0;
+ context->height = 0;
+ context->maxval = 0;
context->pixbuf = NULL;
context->pixels = NULL;
context->got_header = FALSE;
context->did_prescan = FALSE;
-
- context->inbuf.bytes_left = 0;
- context->inbuf.next_byte = NULL;
-
+ context->scan_state = 0;
+
+ context->inbuf.nbytes = 0;
+ context->inbuf.byte = NULL;
+
return (gpointer) context;
}
@@ -720,18 +735,15 @@ void
gdk_pixbuf__pnm_image_stop_load (gpointer data)
{
PnmLoaderContext *context = (PnmLoaderContext *) data;
-
+
g_return_if_fail (context != NULL);
-
+
if (context->pixbuf)
gdk_pixbuf_unref (context->pixbuf);
-
+
g_free (context);
}
-
-
-
/*
* context - from image_begin_load
* buf - new image data
@@ -743,103 +755,104 @@ gboolean
gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size)
{
PnmLoaderContext *context = (PnmLoaderContext *)data;
- PnmIOBuffer *inbuf;
-
- guchar *old_next_byte;
- guint old_bytes_left;
+ PnmIOBuffer *inbuf;
+ guchar *old_byte;
+ guint old_nbytes;
guchar *bufhd;
- guint num_left, spinguard;
- gint rc;
-
+ guint num_left, spinguard;
+ gint retval;
+
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (buf != NULL, FALSE);
-
+
bufhd = buf;
inbuf = &context->inbuf;
- old_bytes_left = inbuf->bytes_left;
- old_next_byte = inbuf->next_byte;
-
+ old_nbytes = inbuf->nbytes;
+ old_byte = inbuf->byte;
+
num_left = size;
spinguard = 0;
while (TRUE) {
guint num_to_copy;
-
+
/* keep buffer as full as possible */
- num_to_copy = MIN (PNM_BUF_SIZE - inbuf->bytes_left, num_left);
+ num_to_copy = MIN (PNM_BUF_SIZE - inbuf->nbytes, num_left);
if (num_to_copy == 0)
spinguard++;
-
+
if (spinguard > 1)
return TRUE;
-
- if (inbuf->next_byte != NULL && inbuf->bytes_left > 0)
- memmove (inbuf->buffer, inbuf->next_byte,
- inbuf->bytes_left);
-
- memcpy (inbuf->buffer + inbuf->bytes_left, bufhd, num_to_copy);
+
+ if (inbuf->byte != NULL && inbuf->nbytes > 0)
+ memmove (inbuf->buffer, inbuf->byte, inbuf->nbytes);
+
+ memcpy (inbuf->buffer + inbuf->nbytes, bufhd, num_to_copy);
bufhd += num_to_copy;
- inbuf->bytes_left += num_to_copy;
- inbuf->next_byte = inbuf->buffer;
+ inbuf->nbytes += num_to_copy;
+ inbuf->byte = inbuf->buffer;
num_left -= num_to_copy;
/* ran out of data and we haven't exited main loop */
- if (inbuf->bytes_left == 0)
+ if (inbuf->nbytes == 0)
return TRUE;
-
+
/* get header if needed */
if (!context->got_header) {
- rc = pnm_read_header (context);
- if (rc == PNM_FATAL_ERR)
+ retval = pnm_read_header (context);
+
+ if (retval == PNM_FATAL_ERR)
return FALSE;
- else if (rc == PNM_SUSPEND)
+ else if (retval == PNM_SUSPEND)
continue;
-
+
context->got_header = TRUE;
}
-
+
/* scan until we hit image data */
if (!context->did_prescan) {
- if (skip_ahead_whitespace (inbuf) == NULL)
+ retval = pnm_skip_whitespace (inbuf);
+
+ if (retval == PNM_FATAL_ERR)
+ return FALSE;
+ else if (retval == PNM_SUSPEND)
continue;
-
+
context->did_prescan = TRUE;
context->output_row = 0;
context->output_col = 0;
-
- context->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- FALSE,
- 8,
- context->width,
- context->height);
-
+
+ context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE,
+ 8,
+ context->width,
+ context->height);
+
if (context->pixbuf == NULL) {
/* Failed to allocate memory */
g_error ("Couldn't allocate gdkpixbuf");
}
-
+
context->pixels = context->pixbuf->pixels;
context->rowstride = context->pixbuf->rowstride;
-
+
/* Notify the client that we are ready to go */
(* context->prepared_func) (context->pixbuf,
context->user_data);
-
}
-
+
/* if we got here we're reading image data */
while (context->output_row < context->height) {
- rc = pnm_read_scanline (context);
-
- if (rc == PNM_SUSPEND) {
+ retval = pnm_read_scanline (context);
+
+ if (retval == PNM_SUSPEND) {
break;
- } else if (rc == PNM_FATAL_ERR) {
+ } else if (retval == PNM_FATAL_ERR) {
if (context->pixbuf)
gdk_pixbuf_unref (context->pixbuf);
- g_warning ("io-pnm.c: error reading rows..\n");
+ g_warning ("io-pnm.c: error reading rows.\n");
return FALSE;
- } else if (rc == PNM_OK) {
-
+ } else if (retval == PNM_OK) {
/* send updated signal */
(* context->updated_func) (context->pixbuf,
0,
@@ -849,12 +862,12 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size)
context->user_data);
}
}
-
+
if (context->output_row < context->height)
continue;
else
break;
}
-
+
return TRUE;
}
diff --git a/gdk-pixbuf/io-tiff.c b/gdk-pixbuf/io-tiff.c
index dcc1ea66b..fdf517463 100644
--- a/gdk-pixbuf/io-tiff.c
+++ b/gdk-pixbuf/io-tiff.c
@@ -171,12 +171,14 @@ gdk_pixbuf__tiff_image_begin_load (ModulePreparedNotifyFunc prepare_func,
fd = open (context->tempname, O_RDWR);
#endif
if (fd < 0) {
+ g_free (context->tempname);
g_free (context);
return NULL;
}
context->file = fdopen (fd, "w");
if (context->file == NULL) {
+ g_free (context->tempname);
g_free (context);
return NULL;
}
diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c
index c94658564..17e2a43f4 100644
--- a/gdk-pixbuf/io-xpm.c
+++ b/gdk-pixbuf/io-xpm.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <glib.h>
#include "gdk-pixbuf-private.h"
+#include "gdk-pixbuf-io.h"
@@ -977,7 +978,8 @@ xpm_seek_string (FILE *infile, const gchar *str, gint skip_comments)
char instr[1024];
while (!feof (infile)) {
- fscanf (infile, "%1023s", instr);
+ if (fscanf (infile, "%1023s", instr) < 0)
+ return FALSE;
if (skip_comments == TRUE && strcmp (instr, "/*") == 0) {
fscanf (infile, "%1023s", instr);
while (!feof (infile) && strcmp (instr, "*/") != 0)
@@ -1373,3 +1375,97 @@ gdk_pixbuf__xpm_image_load_xpm_data (const gchar **data)
return pixbuf;
}
+
+/* Progressive loader */
+typedef struct _XPMContext XPMContext;
+struct _XPMContext
+{
+ ModulePreparedNotifyFunc prepare_func;
+ ModuleUpdatedNotifyFunc update_func;
+ gpointer user_data;
+
+ gchar *tempname;
+ FILE *file;
+ gboolean all_okay;
+};
+
+/*
+ * FIXME xpm loading progressively is not properly implemented.
+ * Instead we will buffer to a file then load that file when done.
+ * This is very broken but it should be relayively simple to fix
+ * in the future.
+ */
+gpointer
+gdk_pixbuf__xpm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
+ ModuleUpdatedNotifyFunc update_func,
+ ModuleFrameDoneNotifyFunc frame_done_func,
+ ModuleAnimationDoneNotifyFunc anim_done_func,
+ gpointer user_data)
+{
+ XPMContext *context;
+ gint fd;
+
+ g_warning ("load start");
+ context = g_new (XPMContext, 1);
+ context->prepare_func = prepare_func;
+ context->update_func = update_func;
+ context->user_data = user_data;
+ context->all_okay = TRUE;
+ context->tempname = g_strdup ("/tmp/gdkpixbuf-xpm-tmp.XXXXXX");
+ fd = mkstemp (context->tempname);
+ if (fd < 0) {
+ g_free (context->tempname);
+ g_free (context);
+ return NULL;
+ }
+
+ context->file = fdopen (fd, "w+");
+ if (context->file == NULL) {
+ g_free (context->tempname);
+ g_free (context);
+ return NULL;
+ }
+
+ return context;
+}
+
+void
+gdk_pixbuf__xpm_image_stop_load (gpointer data)
+{
+ XPMContext *context = (XPMContext*) data;
+ GdkPixbuf *pixbuf;
+
+ g_return_if_fail (data != NULL);
+ g_warning ("stopped loading");
+
+ fflush (context->file);
+ rewind (context->file);
+ if (context->all_okay) {
+ pixbuf = gdk_pixbuf__xpm_image_load (context->file);
+
+ (* context->prepare_func) (pixbuf, context->user_data);
+ (* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
+ gdk_pixbuf_unref (pixbuf);
+ }
+
+ fclose (context->file);
+ unlink (context->tempname);
+ g_free (context->tempname);
+ g_free ((XPMContext *) context);
+}
+
+gboolean
+gdk_pixbuf__xpm_image_load_increment (gpointer data, guchar *buf, guint size)
+{
+ XPMContext *context = (XPMContext *) data;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_warning ("load increment");
+
+ if (fwrite (buf, sizeof (guchar), size, context->file) != size) {
+ context->all_okay = FALSE;
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
index 6714133a9..ea1960715 100644
--- a/gdk-pixbuf/pixops/pixops.c
+++ b/gdk-pixbuf/pixops/pixops.c
@@ -160,7 +160,8 @@ pixops_composite_nearest (guchar *dest_buf,
for (i = 0; i < (render_y1 - render_y0); i++)
{
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
- guchar *dest = dest_buf + i * dest_rowstride + render_x0 * dest_channels;
+ /* FIXME Owen needs to look at this */
+ guchar *dest = dest_buf + i * dest_rowstride;
x = render_x0 * x_step + x_step / 2;