diff options
| -rw-r--r-- | lisp/image.el | 117 |
1 files changed, 91 insertions, 26 deletions
diff --git a/lisp/image.el b/lisp/image.el index f833cc7e18f..72e6ee8e633 100644 --- a/lisp/image.el +++ b/lisp/image.el | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | :group 'multimedia) | 33 | :group 'multimedia) |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | (defconst image-type-regexps | 36 | (defconst image-type-header-regexps |
| 37 | '(("\\`/[\t\n\r ]*\\*.*XPM.\\*/" . xpm) | 37 | '(("\\`/[\t\n\r ]*\\*.*XPM.\\*/" . xpm) |
| 38 | ("\\`P[1-6]" . pbm) | 38 | ("\\`P[1-6]" . pbm) |
| 39 | ("\\`GIF8" . gif) | 39 | ("\\`GIF8" . gif) |
| @@ -49,6 +49,21 @@ IMAGE-TYPE must be a pair (PREDICATE . TYPE). PREDICATE is called | |||
| 49 | with one argument, a string containing the image data. If PREDICATE returns | 49 | with one argument, a string containing the image data. If PREDICATE returns |
| 50 | a non-nil value, TYPE is the image's type.") | 50 | a non-nil value, TYPE is the image's type.") |
| 51 | 51 | ||
| 52 | (defconst image-type-file-name-regexps | ||
| 53 | '(("\\.png\\'" . png) | ||
| 54 | ("\\.gif\\'" . gif) | ||
| 55 | ("\\.jpe?g\\'" . jpeg) | ||
| 56 | ("\\.bmp\\'" . bmp) | ||
| 57 | ("\\.xpm\\'" . xpm) | ||
| 58 | ("\\.pbm\\'" . pbm) | ||
| 59 | ("\\.xbm\\'" . xbm) | ||
| 60 | ("\\.ps\\'" . postscript) | ||
| 61 | ("\\.tiff?\\'" . tiff)) | ||
| 62 | "Alist of (REGEXP . IMAGE-TYPE) pairs used to identify image files. | ||
| 63 | When the name of an image file match REGEXP, it is assumed to | ||
| 64 | be of image type IMAGE-TYPE.") | ||
| 65 | |||
| 66 | |||
| 52 | (defvar image-load-path | 67 | (defvar image-load-path |
| 53 | (list (file-name-as-directory (expand-file-name "images" data-directory)) | 68 | (list (file-name-as-directory (expand-file-name "images" data-directory)) |
| 54 | 'data-directory 'load-path) | 69 | 'data-directory 'load-path) |
| @@ -87,18 +102,50 @@ We accept the tag Exif because that is the same format." | |||
| 87 | "Determine the image type from image data DATA. | 102 | "Determine the image type from image data DATA. |
| 88 | Value is a symbol specifying the image type or nil if type cannot | 103 | Value is a symbol specifying the image type or nil if type cannot |
| 89 | be determined." | 104 | be determined." |
| 90 | (let ((types image-type-regexps) | 105 | (let ((types image-type-header-regexps) |
| 91 | type) | 106 | type) |
| 92 | (while (and types (null type)) | 107 | (while types |
| 93 | (let ((regexp (car (car types))) | 108 | (let ((regexp (car (car types))) |
| 94 | (image-type (cdr (car types)))) | 109 | (image-type (cdr (car types)))) |
| 95 | (when (or (and (symbolp image-type) | 110 | (if (or (and (symbolp image-type) |
| 96 | (string-match regexp data)) | 111 | (string-match regexp data)) |
| 97 | (and (consp image-type) | 112 | (and (consp image-type) |
| 98 | (funcall (car image-type) data) | 113 | (funcall (car image-type) data) |
| 99 | (setq image-type (cdr image-type)))) | 114 | (setq image-type (cdr image-type)))) |
| 100 | (setq type image-type)) | 115 | (setq type image-type |
| 101 | (setq types (cdr types)))) | 116 | types nil) |
| 117 | (setq types (cdr types))))) | ||
| 118 | type)) | ||
| 119 | |||
| 120 | |||
| 121 | ;;;###autoload | ||
| 122 | (defun image-type-from-buffer () | ||
| 123 | "Determine the image type from data in the current buffer. | ||
| 124 | Value is a symbol specifying the image type or nil if type cannot | ||
| 125 | be determined." | ||
| 126 | (let ((types image-type-header-regexps) | ||
| 127 | type | ||
| 128 | (opoint (point))) | ||
| 129 | (goto-char (point-min)) | ||
| 130 | (while types | ||
| 131 | (let ((regexp (car (car types))) | ||
| 132 | (image-type (cdr (car types))) | ||
| 133 | data) | ||
| 134 | (if (or (and (symbolp image-type) | ||
| 135 | (looking-at regexp)) | ||
| 136 | (and (consp image-type) | ||
| 137 | (funcall (car image-type) | ||
| 138 | (or data | ||
| 139 | (setq data | ||
| 140 | (buffer-substring | ||
| 141 | (point-min) | ||
| 142 | (min (point-max) | ||
| 143 | (+ (point-min) 256)))))) | ||
| 144 | (setq image-type (cdr image-type)))) | ||
| 145 | (setq type image-type | ||
| 146 | types nil) | ||
| 147 | (setq types (cdr types))))) | ||
| 148 | (goto-char opoint) | ||
| 102 | type)) | 149 | type)) |
| 103 | 150 | ||
| 104 | 151 | ||
| @@ -107,14 +154,30 @@ be determined." | |||
| 107 | "Determine the type of image file FILE from its first few bytes. | 154 | "Determine the type of image file FILE from its first few bytes. |
| 108 | Value is a symbol specifying the image type, or nil if type cannot | 155 | Value is a symbol specifying the image type, or nil if type cannot |
| 109 | be determined." | 156 | be determined." |
| 110 | (unless (file-name-directory file) | 157 | (unless (or (file-readable-p file) |
| 111 | (setq file (expand-file-name file data-directory))) | 158 | (file-name-absolute-p file)) |
| 112 | (setq file (expand-file-name file)) | 159 | (setq file (image-search-load-path file))) |
| 113 | (let ((header (with-temp-buffer | 160 | (and file |
| 114 | (set-buffer-multibyte nil) | 161 | (file-readable-p file) |
| 115 | (insert-file-contents-literally file nil 0 256) | 162 | (with-temp-buffer |
| 116 | (buffer-string)))) | 163 | (set-buffer-multibyte nil) |
| 117 | (image-type-from-data header))) | 164 | (insert-file-contents-literally file nil 0 256) |
| 165 | (image-type-from-buffer)))) | ||
| 166 | |||
| 167 | |||
| 168 | ;;;###autoload | ||
| 169 | (defun image-type-from-file-name (file) | ||
| 170 | "Determine the type of image file FILE from its name. | ||
| 171 | Value is a symbol specifying the image type, or nil if type cannot | ||
| 172 | be determined." | ||
| 173 | (let ((types image-type-file-name-regexps) | ||
| 174 | type) | ||
| 175 | (while types | ||
| 176 | (if (string-match (car (car types)) file) | ||
| 177 | (setq type (cdr (car types)) | ||
| 178 | types nil) | ||
| 179 | (setq types (cdr types)))) | ||
| 180 | type)) | ||
| 118 | 181 | ||
| 119 | 182 | ||
| 120 | ;;;###autoload | 183 | ;;;###autoload |
| @@ -124,6 +187,7 @@ Image types are symbols like `xbm' or `jpeg'." | |||
| 124 | (and (fboundp 'init-image-library) | 187 | (and (fboundp 'init-image-library) |
| 125 | (init-image-library type image-library-alist))) | 188 | (init-image-library type image-library-alist))) |
| 126 | 189 | ||
| 190 | |||
| 127 | ;;;###autoload | 191 | ;;;###autoload |
| 128 | (defun create-image (file-or-data &optional type data-p &rest props) | 192 | (defun create-image (file-or-data &optional type data-p &rest props) |
| 129 | "Create an image. | 193 | "Create an image. |
| @@ -281,27 +345,29 @@ BUFFER nil or omitted means use the current buffer." | |||
| 281 | (delete-overlay overlay))) | 345 | (delete-overlay overlay))) |
| 282 | (setq overlays (cdr overlays))))) | 346 | (setq overlays (cdr overlays))))) |
| 283 | 347 | ||
| 284 | (defun image-search-load-path (file path) | 348 | (defun image-search-load-path (file &optional path) |
| 285 | (let (element found pathname) | 349 | (unless path |
| 350 | (setq path image-load-path)) | ||
| 351 | (let (element found filename) | ||
| 286 | (while (and (not found) (consp path)) | 352 | (while (and (not found) (consp path)) |
| 287 | (setq element (car path)) | 353 | (setq element (car path)) |
| 288 | (cond | 354 | (cond |
| 289 | ((stringp element) | 355 | ((stringp element) |
| 290 | (setq found | 356 | (setq found |
| 291 | (file-readable-p | 357 | (file-readable-p |
| 292 | (setq pathname (expand-file-name file element))))) | 358 | (setq filename (expand-file-name file element))))) |
| 293 | ((and (symbolp element) (boundp element)) | 359 | ((and (symbolp element) (boundp element)) |
| 294 | (setq element (symbol-value element)) | 360 | (setq element (symbol-value element)) |
| 295 | (cond | 361 | (cond |
| 296 | ((stringp element) | 362 | ((stringp element) |
| 297 | (setq found | 363 | (setq found |
| 298 | (file-readable-p | 364 | (file-readable-p |
| 299 | (setq pathname (expand-file-name file element))))) | 365 | (setq filename (expand-file-name file element))))) |
| 300 | ((consp element) | 366 | ((consp element) |
| 301 | (if (setq pathname (image-search-load-path file element)) | 367 | (if (setq filename (image-search-load-path file element)) |
| 302 | (setq found t)))))) | 368 | (setq found t)))))) |
| 303 | (setq path (cdr path))) | 369 | (setq path (cdr path))) |
| 304 | (if found pathname))) | 370 | (if found filename))) |
| 305 | 371 | ||
| 306 | ;;;###autoload | 372 | ;;;###autoload |
| 307 | (defun find-image (specs) | 373 | (defun find-image (specs) |
| @@ -331,8 +397,7 @@ Image files should not be larger than specified by `max-image-size'." | |||
| 331 | found) | 397 | found) |
| 332 | (when (image-type-available-p type) | 398 | (when (image-type-available-p type) |
| 333 | (cond ((stringp file) | 399 | (cond ((stringp file) |
| 334 | (if (setq found (image-search-load-path | 400 | (if (setq found (image-search-load-path file)) |
| 335 | file image-load-path)) | ||
| 336 | (setq image | 401 | (setq image |
| 337 | (cons 'image (plist-put (copy-sequence spec) | 402 | (cons 'image (plist-put (copy-sequence spec) |
| 338 | :file found))))) | 403 | :file found))))) |