]> code.delx.au - gnu-emacs/blobdiff - lisp/image.el
Add a provide statement.
[gnu-emacs] / lisp / image.el
index 3e61b100cee21db840379b4917ad61b6158243e4..13fdf2f6e4cf2d57228d3c290fc02a0677f33ba1 100644 (file)
@@ -1,6 +1,8 @@
 ;;; 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.
@@ -36,7 +38,7 @@
     ("\\`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.
@@ -44,11 +46,25 @@ When the first bytes of an image file match REGEXP, it is assumed to
 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))
@@ -59,11 +75,13 @@ a non-nil value, TYPE is the image's type ")
          (when (>= (+ i 2) len)
            (throw 'jfif nil))
          (let ((nbytes (+ (lsh (aref data (+ i 1)) 8)
-                          (aref data (+ i 2)))))
-           (when (= (aref data i) #xe0)
+                          (aref data (+ i 2))))
+               (code (aref data i)))
+           (when (and (>= code #xe0) (<= code #xef))
              ;; APP0 LEN1 LEN2 "JFIF\0"
-             (throw 'jfif (string-match "\\`\xe0..JFIF\0" 
-                                        (substring data i (+ i 10)))))
+             (throw 'jfif
+                    (string-match "JFIF\\|Exif"
+                                  (substring data i (min (+ i nbytes) len)))))
            (setq i (+ i 1 nbytes))))))))
 
 
@@ -96,6 +114,7 @@ be determined."
     (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)))
@@ -105,8 +124,8 @@ be determined."
 (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)
@@ -170,7 +189,7 @@ means display it in the right marginal area."
 
 
 ;;;###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
@@ -178,7 +197,12 @@ 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."
+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 " "))
@@ -198,11 +222,49 @@ means display it in the right marginal area."
   (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
@@ -291,4 +353,5 @@ Example:
 
 (provide 'image)
 
+;;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3
 ;;; image.el ends here