aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim F. Storm2010-03-07 21:02:20 +0200
committerJuri Linkov2010-03-07 21:02:20 +0200
commit0608aa457fd97d1c9a116152a77544b07f7fd55a (patch)
tree40aaded8d817bc2a78a28cbfa6089c0f175db429
parentdd5de7c6e4efc3c49e01ce75313303ba78e31b94 (diff)
downloademacs-0608aa457fd97d1c9a116152a77544b07f7fd55a.tar.gz
emacs-0608aa457fd97d1c9a116152a77544b07f7fd55a.zip
Animated image API.
http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg00211.html * image.el (image-animate-max-time): New defcustom. (image-animated-types): New defconst. (create-animated-image, image-animate-timer) (image-animate-start, image-animate-stop, image-animate-timeout) (image-animated-p): New functions. * image-mode.el (image-toggle-display-image): Replace `create-image' with `create-animated-image'.
-rw-r--r--lisp/ChangeLog14
-rw-r--r--lisp/image-mode.el2
-rw-r--r--lisp/image.el104
3 files changed, 119 insertions, 1 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8ac8d5ed450..cf3be1586e5 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,17 @@
12010-03-07 Kim F. Storm <storm@cua.dk>
2
3 Animated image API.
4 http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg00211.html
5
6 * image.el (image-animate-max-time): New defcustom.
7 (image-animated-types): New defconst.
8 (create-animated-image, image-animate-timer)
9 (image-animate-start, image-animate-stop, image-animate-timeout)
10 (image-animated-p): New functions.
11
12 * image-mode.el (image-toggle-display-image):
13 Replace `create-image' with `create-animated-image'.
14
12010-01-27 Stephen Berman <stephen.berman@gmx.net> 152010-01-27 Stephen Berman <stephen.berman@gmx.net>
2 16
3 * calendar/diary-lib.el (diary-unhide-everything): Handle narrowed 17 * calendar/diary-lib.el (diary-unhide-everything): Handle narrowed
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index f3cdc05da16..1d999b50007 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -464,7 +464,7 @@ was inserted."
464 (buffer-substring-no-properties (point-min) (point-max))) 464 (buffer-substring-no-properties (point-min) (point-max)))
465 filename)) 465 filename))
466 (type (image-type file-or-data nil data-p)) 466 (type (image-type file-or-data nil data-p))
467 (image (create-image file-or-data type data-p)) 467 (image (create-animated-image file-or-data type data-p))
468 (props 468 (props
469 `(display ,image 469 `(display ,image
470 intangible ,image 470 intangible ,image
diff --git a/lisp/image.el b/lisp/image.el
index 944c6135e23..e5dfe1a3996 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -584,7 +584,111 @@ Example:
584 (declare (doc-string 3)) 584 (declare (doc-string 3))
585 `(defvar ,symbol (find-image ',specs) ,doc)) 585 `(defvar ,symbol (find-image ',specs) ,doc))
586 586
587
588;;; Animated image API
587 589
590(defcustom image-animate-max-time 30
591 "Time in seconds to animate images."
592 :type 'integer
593 :version "22.1"
594 :group 'image)
595
596(defconst image-animated-types '(gif)
597 "List of supported animated image types.")
598
599;;;###autoload
600(defun create-animated-image (file-or-data &optional type data-p &rest props)
601 "Create an animated image.
602FILE-OR-DATA is an image file name or image data.
603Optional TYPE is a symbol describing the image type. If TYPE is omitted
604or nil, try to determine the image type from its first few bytes
605of image data. If that doesn't work, and FILE-OR-DATA is a file name,
606use its file extension as image type.
607Optional DATA-P non-nil means FILE-OR-DATA is a string containing image data.
608Optional PROPS are additional image attributes to assign to the image,
609like, e.g. `:mask MASK'.
610Value is the image created, or nil if images of type TYPE are not supported.
611
612Images should not be larger than specified by `max-image-size'."
613 (setq type (image-type file-or-data type data-p))
614 (when (image-type-available-p type)
615 (let* ((animate (memq type image-animated-types))
616 (image
617 (append (list 'image :type type (if data-p :data :file) file-or-data)
618 (if animate '(:index 0 :mask heuristic))
619 props)))
620 (if animate
621 (image-animate-start image))
622 image)))
623
624(defun image-animate-timer (image)
625 "Return the animation timer for image IMAGE."
626 ;; See cancel-function-timers
627 (let ((tail timer-list) timer)
628 (while tail
629 (setq timer (car tail)
630 tail (cdr tail))
631 (if (and (eq (aref timer 5) #'image-animate-timeout)
632 (consp (aref timer 6))
633 (eq (car (aref timer 6)) image))
634 (setq tail nil)
635 (setq timer nil)))
636 timer))
637
638(defun image-animate-start (image &optional max-time)
639 "Start animation of image IMAGE.
640Optional second arg MAX-TIME is number of seconds to animate image,
641or t to animate infinitely."
642 (let ((anim (image-animated-p image))
643 timer tmo)
644 (when anim
645 (if (setq timer (image-animate-timer image))
646 (setcar (nthcdr 3 (aref timer 6)) max-time)
647 (setq tmo (* (cdr anim) 0.01))
648 (setq max-time (or max-time image-animate-max-time))
649 (run-with-timer tmo nil #'image-animate-timeout
650 image 1 (car anim)
651 (if (numberp max-time)
652 (- max-time tmo)
653 max-time))))))
654
655(defun image-animate-stop (image)
656 "Stop animation of image."
657 (let ((timer (image-animate-timer image)))
658 (when timer
659 (cancel-timer timer))))
660
661(defun image-animate-timeout (image ino count time-left)
662 (if (>= ino count)
663 (setq ino 0))
664 (plist-put (cdr image) :index ino)
665 (force-window-update)
666 (let ((anim (image-animated-p image)) tmo)
667 (when anim
668 (setq tmo (* (cdr anim) 0.01))
669 (unless (and (= ino 0) (numberp time-left) (< time-left tmo))
670 (run-with-timer tmo nil #'image-animate-timeout
671 image (1+ ino) count
672 (if (numberp time-left)
673 (- time-left tmo)
674 time-left))))))
675
676(defun image-animated-p (image)
677 "Return non-nil if image is animated.
678Actually, return value is a cons (IMAGES . DELAY) where IMAGES
679is the number of sub-images in the animated image, and DELAY
680is the delay in 100ths of a second until the next sub-image
681shall be displayed."
682 (cond
683 ((eq (plist-get (cdr image) :type) 'gif)
684 (let* ((extdata (image-extension-data image))
685 (images (plist-get extdata 'count))
686 (anim (plist-get extdata #xF9)))
687 (and (integerp images) (> images 1)
688 (stringp anim) (>= (length anim) 4)
689 (cons images (+ (aref anim 1) (* (aref anim 2) 256))))))))
690
691
588(provide 'image) 692(provide 'image)
589 693
590;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3 694;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3