1 ;;; images.el --- Automatic image converters
2 ;; Author: $Author: legoscia $
3 ;; Created: $Date: 2007/11/15 12:22:34 $
4 ;; Version: $Revision: 1.6 $
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; Copyright (c) 1996 - 1999, 2007 Free Software Foundation Inc.
9 ;;; Copyright (c) 1995 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
11 ;;; This file is part of GNU Emacs.
13 ;;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;;; it under the terms of the GNU General Public License as published by
15 ;;; the Free Software Foundation; either version 2, or (at your option)
16 ;;; any later version.
18 ;;; GNU Emacs is distributed in the hope that it will be useful,
19 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;;; GNU General Public License for more details.
23 ;;; You should have received a copy of the GNU General Public License
24 ;;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;;; Boston, MA 02111-1307, USA.
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29 (defvar image-temp-stack nil "Do no touch - internal storage.")
30 (defvar image-converters nil "Storage for the image converters.")
31 (defvar image-native-formats
34 (delq nil (cons (if (featurep 'x) 'xbm)
35 (mapcar (function (lambda (x) (if (featurep x) x)))
36 '(xpm gif jpeg tiff png imagick)))))
37 ((boundp 'image-types)
40 "A list of image formats that this version of emacs supports natively.")
42 (defun image-register-converter (from to converter)
43 "Register the image converter for FROM to TO. CONVERTER is the actual
44 command used to convert the image. If this is a string, it will be executed
45 in a subprocess. If a symbol, it is assumed to be a function. It will be
46 called with two arguments, the start and end of the data to be converted.
47 The function should replace that data with the new image data. The return
48 value is not significant."
49 (let* ((node (assq from image-converters))
50 (replace (assq to (cdr-safe node))))
52 (replace ; Replace existing converter
53 (setcdr replace converter)
54 (display-warning 'image (format "Replacing image converter %s->%s"
56 (node ; Add to existing node
57 (setcdr node (cons (cons to converter) (cdr node))))
58 (t ; New toplevel converter
59 (setq image-converters (cons (cons from (list (cons to converter)))
60 image-converters))))))
62 (defun image-unregister-converter (from to)
63 "Unregister the image converter for FROM to TO"
64 (let* ((node (assq from image-converters))
68 (if (eq to (car (car tos)))
70 (setq new (cons (car tos) new)))
74 (defun image-converter-registered-p (from to)
75 (cdr-safe (assq to (cdr-safe (assq from image-converters)))))
77 (defun image-converter-chain (from to)
78 "Return the shortest converter chain for image format FROM to TO"
79 (setq image-temp-stack (cons from image-temp-stack))
80 (let ((converters (cdr-safe (assq from image-converters)))
84 (while (and (not done) converters)
85 (setq thisone (car converters))
87 ((eq (car thisone) to)
89 ((memq (car thisone) image-temp-stack)
92 (setq possibles (cons (image-converter-chain (car thisone) to)
94 (setq converters (cdr converters)))
95 (setq image-temp-stack (cdr image-temp-stack)
96 possibles (sort (delq nil possibles)
99 (< (length (delete 'ignore x))
100 (length (delete 'ignore y)))))))
102 (setq done (car possibles)))
104 ((eq done t) (list (cdr thisone)))
105 (done (setq done (cons (cdr thisone) done)))
108 (defun image-normalize (format data)
109 "Return an image specification for XEmacs 19.13 and later. FORMAT specifies
110 the image format, DATA is the image data as a string. Any conversions to get
111 to a suitable internal image format will be carried out."
112 (setq image-temp-stack nil)
113 (if (stringp format) (setq format (intern format)))
114 (if (not (memq format image-native-formats))
115 (let* ((winner (car-safe
121 (image-converter-chain format
123 image-native-formats)
130 (< (length (memq (car x)
131 image-native-formats))
132 (length (memq (car y)
133 image-native-formats))))
136 (length (cdr y))))))))))
137 (type (car-safe winner))
138 (chain (cdr-safe winner))
142 (set-buffer (generate-new-buffer " *image-conversion*"))
147 ((stringp (car chain))
148 (let ((coding-system-for-read 'binary))
150 (point-min) (point-max)
152 (list (current-buffer) nil)
155 ((and (symbolp (car chain)) (fboundp (car chain)))
156 (funcall (car chain) (point-min) (point-max))))
157 (setq chain (cdr chain)))
158 (setq data (buffer-string))
159 (kill-buffer (current-buffer)))
161 (vector type ':data data))
162 (vector format ':data data)))
164 (defun image-register-netpbm-utilities ()
165 "Register all the netpbm utility packages converters."
167 (if (image-converter-registered-p 'pgm 'pbm)
169 (image-register-converter 'pgm 'pbm "pgmtopbm")
170 (image-register-converter 'ppm 'pgm "ppmtopgm")
171 (image-register-converter 'pnm 'xpm "ppmtoxpm")
172 (image-register-converter 'ppm 'xpm "ppmtoxpm")
173 (image-register-converter 'xpm 'ppm "xpmtoppm")
174 (image-register-converter 'gif 'ppm "giftopnm")
175 (image-register-converter 'pnm 'gif "(ppmquant 256 | ppmtogif)")
176 (image-register-converter 'ppm 'gif "(ppmquant 256 | ppmtogif)")
177 (image-register-converter 'bmp 'ppm "bmptoppm")
178 (image-register-converter 'ppm 'bmp "ppmtobmp")
179 (image-register-converter 'ppm 'ps "pnmtops")
180 (image-register-converter 'pnm 'ps "pnmtops")
181 (image-register-converter 'ps 'pnm "pstopnm")
182 (image-register-converter 'g3 'pbm "g3topbm")
183 (image-register-converter 'macpt 'pbm "macptopbm")
184 (image-register-converter 'pbm 'macpt "pbmtomacp")
185 (image-register-converter 'pcx 'ppm "pcxtoppm")
186 (image-register-converter 'ppm 'pcx "ppmtopcx")
187 (image-register-converter 'pict 'ppm "picttoppm")
188 (image-register-converter 'ppm 'pict "ppmtopict")
189 (image-register-converter 'pnm 'sgi "pnmtosgi")
190 (image-register-converter 'tga 'ppm "tgatoppm")
191 (image-register-converter 'ppm 'tga "ppmtotga")
192 (image-register-converter 'sgi 'pnm "sgitopnm")
193 (image-register-converter 'tiff 'pnm "tifftopnm")
194 (image-register-converter 'pnm 'tiff "pnmtotiff")
195 (image-register-converter 'xbm 'pbm "xbmtopbm")
196 (image-register-converter 'pbm 'xbm "pbmtoxbm")
197 (image-register-converter 'png 'pnm "pngtopnm")
198 (image-register-converter 'pnm 'png "pnmtopng")
199 (image-register-converter 'pnm 'jbg "pbmtojbg")
200 (image-register-converter 'jbg 'pnm "jbgtopbm")
201 (image-register-converter 'jpeg 'ppm "djpeg")))