aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/image
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-11-19 11:47:19 +0100
committerLars Ingebrigtsen2019-11-19 11:47:25 +0100
commit067a42f8dd2ce19de3203605ee8c1c08aa192580 (patch)
treeb316871e26d62bad39e8d9068f7884b401a57f0d /lisp/image
parent49192e9510fe3c491b8c759a639bbe8bccf35856 (diff)
downloademacs-067a42f8dd2ce19de3203605ee8c1c08aa192580.tar.gz
emacs-067a42f8dd2ce19de3203605ee8c1c08aa192580.zip
Allow eww to display exotic images like webp
* lisp/image.el (image-type): Allow passing in the image type. (create-image): Make conversion work with data in addition to files. * lisp/image/image-converter.el (image-convert-p): Allow taking working on data in addition to files (bug#38036). (image-convert): Ditto. (image-converter--convert): Extend signature to say whether we're getting a file or data. (image-converter--convert-magick): Convert data. (image-converter--convert): Ditto.
Diffstat (limited to 'lisp/image')
-rw-r--r--lisp/image/image-converter.el105
1 files changed, 76 insertions, 29 deletions
diff --git a/lisp/image/image-converter.el b/lisp/image/image-converter.el
index 2e09976c011..dedccadcf46 100644
--- a/lisp/image/image-converter.el
+++ b/lisp/image/image-converter.el
@@ -48,43 +48,58 @@ installed on the system."
48 (imagemagick :command "convert" :probe ("-list" "format"))) 48 (imagemagick :command "convert" :probe ("-list" "format")))
49 "List of supported image converters to try.") 49 "List of supported image converters to try.")
50 50
51(defun image-convert-p (file) 51(defun image-convert-p (source &optional data-p)
52 "Return `image-convert' if FILE is an image file that can be converted." 52 "Return `image-convert' if SOURCE is an image that can be converted.
53SOURCE can either be a file name or a string containing image
54data. In the latter case, DATA-P should be non-nil. If DATA-P
55is a string, it should be a MIME format string like
56\"image/gif\"."
53 ;; Find an installed image converter. 57 ;; Find an installed image converter.
54 (unless image-converter 58 (unless image-converter
55 (image-converter--find-converter)) 59 (image-converter--find-converter))
56 (and image-converter 60 (and image-converter
57 (string-match image-converter-regexp file) 61 (or (and (not data-p)
62 (string-match image-converter-regexp source))
63 (and data-p
64 (symbolp data-p)
65 (string-match "/" (symbol-name data-p))
66 (string-match
67 image-converter-regexp
68 (concat "foo." (image-converter--mime-type data-p)))))
58 'image-convert)) 69 'image-convert))
59 70
60(defun image-convert (image) 71(defun image-convert (image &optional image-format)
61 "Convert IMAGE file to the PNG format. 72 "Convert IMAGE file to the PNG format.
62IMAGE can either be a file name, which will make the return value 73IMAGE can either be a file name, which will make the return value
63a string with the image data. It can also be an image object as 74a string with the image data.
64returned by `create-image'. If so, it has to be an image object 75
65where created with DATA-P nil (i.e., it has to refer to a file)." 76If IMAGE-FORMAT is non-nil, IMAGE is a string containing the
77image data, and IMAGE-FORMAT is a symbol with a MIME format name
78like \"image/webp\".
79
80IMAGE can also be an image object as returned by `create-image'."
66 ;; Find an installed image converter. 81 ;; Find an installed image converter.
67 (unless image-converter 82 (unless image-converter
68 (image-converter--find-converter)) 83 (image-converter--find-converter))
69 (unless image-converter 84 (unless image-converter
70 (error "No external image converters available")) 85 (error "No external image converters available"))
71 (when (and (listp image)
72 (not (plist-get (cdr image) :file)))
73 (error "Only images that refer to files can be converted"))
74 (with-temp-buffer 86 (with-temp-buffer
75 (set-buffer-multibyte nil) 87 (set-buffer-multibyte nil)
76 (when-let ((err (image-converter--convert 88 (when-let ((err (image-converter--convert
77 image-converter 89 image-converter
78 (if (listp image) 90 (if (listp image)
79 (plist-get (cdr image) :file) 91 (plist-get (cdr image) :file)
80 image)))) 92 image)
93 (if (listp image)
94 (plist-get (cdr image) :data-p)
95 image-format))))
81 (error "%s" err)) 96 (error "%s" err))
82 (if (listp image) 97 (if (listp image)
83 ;; Return an image object that's the same as we were passed, 98 ;; Return an image object that's the same as we were passed,
84 ;; but ignore the :type and :file values. 99 ;; but ignore the :type value.
85 (apply #'create-image (buffer-string) 'png t 100 (apply #'create-image (buffer-string) 'png t
86 (cl-loop for (key val) on (cdr image) by #'cddr 101 (cl-loop for (key val) on (cdr image) by #'cddr
87 unless (memq key '(:type :file)) 102 unless (eq key :type)
88 append (list key val))) 103 append (list key val)))
89 (buffer-string)))) 104 (buffer-string))))
90 105
@@ -159,33 +174,65 @@ where created with DATA-P nil (i.e., it has to refer to a file)."
159 image-converter-regexp (concat "\\." (regexp-opt formats) "\\'")) 174 image-converter-regexp (concat "\\." (regexp-opt formats) "\\'"))
160 (throw 'done image-converter))))) 175 (throw 'done image-converter)))))
161 176
162(cl-defmethod image-converter--convert ((type (eql graphicsmagick)) file) 177(cl-defmethod image-converter--convert ((type (eql graphicsmagick)) source
178 image-format)
163 "Convert using GraphicsMagick." 179 "Convert using GraphicsMagick."
164 (image-converter--convert-magick type file)) 180 (image-converter--convert-magick type source image-format))
165 181
166(cl-defmethod image-converter--convert ((type (eql imagemagick)) file) 182(cl-defmethod image-converter--convert ((type (eql imagemagick)) source
183 image-format)
167 "Convert using ImageMagick." 184 "Convert using ImageMagick."
168 (image-converter--convert-magick type file)) 185 (image-converter--convert-magick type source image-format))
186
187(defun image-converter--mime-type (image-format)
188 (and (symbolp image-format)
189 (cadr (split-string (symbol-name image-format) "/"))))
169 190
170(defun image-converter--convert-magick (type file) 191(defun image-converter--convert-magick (type source image-format)
171 (let ((command (image-converter--value type :command))) 192 (let ((command (image-converter--value type :command)))
172 (unless (zerop (apply #'call-process (car command) 193 (unless (zerop (if image-format
173 nil t nil 194 ;; We have the image data in SOURCE.
174 (append (cdr command) 195 (progn
175 (list (expand-file-name file) "png:-")))) 196 (insert source)
197 (apply #'call-process-region (point-min) (point-max)
198 (car command) t t nil
199 (append
200 (cdr command)
201 (list (format "%s:-"
202 (image-converter--mime-type
203 image-format))
204 "png:-"))))
205 ;; SOURCE is a file name.
206 (apply #'call-process (car command)
207 nil t nil
208 (append (cdr command)
209 (list (expand-file-name source) "png:-")))))
176 ;; If the command failed, hopefully the buffer contains the 210 ;; If the command failed, hopefully the buffer contains the
177 ;; error message. 211 ;; error message.
178 (buffer-string)))) 212 (buffer-string))))
179 213
180(cl-defmethod image-converter--convert ((type (eql ffmpeg)) file) 214(cl-defmethod image-converter--convert ((type (eql ffmpeg)) source
215 image-format)
181 "Convert using ffmpeg." 216 "Convert using ffmpeg."
182 (let ((command (image-converter--value type :command))) 217 (let ((command (image-converter--value type :command)))
183 (unless (zerop (apply #'call-process 218 (unless (zerop (if image-format
184 (car command) 219 (progn
185 nil '(t nil) nil 220 (insert source)
186 (append (cdr command) 221 (apply #'call-process-region
187 (list "-i" (expand-file-name file) 222 (point-min) (point-max) (car command)
188 "-c:v" "png" "-f" "image2pipe" "-")))) 223 t '(t nil) nil
224 (append
225 (cdr command)
226 (list "-i" "-"
227 "-c:v" "png"
228 "-f" "image2pipe" "-"))))
229 (apply #'call-process
230 (car command)
231 nil '(t nil) nil
232 (append (cdr command)
233 (list "-i" (expand-file-name source)
234 "-c:v" "png" "-f" "image2pipe"
235 "-")))))
189 "ffmpeg error when converting"))) 236 "ffmpeg error when converting")))
190 237
191(provide 'image-converter) 238(provide 'image-converter)