summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorMark Crichton <crichton@src.gnome.org>1999-06-29 06:07:14 +0000
committerMark Crichton <crichton@src.gnome.org>1999-06-29 06:07:14 +0000
commit42311804a42482bde8e34208cce943b0d85d454c (patch)
treee313f978da49fb5b7d76173b5a7c3b22802932ca /gdk-pixbuf
parenta83f00d89e734894e5b3958f4b055edc4aec6266 (diff)
downloadgdk-pixbuf-42311804a42482bde8e34208cce943b0d85d454c.tar.gz
io-png.c: changed g_malloc call for pixles to art_alloc (to be "correct")
io-png.c: changed g_malloc call for pixles to art_alloc (to be "correct") io-gif.c: implemented GIF file loading.
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/io-gif.c156
-rw-r--r--gdk-pixbuf/io-png.c4
2 files changed, 158 insertions, 2 deletions
diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
new file mode 100644
index 000000000..c3252db3c
--- /dev/null
+++ b/gdk-pixbuf/io-gif.c
@@ -0,0 +1,156 @@
+/*
+ * io-png.c: GdkPixBuf I/O for GIF files.
+ * ...second verse, same as the first...
+ *
+ * Author:
+ * Mark Crichton <crichton@gimp.org>
+ *
+ */
+#include <config.h>
+#include <stdio.h>
+#include <glib.h>
+#include "gdk-pixbuf.h"
+#include "gdk-pixbuf-io.h"
+#include <gif_lib.h>
+
+/* Shared library entry point */
+GdkPixBuf *image_load(FILE * f)
+{
+ gint fn, is_trans, done;
+ gint t_color = -1;
+ gint w, h, i, j;
+ art_u8 *pixels, *tmpptr;
+ GifFileType *gif;
+ GifRowType *rows;
+ GifRecordType rec;
+ ColorMapObject *cmap;
+ int intoffset[] = {0, 4, 2, 1};
+ int intjump[] = {8, 8, 4, 2};
+
+ GdkPixBuf *pixbuf;
+
+ g_return_val_if_fail(f != NULL, NULL);
+
+ fn = fileno(f);
+ gif = DGifOpenFileHandle(fn);
+
+ if (!gif) {
+ g_error("DGifOpenFilehandle FAILED");
+ PrintGifError();
+ return NULL;
+ }
+ /* Now we do the ungodly mess of loading a GIF image
+ * I used to remember when I liked this file format...
+ * of course, I still coded in assembler then.
+ * This comes from gdk_imlib, with some cleanups.
+ */
+
+ do {
+ if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
+ PrintGifError();
+ rec = TERMINATE_RECORD_TYPE;
+ }
+ if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
+ if (DGifGetImageDesc(gif) == GIF_ERROR) {
+ PrintGifError();
+ rec = TERMINATE_RECORD_TYPE;
+ }
+ w = gif->Image.Width;
+ h = gif->Image.Height;
+ rows = g_malloc(h * sizeof(GifRowType *));
+ if (!rows) {
+ DGifCloseFile(gif);
+ return NULL;
+ }
+ for (i = 0; i < h; i++) {
+ rows[i] = g_malloc(w * sizeof(GifPixelType));
+ if (!rows[i]) {
+ DGifCloseFile(gif);
+ for (i = 0; i < h; i++)
+ if (rows[i])
+ g_free(rows[i]);
+ free(rows);
+ return NULL;
+ }
+ }
+ if (gif->Image.Interlace) {
+ for (i = 0; i < 4; i++) {
+ for (j = intoffset[i]; j < h; j += intjump[i])
+ DGifGetLine(gif, rows[j], w);
+ }
+ } else {
+ for (i = 0; i < h; i++)
+ DGifGetLine(gif, rows[i], w);
+ }
+ done = TRUE;
+ } else if (rec == EXTENSION_RECORD_TYPE) {
+ gint ext_code;
+ GifByteType *ext;
+
+ DGifGetExtension(gif, &ext_code, &ext);
+ while (ext) {
+ if ((ext_code == GRAPHICS_EXT_FUNC_CODE) &&
+ (ext[1] & 1) && (t_color < 0)) {
+ is_trans = TRUE;
+ t_color = (gint) ext[4];
+ }
+ ext = NULL;
+ DGifGetExtensionNext(gif, &ext);
+ }
+ }
+ }
+ while (rec != TERMINATE_RECORD_TYPE);
+
+ /* Ok, we're loaded, now to convert from indexed -> RGB
+ * with alpha if necessary
+ */
+
+ if (is_trans)
+ pixels = art_alloc(h * w * 4);
+ else
+ pixels = art_alloc(h * w * 3);
+ tmpptr = pixels;
+
+ if (!pixels)
+ return NULL;
+
+ /* The meat of the transformation */
+ /* Get the right palette */
+ cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
+
+ /* Unindex the data, and pack it in RGB(A) order.
+ * Note for transparent GIFs, the alpha is set to 0
+ * for the transparent color, and 0xFF for everything else.
+ * I think that's right...
+ */
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ tmpptr[0] = cmap->Colors[rows[i][j]].Red;
+ tmpptr[1] = cmap->Colors[rows[i][j]].Green;
+ tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
+ if (is_trans && (rows[i][j] == t_color))
+ tmpptr[3] = 0;
+ else
+ tmpptr[3] = 0xFF;
+ tmpptr += (is_trans ? 3 : 4);
+ }
+ }
+
+ /* Ok, now stuff the GdkPixBuf with goodies */
+
+ pixbuf = g_new(GdkPixBuf, 1);
+
+ if (is_trans)
+ pixbuf->art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
+ else
+ pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
+
+ /* Ok, I'm anal...shoot me */
+ if (!(pixbuf->art_pixbuf))
+ return NULL;
+ pixbuf->ref_count = 0;
+ pixbuf->unref_func = NULL;
+
+ return pixbuf;
+}
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
index 70d2df645..789a08645 100644
--- a/gdk-pixbuf/io-png.c
+++ b/gdk-pixbuf/io-png.c
@@ -91,7 +91,7 @@ GdkPixBuf *image_load(FILE * f)
else
bpp = 3;
- pixels = g_malloc(w*h*bpp);
+ pixels = art_alloc(w*h*bpp);
rows = g_malloc(h*sizeof(png_bytep));
if ((!pixels) || (!rows)) {
@@ -126,7 +126,7 @@ GdkPixBuf *image_load(FILE * f)
temp[1] = rowdata[(x*bpp)+1];
temp[2] = rowdata[(x*bpp)+2];
if (bpp == 4)
- temp[3] = rowdata[(x*4)+3];
+ temp[3] = rowdata[(x*bpp)+3];
temp += bpp;
}
g_free(rows[y]);