Mercurial > hg > xemacs-beta
diff src/glyphs-eimage.c @ 4708:1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
routines. Delete internal GIF support code with no stated license. Fix up
a number of references in the documentation to GIF support. See discussion
on xemacs-beta: <87iqg4vg9t.fsf@uwakimon.sk.tsukuba.ac.jp>.
author | Jerry James <james@xemacs.org> |
---|---|
date | Mon, 05 Oct 2009 10:11:59 -0600 |
parents | a9493cab536f |
children | b3ea9c582280 |
line wrap: on
line diff
--- a/src/glyphs-eimage.c Sat Oct 03 14:22:08 2009 +0100 +++ b/src/glyphs-eimage.c Mon Oct 05 10:11:59 2009 -0600 @@ -34,6 +34,7 @@ Many changes for color work and optimizations by Jareth Hein for 21.0 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 TIFF code by Jareth Hein for 21.0 + GIF support changed to external giflib by Jerry James for 21.5 TODO: Convert images.el to C and stick it in here? This file is really repetitious; can we refactor? @@ -527,7 +528,7 @@ * GIF * **********************************************************************/ -#include "gifrlib.h" +#include <gif_lib.h> static void gif_validate (Lisp_Object instantiator) @@ -569,7 +570,7 @@ if (data->giffile) { DGifCloseFile (data->giffile); - GifFree(data->giffile); + FreeSavedImages(data->giffile); } if (data->eimage) xfree (data->eimage, Binbyte *); @@ -584,10 +585,10 @@ Bytecount index; /* Where are we? */ } gif_memory_storage; -static Bytecount -gif_read_from_memory (GifByteType *buf, Bytecount size, VoidPtr data) +static int +gif_read_from_memory (GifFileType *gif, GifByteType *buf, int size) { - gif_memory_storage *mem = (gif_memory_storage *) data; + gif_memory_storage *mem = (gif_memory_storage *) gif->UserData; if (size > (mem->len - mem->index)) return -1; @@ -596,26 +597,40 @@ return size; } -static int -gif_memory_close (VoidPtr UNUSED (data)) -{ - return 0; -} - -struct gif_error_struct +static const char * +gif_decode_error_string () { - const Extbyte *err_str; /* return the error string */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -static void -gif_error_func (const Extbyte *err_str, VoidPtr error_ptr) -{ - struct gif_error_struct *error_data = (struct gif_error_struct *) error_ptr; - - /* return to setjmp point */ - error_data->err_str = err_str; - longjmp (error_data->setjmp_buffer, 1); + switch (GifLastError ()) + { + case D_GIF_ERR_OPEN_FAILED: + return "GIF error: unable to open"; + case D_GIF_ERR_READ_FAILED: + return "GIF error: read failed"; + case D_GIF_ERR_NOT_GIF_FILE: + return "GIF error: not a GIF file"; + case D_GIF_ERR_NO_SCRN_DSCR: + return "GIF error: no Screen Descriptor detected"; + case D_GIF_ERR_NO_IMAG_DSCR: + return "GIF error: no Image Descriptor detected"; + case D_GIF_ERR_NO_COLOR_MAP: + return "GIF error: no global or local color map"; + case D_GIF_ERR_WRONG_RECORD: + return "GIF error: wrong record type"; + case D_GIF_ERR_DATA_TOO_BIG: + return "GIF error: image is larger than indicated by header"; + case D_GIF_ERR_NOT_ENOUGH_MEM: + return "GIF error: out of memory"; + case D_GIF_ERR_CLOSE_FAILED: + return "GIF error: failed to close file"; + case D_GIF_ERR_NOT_READABLE: + return "GIF error: file is not readable"; + case D_GIF_ERR_IMAGE_DEFECT: + return "GIF error: image is defective"; + case D_GIF_ERR_EOF_TOO_SOON: + return "GIF error: image EOF detected before image complete"; + default: + return "GIF error: unknown error"; + } } static void @@ -630,7 +645,6 @@ struct gif_unwind_data unwind; int speccount = specpdl_depth (); gif_memory_storage mem_struct; - struct gif_error_struct gif_err; Binbyte *bytes; Bytecount len; int height = 0; @@ -646,35 +660,19 @@ assert (!NILP (data)); - if (!(unwind.giffile = GifSetup())) - signal_image_error ("Insufficient memory to instantiate GIF image", instantiator); - - /* set up error facilities */ - if (setjmp(gif_err.setjmp_buffer)) - { - /* An error was signaled. No clean up is needed, as unwind handles that - for us. Just pass the error along. */ - Ibyte *interr; - Lisp_Object errstring; - EXTERNAL_TO_C_STRING (gif_err.err_str, interr, Qnative); - errstring = build_msg_intstring (interr); - signal_image_error_2 ("GIF decoding error", errstring, instantiator); - } - GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err); - TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary); mem_struct.bytes = bytes; mem_struct.len = len; mem_struct.index = 0; - GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct); - GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct); - DGifInitRead(unwind.giffile); + unwind.giffile = DGifOpen (&mem_struct, gif_read_from_memory); + if (unwind.giffile == NULL) + signal_image_error (gif_decode_error_string (), instantiator); /* Then slurp the image into memory, decoding along the way. The result is the image in a simple one-byte-per-pixel - format (#### the GIF routines only support 8-bit GIFs, - it appears). */ - DGifSlurp (unwind.giffile); + format. */ + if (DGifSlurp (unwind.giffile) == GIF_ERROR) + signal_image_error (gif_decode_error_string (), instantiator); } /* 3. Now create the EImage(s) */ @@ -748,7 +746,7 @@ if (unwind.giffile->ImageCount > 1) { /* See if there is a timeout value. In theory there could be one - for every image - but that makes the implementation way to + for every image - but that makes the implementation way too complicated for now so we just take the first. */ unsigned short timeout = 0; Lisp_Object tid;