"Return non-nil if image can be animated.
Actually, the return value is a cons (NIMAGES . DELAY), where
NIMAGES is the number of sub-images in the animated image and
-DELAY is the delay in 100ths of a second until the next sub-image
-shall be displayed."
+DELAY is the delay in second until the next sub-image shall be
+displayed."
(cond
((eq (plist-get (cdr image) :type) 'gif)
(let* ((metadata (image-metadata image))
(images (plist-get metadata 'count))
- (extdata (plist-get metadata 'extension-data))
- (anim (plist-get extdata #xF9))
- (tmo (and (integerp images) (> images 1)
- (stringp anim) (>= (length anim) 4)
- (+ (aref anim 1) (* (aref anim 2) 256)))))
- (when tmo
- (if (eq tmo 0) (setq tmo 10))
- (cons images tmo))))))
+ (delay (plist-get metadata 'delay)))
+ (when (and images (> images 1) (numberp delay))
+ (if (< delay 0) (setq delay 0.1))
+ (cons images delay))))))
(defun image-animate (image &optional index limit)
"Start animating IMAGE.
LIMIT specifies how long to animate the image. If omitted or
nil, play the animation until the end. If t, loop forever. If a
number, play until that number of seconds has elapsed."
- (let ((anim (image-animated-p image))
- delay timer)
- (when anim
+ (let ((animation (image-animated-p image))
+ timer)
+ (when animation
(if (setq timer (image-animate-timer image))
(cancel-timer timer))
- (setq delay (max (* (cdr anim) 0.01) 0.025))
- (run-with-timer 0.2 nil #'image-animate-timeout
- image (or index 0) (car anim)
- delay 0 limit))))
+ (run-with-timer 0.2 nil 'image-animate-timeout
+ image (or index 0) (car animation)
+ 0 limit))))
(defun image-animate-timer (image)
"Return the animation timer for image IMAGE."
(setq timer nil)))
timer))
-(defun image-animate-timeout (image n count delay time-elapsed limit)
+(defun image-animate-timeout (image n count time-elapsed limit)
"Display animation frame N of IMAGE.
N=0 refers to the initial animation frame.
COUNT is the total number of frames in the animation.
LIMIT determines when to stop. If t, loop forever. If nil, stop
after displaying the last animation frame. Otherwise, stop
after LIMIT seconds have elapsed."
- (let (done)
- (plist-put (cdr image) :index n)
- (force-window-update)
- (setq n (1+ n))
+ (plist-put (cdr image) :index n)
+ (force-window-update)
+ (setq n (1+ n))
+ (let* ((time (float-time))
+ (animation (image-animated-p image))
+ ;; Subtract off the time we took to load the image from the
+ ;; stated delay time.
+ (delay (max (+ (cdr animation) time (- (float-time)))
+ 0.01))
+ done)
(if (>= n count)
(if limit
(setq n 0)
(setq done (>= time-elapsed limit)))
(unless done
(run-with-timer delay nil 'image-animate-timeout
- image n count delay
- time-elapsed limit))))
+ image n count time-elapsed limit))))
\f
(defcustom imagemagick-types-inhibit
/* Keywords. */
Lisp_Object QCascent, QCmargin, QCrelief;
-static Lisp_Object Qcount, Qextension_data;
Lisp_Object QCconversion;
static Lisp_Object QCheuristic_mask;
static Lisp_Object QCcolor_symbols;
/* Other symbols. */
+static Lisp_Object Qcount, Qextension_data, Qdelay;
static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
/* Function prototypes. */
img->lisp_data = Qnil;
if (gif->SavedImages[idx].ExtensionBlockCount > 0)
{
+ unsigned int delay = 0;
ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
/* Append (... FUNCTION "BYTES") */
- img->lisp_data = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
- Fcons (make_number (ext->Function),
- img->lisp_data));
+ {
+ img->lisp_data
+ = Fcons (make_number (ext->Function),
+ Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
+ img->lisp_data));
+ if (ext->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION
+ && ext->ByteCount == 4)
+ {
+ delay = ext->Bytes[2] << CHAR_BIT;
+ delay |= ext->Bytes[1];
+ }
+ }
img->lisp_data = Fcons (Qextension_data,
- Fcons (Fnreverse (img->lisp_data),
- Qnil));
+ Fcons (img->lisp_data, Qnil));
+ if (delay)
+ img->lisp_data
+ = Fcons (Qdelay,
+ Fcons (make_float (((double) delay) * 0.01),
+ img->lisp_data));
}
+
if (gif->ImageCount > 1)
img->lisp_data = Fcons (Qcount,
Fcons (make_number (gif->ImageCount),
non-numeric, there is no explicit limit on the size of images. */);
Vmax_image_size = make_float (MAX_IMAGE_SIZE);
- Qpbm = intern_c_string ("pbm");
- staticpro (&Qpbm);
+ DEFSYM (Qpbm, "pbm");
ADD_IMAGE_TYPE (Qpbm);
- Qxbm = intern_c_string ("xbm");
- staticpro (&Qxbm);
+ DEFSYM (Qxbm, "xbm");
ADD_IMAGE_TYPE (Qxbm);
define_image_type (&xbm_type, 1);
define_image_type (&pbm_type, 1);
- Qcount = intern_c_string ("count");
- staticpro (&Qcount);
- Qextension_data = intern_c_string ("extension-data");
- staticpro (&Qextension_data);
-
- QCascent = intern_c_string (":ascent");
- staticpro (&QCascent);
- QCmargin = intern_c_string (":margin");
- staticpro (&QCmargin);
- QCrelief = intern_c_string (":relief");
- staticpro (&QCrelief);
- QCconversion = intern_c_string (":conversion");
- staticpro (&QCconversion);
- QCcolor_symbols = intern_c_string (":color-symbols");
- staticpro (&QCcolor_symbols);
- QCheuristic_mask = intern_c_string (":heuristic-mask");
- staticpro (&QCheuristic_mask);
- QCindex = intern_c_string (":index");
- staticpro (&QCindex);
- QCgeometry = intern_c_string (":geometry");
- staticpro (&QCgeometry);
- QCcrop = intern_c_string (":crop");
- staticpro (&QCcrop);
- QCrotation = intern_c_string (":rotation");
- staticpro (&QCrotation);
- QCmatrix = intern_c_string (":matrix");
- staticpro (&QCmatrix);
- QCcolor_adjustment = intern_c_string (":color-adjustment");
- staticpro (&QCcolor_adjustment);
- QCmask = intern_c_string (":mask");
- staticpro (&QCmask);
-
- Qlaplace = intern_c_string ("laplace");
- staticpro (&Qlaplace);
- Qemboss = intern_c_string ("emboss");
- staticpro (&Qemboss);
- Qedge_detection = intern_c_string ("edge-detection");
- staticpro (&Qedge_detection);
- Qheuristic = intern_c_string ("heuristic");
- staticpro (&Qheuristic);
-
- Qpostscript = intern_c_string ("postscript");
- staticpro (&Qpostscript);
+ DEFSYM (Qcount, "count");
+ DEFSYM (Qextension_data, "extension-data");
+ DEFSYM (Qdelay, "delay");
+
+ DEFSYM (QCascent, ":ascent");
+ DEFSYM (QCmargin, ":margin");
+ DEFSYM (QCrelief, ":relief");
+ DEFSYM (QCconversion, ":conversion");
+ DEFSYM (QCcolor_symbols, ":color-symbols");
+ DEFSYM (QCheuristic_mask, ":heuristic-mask");
+ DEFSYM (QCindex, ":index");
+ DEFSYM (QCgeometry, ":geometry");
+ DEFSYM (QCcrop, ":crop");
+ DEFSYM (QCrotation, ":rotation");
+ DEFSYM (QCmatrix, ":matrix");
+ DEFSYM (QCcolor_adjustment, ":color-adjustment");
+ DEFSYM (QCmask, ":mask");
+
+ DEFSYM (Qlaplace, "laplace");
+ DEFSYM (Qemboss, "emboss");
+ DEFSYM (Qedge_detection, "edge-detection");
+ DEFSYM (Qheuristic, "heuristic");
+
+ DEFSYM (Qpostscript, "postscript");
#ifdef HAVE_GHOSTSCRIPT
ADD_IMAGE_TYPE (Qpostscript);
- QCloader = intern_c_string (":loader");
- staticpro (&QCloader);
- QCbounding_box = intern_c_string (":bounding-box");
- staticpro (&QCbounding_box);
- QCpt_width = intern_c_string (":pt-width");
- staticpro (&QCpt_width);
- QCpt_height = intern_c_string (":pt-height");
- staticpro (&QCpt_height);
+ DEFSYM (QCloader, ":loader");
+ DEFSYM (QCbounding_box, ":bounding-box");
+ DEFSYM (QCpt_width, ":pt-width");
+ DEFSYM (QCpt_height, ":pt-height");
#endif /* HAVE_GHOSTSCRIPT */
#ifdef HAVE_NTGUI
- Qlibpng_version = intern_c_string ("libpng-version");
- staticpro (&Qlibpng_version);
+ DEFSYM (Qlibpng_version, "libpng-version");
Fset (Qlibpng_version,
#if HAVE_PNG
make_number (PNG_LIBPNG_VER)
#endif
#if defined (HAVE_XPM) || defined (HAVE_NS)
- Qxpm = intern_c_string ("xpm");
- staticpro (&Qxpm);
+ DEFSYM (Qxpm, "xpm");
ADD_IMAGE_TYPE (Qxpm);
#endif
#if defined (HAVE_JPEG) || defined (HAVE_NS)
- Qjpeg = intern_c_string ("jpeg");
- staticpro (&Qjpeg);
+ DEFSYM (Qjpeg, "jpeg");
ADD_IMAGE_TYPE (Qjpeg);
#endif
#if defined (HAVE_TIFF) || defined (HAVE_NS)
- Qtiff = intern_c_string ("tiff");
- staticpro (&Qtiff);
+ DEFSYM (Qtiff, "tiff");
ADD_IMAGE_TYPE (Qtiff);
#endif
#if defined (HAVE_GIF) || defined (HAVE_NS)
- Qgif = intern_c_string ("gif");
- staticpro (&Qgif);
+ DEFSYM (Qgif, "gif");
ADD_IMAGE_TYPE (Qgif);
#endif
#if defined (HAVE_PNG) || defined (HAVE_NS)
- Qpng = intern_c_string ("png");
- staticpro (&Qpng);
+ DEFSYM (Qpng, "png");
ADD_IMAGE_TYPE (Qpng);
#endif
#if defined (HAVE_IMAGEMAGICK)
- Qimagemagick = intern_c_string ("imagemagick");
- staticpro (&Qimagemagick);
+ DEFSYM (Qimagemagick, "imagemagick");
ADD_IMAGE_TYPE (Qimagemagick);
#endif
#if defined (HAVE_RSVG)
- Qsvg = intern_c_string ("svg");
- staticpro (&Qsvg);
+ DEFSYM (Qsvg, "svg");
ADD_IMAGE_TYPE (Qsvg);
#ifdef HAVE_NTGUI
/* Other libraries used directly by svg code. */
- Qgdk_pixbuf = intern_c_string ("gdk-pixbuf");
- staticpro (&Qgdk_pixbuf);
- Qglib = intern_c_string ("glib");
- staticpro (&Qglib);
- Qgobject = intern_c_string ("gobject");
- staticpro (&Qgobject);
+ DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
+ DEFSYM (Qglib, "glib");
+ DEFSYM (Qgobject, "gobject");
#endif /* HAVE_NTGUI */
#endif /* HAVE_RSVG */