diff options
author | Mark Crichton <crichton@src.gnome.org> | 1999-06-29 06:07:14 +0000 |
---|---|---|
committer | Mark Crichton <crichton@src.gnome.org> | 1999-06-29 06:07:14 +0000 |
commit | 42311804a42482bde8e34208cce943b0d85d454c (patch) | |
tree | e313f978da49fb5b7d76173b5a7c3b22802932ca /gdk-pixbuf | |
parent | a83f00d89e734894e5b3958f4b055edc4aec6266 (diff) | |
download | gdk-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.c | 156 | ||||
-rw-r--r-- | gdk-pixbuf/io-png.c | 4 |
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]); |