emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r104565: Handle gif subimage animatio


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104565: Handle gif subimage animation delay correctly.
Date: Sat, 11 Jun 2011 19:03:16 -0400
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104565
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Sat 2011-06-11 19:03:16 -0400
message:
  Handle gif subimage animation delay correctly.
  
  * lisp/image.el (image-animated-p): Return animation delay in seconds.
  Avoid bit manipulation in Lisp; use `delay' entry in the metadata.
  (image-animate-timeout): Remove DELAY argument.  Use
  image-animated-p to get animation delay for each frame.
  (image-animate): Caller changed.
  
  * src/image.c (gif_load): Add animation frame delay to the metadata.
  (syms_of_image): Use DEFSYM.  New symbol `delay'.
modified:
  lisp/ChangeLog
  lisp/image.el
  src/ChangeLog
  src/image.c
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-06-11 18:30:43 +0000
+++ b/lisp/ChangeLog    2011-06-11 23:03:16 +0000
@@ -1,3 +1,11 @@
+2011-06-11  Chong Yidong  <address@hidden>
+
+       * image.el (image-animated-p): Return animation delay in seconds.
+       Avoid bit manipulation in Lisp; use `delay' entry in the metadata.
+       (image-animate-timeout): Remove DELAY argument.  Don't assume
+       every subimage has the same delay; get it from image-animated-p.
+       (image-animate): Caller changed.
+
 2011-06-11  Michael Albinus  <address@hidden>
 
        * net/tramp.el (tramp-debug-message): Add `tramp-with-progress-reporter'

=== modified file 'lisp/image.el'
--- a/lisp/image.el     2011-06-07 18:32:12 +0000
+++ b/lisp/image.el     2011-06-11 23:03:16 +0000
@@ -597,20 +597,16 @@
   "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.
@@ -620,15 +616,14 @@
 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."
@@ -643,7 +638,7 @@
        (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.
@@ -653,10 +648,16 @@
 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)
@@ -666,8 +667,7 @@
        (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))))
 
 
 (defcustom imagemagick-types-inhibit

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-06-11 14:06:16 +0000
+++ b/src/ChangeLog     2011-06-11 23:03:16 +0000
@@ -1,3 +1,8 @@
+2011-06-11  Chong Yidong  <address@hidden>
+
+       * image.c (gif_load): Add animation frame delay to the metadata.
+       (syms_of_image): Use DEFSYM.  New symbol `delay'.
+
 2011-06-11  Martin Rudalics  <address@hidden>
 
        * window.c (delete_deletable_window): Re-add.

=== modified file 'src/image.c'
--- a/src/image.c       2011-06-11 10:11:07 +0000
+++ b/src/image.c       2011-06-11 23:03:16 +0000
@@ -564,7 +564,6 @@
 /* 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;
@@ -573,6 +572,7 @@
 
 /* Other symbols.  */
 
+static Lisp_Object Qcount, Qextension_data, Qdelay;
 static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
 
 /* Function prototypes.  */
@@ -7315,16 +7315,31 @@
   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),
@@ -8688,75 +8703,49 @@
 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)
@@ -8767,53 +8756,43 @@
 #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  */
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]