1 ;;; image-mode.el --- Major mode for navigating images
3 ;; Copyright (C) 1997 MORIOKA Tomohiko
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
7 ;; Version: image-mode.el,v 20.3.1.2 1997/07/01 17:29:44 morioka Exp
8 ;; Keywords: image, graphics
10 ;; This file is part of XEmacs.
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 ;; Modified: 2001-07-10, Glynn Clements <glynn.clements@virgin.net>
30 ;; Substantially re-written to avoid use of format-alist
31 ;; Modified: 2002-10-18, Glynn Clements <glynn.clements@virgin.net>
32 ;; Autoload image-mode-install
33 ;; Modified: 2002-10-22, Glynn Clements <glynn.clements@virgin.net>
34 ;; Remove format-alist entries
40 (defvar image-format nil)
41 (make-variable-buffer-local 'image-format)
43 (defvar image-decoded nil)
44 (make-variable-buffer-local 'image-decoded)
47 (defvar image-formats-alist
56 (defun image-guess-type ()
59 (setq ext (downcase (file-name-extension buffer-file-name)))
60 (setq item (assoc* ext image-formats-alist
61 :test (lambda (str re)
62 (string-match (concat "^" re "\\'")
64 (setq image-format (cdr item)))))
66 (defun image-decode-buffer ()
67 (image-decode (point-min) (point-max) image-format)
68 (setq image-decoded t)
69 (set-buffer-modified-p nil))
71 (defun image-undecode-buffer ()
72 (setq buffer-read-only nil)
73 (map-extents (function
74 (lambda (extent maparg)
75 (delete-extent extent)))
76 nil (point-min) (point-max) nil 'end-closed)
77 (setq image-decoded nil))
79 (defun image-decode (start end type)
80 "Decode the image between START and END which is encoded in TYPE."
82 (let ((image (and type
84 (vector type :data (buffer-string start end))
87 (setq image (make-image-instance
88 (vector 'string :data "format is not supported!\n")
90 (set-extent-property (make-extent start end) 'invisible t)
91 (let ((glyph (make-glyph image)))
92 (set-extent-end-glyph (make-extent end end) glyph))
93 (setq buffer-read-only t))))
95 (defvar image-mode-map (make-keymap))
96 (suppress-keymap image-mode-map)
97 (define-key image-mode-map "v" 'image-start-external-viewer)
98 (define-key image-mode-map "t" 'image-toggle-decoding)
99 (define-key image-mode-map "h" 'image-enter-hexl-mode)
100 (define-key image-mode-map "e" 'image-enter-xpm-mode)
101 (define-key image-mode-map "q" 'image-mode-quit)
103 ;; ### There must be a general way of doing this, using mimecap....
104 (defvar image-external-viewer-list
107 "display" ; ImageMagic
109 "*List of external viewers for image-mode.
111 Each viewer is a string, to be called via `start-process'. If null,
112 no external viewer will be used.")
114 (defun image-start-external-viewer ()
115 "Start external image viewer for current-buffer.
117 It tries each program name in `image-external-viewer-list' in order.
118 If `image-external-viewer-list' is empty, or none of the viewers can
119 be found, signals an error."
122 (let ((vl image-external-viewer-list))
128 (start-process "external image viewer" nil
129 (car vl) buffer-file-name)
130 (throw 'done nil)) ; exit loop
131 (file-error (setq vl (cdr vl)))))
132 (error "image-start-external-viewer: couldn't start any viewer in `image-external-viewer-list'"))
133 (error "image-start-external-viewer: `image-external-viewer-list' is empty."))))
135 (defun image-toggle-decoding ()
136 "Toggle image display mode in current buffer."
139 (image-undecode-buffer)
140 (image-decode-buffer)))
142 (defun image-exit-hexl-mode-function ()
143 (image-decode-buffer)
144 (remove-hook 'hexl-mode-exit-hook 'image-exit-hexl-mode-function))
146 (defun image-enter-hexl-mode ()
150 (image-undecode-buffer)
151 (add-hook 'hexl-mode-exit-hook 'image-exit-hexl-mode-function))
154 (defun image-enter-xpm-mode ()
157 (if (not (eq image-format 'xpm))
158 (error "Not an XPM image."))
160 (image-undecode-buffer))
163 (defun image-mode-quit ()
166 (kill-buffer (current-buffer)))
168 (defun image-maybe-restore ()
169 "Restore buffer if it is decoded."
171 (image-undecode-buffer)))
173 (add-hook 'change-major-mode-hook 'image-maybe-restore)
176 (defun image-mode (&optional arg)
179 (setq major-mode 'image-mode)
180 (setq mode-name "Image")
181 (use-local-map image-mode-map)
183 (image-decode-buffer))
188 (remove-if (lambda (x)
189 (eq (nth 6 x) 'image-mode))
191 (dolist (format image-formats-alist)
192 (let* ((re (car format))
194 (regexp (concat "\\.\\(" re "\\|" (upcase re) "\\)\\'"))
195 (item (cons regexp 'image-mode)))
197 (add-to-list 'auto-mode-alist item)))))
199 (provide 'image-mode)
201 ;;; image-mode.el ends here