;;; mime-image.el --- mime-view filter to display images ;; Copyright (C) 1995,1996,1997,1998 MORIOKA Tomohiko ;; Copyright (C) 1996 Dan Rich ;; Author: MORIOKA Tomohiko ;; Dan Rich ;; Daiki Ueno ;; Katsumi Yamaoka ;; Maintainer: MORIOKA Tomohiko ;; Created: 1995/12/15 ;; Renamed: 1997/2/21 from tm-image.el ;; Keywords: image, picture, X-Face, MIME, multimedia, mail, news ;; This file is part of SEMI (Showy Emacs MIME Interfaces). ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 2, or (at ;; your option) any later version. ;; This program is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU XEmacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; If you use this program with MULE, please install ;; etl8x16-bitmap.bdf font included in tl package. ;;; Code: (eval-when-compile (require 'cl)) (eval-when-compile (require 'static)) (require 'mime-view) (require 'alist) (require 'path-util) (static-if (featurep 'xemacs) (progn (defun mime-image-type-available-p (type) (memq type (image-instantiator-format-list))) (defun mime-image-create (file-or-data &optional type data-p &rest props) (let ((instance (make-image-instance (if (and type (mime-image-type-available-p type)) (vector type (if data-p :data :file) file-or-data) file-or-data) nil nil 'noerror))) (if (nothing-image-instance-p instance) nil (make-glyph instance)))) (defun mime-image-insert (image string &optional area) (let ((extent (make-extent (point) (progn (insert string)(point))))) (set-extent-property extent 'invisible t) (set-extent-end-glyph extent image)))) (condition-case nil (progn (require 'image) (defalias 'mime-image-type-available-p 'image-type-available-p) (defalias 'mime-image-create 'create-image) (defalias 'mime-image-insert 'insert-image)) (error (condition-case nil (progn (require (if (featurep 'mule) 'bitmap "")) (defun mime-image-read-xbm-buffer (buffer) (condition-case nil (mapconcat #'bitmap-compose (append (bitmap-decode-xbm (bitmap-read-xbm-buffer (current-buffer))) nil) "\n") (error nil))) (defun mime-image-insert (image string &optional area) (insert image))) (error (defun mime-image-read-xbm-buffer (buffer) (save-excursion (set-buffer buffer) (let ((case-fold-search t) width height xbytes right margin) (goto-char (point-min)) (or (re-search-forward "_width[\t ]+\\([0-9]+\\)" nil t) (error "!! Illegal xbm file format" (current-buffer))) (setq width (string-to-int (match-string 1)) xbytes (/ (+ width 7) 8)) (goto-char (point-min)) (or (re-search-forward "_height[\t ]+\\([0-9]+\\)" nil t) (error "!! Illegal xbm file format" (current-buffer))) (setq height (string-to-int (match-string 1))) (goto-char (point-min)) (re-search-forward "0x[0-9a-f][0-9a-f],") (delete-region (point-min) (match-beginning 0)) (goto-char (point-min)) (while (re-search-forward "[\n\r\t ,;}]" nil t) (replace-match "")) (goto-char (point-min)) (while (re-search-forward "0x" nil t) (replace-match "\\x" nil t)) (goto-char (point-min)) (insert "(" (number-to-string width) " " (number-to-string height) " \"") (goto-char (point-max)) (insert "\")") (goto-char (point-min)) (read (current-buffer))))) (defun mime-image-insert (image string &optional area) (save-restriction (narrow-to-region (point)(point)) (let ((face (gensym "mis"))) (or (facep face) (make-face face)) (set-face-stipple face image) (let ((row (make-string (/ (car image) (frame-char-width)) ? )) (height (/ (nth 1 image) (frame-char-height))) (i 0)) (while (< i height) (set-text-properties (point) (progn (insert row)(point)) (list 'face face)) (insert "\n") (setq i (1+ i))))))))) (defun mime-image-type-available-p (type) (eq type 'xbm)) (defun mime-image-create (file-or-data &optional type data-p &rest props) (when (or (null type) (eq type 'xbm)) (with-temp-buffer (if data-p (insert file-or-data) (insert-file-contents file-or-data)) (mime-image-read-xbm-buffer (current-buffer)))))))) (defvar mime-image-format-alist '((image jpeg jpeg) (image gif gif) (image tiff tiff) (image x-tiff tiff) (image xbm xbm) (image x-xbm xbm) (image x-xpixmap xpm) (image png png))) (dolist (rule mime-image-format-alist) (when (mime-image-type-available-p (nth 2 rule)) (ctree-set-calist-strictly 'mime-preview-condition (list (cons 'type (car rule))(cons 'subtype (nth 1 rule)) '(body . visible) (cons 'body-presentation-method #'mime-display-image) (cons 'image-format (nth 2 rule)))))) ;;; @ content filter for images ;;; ;; (for XEmacs 19.12 or later) (defun mime-display-image (entity situation) (message "Decoding image...") (let ((format (cdr (assq 'image-format situation))) (image-file (make-temp-name (expand-file-name "tm" temporary-file-directory))) (orig-mode (default-file-modes)) image) (unwind-protect (progn (set-default-file-modes 448) (mime-write-entity-content entity image-file) (if (null (setq image (mime-image-create image-file format))) (message "Invalid glyph!") (save-excursion (mime-image-insert image "x") (insert "\n") (save-window-excursion (set-window-buffer (selected-window)(current-buffer)) (sit-for 0)) (message "Decoding image... done")))) (set-default-file-modes orig-mode) (condition-case nil (delete-file image-file) (error nil))))) ;;; @ end ;;; (provide 'mime-image) ;;; mime-image.el ends here