+(defun image-goto-frame (n &optional relative)
+ "Show frame N of a multi-frame image.
+Optional argument OFFSET non-nil means interpret N as relative to the
+current frame. Frames are indexed from 1."
+ (interactive
+ (list (or current-prefix-arg
+ (read-number "Show frame number: "))))
+ (let ((image (image-get-display-property))
+ animation)
+ (cond
+ ((null image)
+ (error "No image is present"))
+ ((null image-current-frame)
+ (message "No image animation."))
+ (t
+ (image-nth-frame image (if relative (+ n image-current-frame) (1- n)))))))
+
+(defun image-next-frame (&optional n)
+ "Switch to the next frame of a multi-frame image.
+With optional argument N, switch to the Nth frame after the current one.
+If N is negative, switch to the Nth frame before the current one."
+ (interactive "p")
+ (image-goto-frame n t))
+
+(defun image-previous-frame (&optional n)
+ "Switch to the previous frame of a multi-frame image.
+With optional argument N, switch to the Nth frame before the current one.
+If N is negative, switch to the Nth frame after the current one."
+ (interactive "p")
+ (image-next-frame (- n)))
+
+\f
+;;; Switching to the next/previous image
+
+(defun image-next-file (&optional n)
+ "Visit the next image in the same directory as the current image file.
+With optional argument N, visit the Nth image file after the
+current one, in cyclic alphabetical order.
+
+This command visits the specified file via `find-alternate-file',
+replacing the current Image mode buffer."
+ (interactive "p")
+ (unless (derived-mode-p 'image-mode)
+ (error "The buffer is not in Image mode"))
+ (unless buffer-file-name
+ (error "The current image is not associated with a file"))
+ (let* ((file (file-name-nondirectory buffer-file-name))
+ (images (image-mode--images-in-directory file))
+ (idx 0))
+ (catch 'image-visit-next-file
+ (dolist (f images)
+ (if (string= f file)
+ (throw 'image-visit-next-file (1+ idx)))
+ (setq idx (1+ idx))))
+ (setq idx (mod (+ idx (or n 1)) (length images)))
+ (find-alternate-file (nth idx images))))
+
+(defun image-previous-file (&optional n)
+ "Visit the preceding image in the same directory as the current file.
+With optional argument N, visit the Nth image file preceding the
+current one, in cyclic alphabetical order.
+
+This command visits the specified file via `find-alternate-file',
+replacing the current Image mode buffer."
+ (interactive "p")
+ (image-next-file (- n)))
+
+(defun image-mode--images-in-directory (file)
+ (let* ((dir (file-name-directory buffer-file-name))
+ (files (directory-files dir nil
+ (image-file-name-regexp) t)))
+ ;; Add the current file to the list of images if necessary, in
+ ;; case it does not match `image-file-name-regexp'.
+ (unless (member file files)
+ (push file files))
+ (sort files 'string-lessp)))
+