;;; image.el --- image API
-;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 99, 2000, 01, 04 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
;; Keywords: multimedia
;; This file is part of GNU Emacs.
("\\`GIF8" . gif)
("\\`\211PNG\r\n" . png)
("\\`[\t\n\r ]*#define" . xbm)
- ("\\`\\(MM\0\\*\\)\\|\\(II\\*\0\\)" . tiff)
+ ("\\`\\(MM\0\\*\\|II\\*\0\\)" . tiff)
("\\`[\t\n\r ]*%!PS" . postscript)
("\\`\xff\xd8" . (image-jpeg-p . jpeg)))
"Alist of (REGEXP . IMAGE-TYPE) pairs used to auto-detect image types.
be of image type IMAGE-TYPE if IMAGE-TYPE is a symbol. If not a symbol,
IMAGE-TYPE must be a pair (PREDICATE . TYPE). PREDICATE is called
with one argument, a string containing the image data. If PREDICATE returns
-a non-nil value, TYPE is the image's type ")
+a non-nil value, TYPE is the image's type.")
+
+;;;###autoload
+(defvar image-library-alist nil
+ "Alist of image types vs external libraries needed to display them.
+
+Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
+representing a supported image type, and the rest are strings giving
+alternate filenames for the corresponding external libraries.
+Emacs tries to load the libraries in the order they appear on the
+list; if none is loaded, the running session of Emacs won't
+support the image type. Types 'pbm and 'xbm don't need to be
+listed; they're always supported.")
+;;;###autoload (put 'image-library-alist 'risky-local-variable t)
(defun image-jpeg-p (data)
- "Value is non-nil if DATA, a string, consists of JFIF image data."
+ "Value is non-nil if DATA, a string, consists of JFIF image data.
+We accept the tag Exif because that is the same format."
(when (string-match "\\`\xff\xd8" data)
(catch 'jfif
(let ((len (length data)) (i 2))
(code (aref data i)))
(when (and (>= code #xe0) (<= code #xef))
;; APP0 LEN1 LEN2 "JFIF\0"
- (throw 'jfif
- (string-match "JFIF" (substring data i (+ i nbytes)))))
+ (throw 'jfif
+ (string-match "JFIF\\|Exif"
+ (substring data i (min (+ i nbytes) len)))))
(setq i (+ i 1 nbytes))))))))
(setq file (expand-file-name file data-directory)))
(setq file (expand-file-name file))
(let ((header (with-temp-buffer
+ (set-buffer-multibyte nil)
(insert-file-contents-literally file nil 0 256)
(buffer-string))))
(image-type-from-data header)))
(defun image-type-available-p (type)
"Value is non-nil if image type TYPE is available.
Image types are symbols like `xbm' or `jpeg'."
- (and (boundp 'image-types) (not (null (memq type image-types)))))
-
+ (and (fboundp 'init-image-library)
+ (init-image-library type image-library-alist)))
;;;###autoload
(defun create-image (file-or-data &optional type data-p &rest props)
;;;###autoload
-(defun insert-image (image &optional string area)
+(defun insert-image (image &optional string area slice)
"Insert IMAGE into current buffer at point.
IMAGE is displayed by inserting STRING into the current buffer
with a `display' property whose value is the image. STRING is
AREA is where to display the image. AREA nil or omitted means
display it in the text area, a value of `left-margin' means
display it in the left marginal area, a value of `right-margin'
-means display it in the right marginal area."
+means display it in the right marginal area.
+SLICE specifies slice of IMAGE to insert. SLICE nil or omitted
+means insert whole image. SLICE is a list (X Y WIDTH HEIGHT)
+specifying the X and Y positions and WIDTH and HEIGHT of image area
+to insert. A float value 0.0 - 1.0 means relative to the width or
+height of the image; integer values are taken as pixel values."
;; Use a space as least likely to cause trouble when it's a hidden
;; character in the buffer.
(unless string (setq string " "))
(let ((start (point)))
(insert string)
(add-text-properties start (point)
- (list 'display image
- ;; `image' has the right properties to
- ;; mark an intangible field.
- 'intangible image
- 'rear-nonsticky (list 'display)))))
+ `(display ,(if slice
+ (list (cons 'slice slice) image)
+ image) rear-nonsticky (display)))))
+
+
+(defun insert-sliced-image (image &optional string area rows cols)
+ "Insert IMAGE into current buffer at point.
+IMAGE is displayed by inserting STRING into the current buffer
+with a `display' property whose value is the image. STRING is
+defaulted if you omit it.
+AREA is where to display the image. AREA nil or omitted means
+display it in the text area, a value of `left-margin' means
+display it in the left marginal area, a value of `right-margin'
+means display it in the right marginal area.
+The image is automatically split into ROW x COLS slices."
+ (unless string (setq string " "))
+ (unless (eq (car-safe image) 'image)
+ (error "Not an image: %s" image))
+ (unless (or (null area) (memq area '(left-margin right-margin)))
+ (error "Invalid area %s" area))
+ (if area
+ (setq image (list (list 'margin area) image))
+ ;; Cons up a new spec equal but not eq to `image' so that
+ ;; inserting it twice in a row (adjacently) displays two copies of
+ ;; the image. Don't try to avoid this by looking at the display
+ ;; properties on either side so that we DTRT more often with
+ ;; cut-and-paste. (Yanking killed image text next to another copy
+ ;; of it loses anyway.)
+ (setq image (cons 'image (cdr image))))
+ (let ((x 0.0) (dx (/ 1.0001 (or cols 1)))
+ (y 0.0) (dy (/ 1.0001 (or rows 1))))
+ (while (< y 1.0)
+ (while (< x 1.0)
+ (let ((start (point)))
+ (insert string)
+ (add-text-properties start (point)
+ `(display ,(list (list 'slice x y dx dy) image)
+ rear-nonsticky (display)))
+ (setq x (+ x dx))))
+ (setq x 0.0
+ y (+ y dy))
+ (insert (propertize "\n" 'line-height 0)))))
+
;;;###autoload
(provide 'image)
+;;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3
;;; image.el ends here