Partially remove exiftool dependency from image-dired.el

* lisp/image-dired.el (exif): Require.
(image-dired-cmd-read-exif-data-program)
(image-dired-cmd-read-exif-data-options)
(image-dired-get-exif-data): Make obsolete in favour of using
exif.el.  This removes a dependency on external exiftool for some
operations.
(image-dired-get-exif-file-name)
(image-dired-thumbnail-set-image-description): Use exif.el
functions instead of exiftool.
* lisp/image/exif.el (exif-tag-alist): Add description and
copyright fields.
* test/lisp/image-dired-tests.el: New file.
This commit is contained in:
Stefan Kangas 2021-10-23 06:49:09 +02:00
parent bb06d5648e
commit ad7fd3cb47
4 changed files with 104 additions and 50 deletions

View file

@ -189,6 +189,15 @@ To improve security, if an sql product has ':password-in-comint' set
to t, a password supplied via the minibuffer will be sent in-process,
as opposed to via the command-line.
** Image Dired
---
*** Reduce dependency on external "exiftool" command.
The `image-dired-copy-with-exif-file-name' no longer requires an
external "exiftool" command to be available. The user options
`image-dired-cmd-read-exif-data-program' and
`image-dired-cmd-read-exif-data-options' are now obsolete.
** Exif
*** New function 'exif-field'.
@ -253,6 +262,10 @@ Use 'define-keymap' instead.
MozRepl was removed from Firefox in 2017, so this code doesn't work
with recent versions of Firefox.
---
** The function `image-dired-get-exif-data' is now obsolete.
Use `exif-parse-file' and `exif-field' instead.
* Lisp Changes in Emacs 29.1

View file

@ -65,13 +65,10 @@
;; * For non-lossy rotation of JPEG images, the JpegTRAN program is
;; needed.
;;
;; * For `image-dired-get-exif-data' and `image-dired-set-exif-data' to work,
;; the command line tool `exiftool' is needed. It can be found here:
;; https://exiftool.org/. These two functions are, among other
;; things, used for writing comments to image files using
;; `image-dired-thumbnail-set-image-description' and to create
;; "unique" file names using `image-dired-get-exif-file-name' (used by
;; `image-dired-copy-with-exif-file-name').
;; * For `image-dired-set-exif-data' to work, the command line tool `exiftool' is
;; needed. It can be found here: https://exiftool.org/. This
;; function is, among other things, used for writing comments to
;; image files using `image-dired-thumbnail-set-image-description'.
;;
;;
;; USAGE
@ -149,6 +146,7 @@
;;; Code:
(require 'dired)
(require 'exif)
(require 'image-mode)
(require 'widget)
@ -378,21 +376,6 @@ which is replaced by the tag value."
:version "26.1"
:type '(repeat (string :tag "Argument")))
(defcustom image-dired-cmd-read-exif-data-program
"exiftool"
"Program used to read EXIF data to image.
Used together with `image-dired-cmd-read-exif-data-options'."
:type 'file)
(defcustom image-dired-cmd-read-exif-data-options
'("-s" "-s" "-s" "-%t" "%f")
"Arguments of command used to read EXIF data.
Used with `image-dired-cmd-read-exif-data-program'.
Available format specifiers are: %f which is replaced
by the image file name and %t which is replaced by the tag name."
:version "26.1"
:type '(repeat (string :tag "Argument")))
(defcustom image-dired-gallery-hidden-tags
(list "private" "hidden" "pending")
"List of \"hidden\" tags.
@ -2063,8 +2046,8 @@ YYYY_MM_DD_HH_MM_DD_ORIG_FILE_NAME.jpg. Used from
"%Y:%m:%d %H:%M:%S"
(file-attribute-modification-time
(file-attributes (expand-file-name file)))))
(setq data (image-dired-get-exif-data (expand-file-name file)
"DateTimeOriginal")))
(setq data (exif-field 'date-time (exif-parse-file
(expand-file-name file)))))
(while (string-match "[ :]" data)
(setq data (replace-match "_" nil nil data)))
(format "%s%s%s" data
@ -2081,7 +2064,7 @@ default value at the prompt."
(if (not (image-dired-image-at-point-p))
(message "No thumbnail at point")
(let* ((file (image-dired-original-file-name))
(old-value (image-dired-get-exif-data file "ImageDescription")))
(old-value (or (exif-field 'description (exif-parse-file file)) "")))
(if (eq 0
(image-dired-set-exif-data file "ImageDescription"
(read-string "Value of ImageDescription: "
@ -2102,30 +2085,6 @@ default value at the prompt."
(mapcar (lambda (arg) (format-spec arg spec))
image-dired-cmd-write-exif-data-options))))
(defun image-dired-get-exif-data (file tag-name)
"From FILE, return EXIF tag TAG-NAME."
(image-dired--check-executable-exists
'image-dired-cmd-read-exif-data-program)
(let ((buf (get-buffer-create "*image-dired-get-exif-data*"))
(spec (list (cons ?f file) (cons ?t tag-name)))
tag-value)
(with-current-buffer buf
(delete-region (point-min) (point-max))
(if (not (eq (apply #'call-process image-dired-cmd-read-exif-data-program
nil t nil
(mapcar
(lambda (arg) (format-spec arg spec))
image-dired-cmd-read-exif-data-options))
0))
(error "Could not get EXIF tag")
(goto-char (point-min))
;; Clean buffer from newlines and carriage returns before
;; getting final info
(while (search-forward-regexp "[\n\r]" nil t)
(replace-match "" nil t))
(setq tag-value (buffer-substring (point-min) (point-max)))))
tag-value))
(defun image-dired-copy-with-exif-file-name ()
"Copy file with unique name to main image directory.
Copy current or all marked files in dired to a new file in your
@ -2696,6 +2655,50 @@ tags to their respective image file. Internal function used by
(dolist (tag tag-list)
(push (cons file tag) lst))))))
;;;; Obsolete
(defcustom image-dired-cmd-read-exif-data-program "exiftool"
"Program used to read EXIF data to image.
Used together with `image-dired-cmd-read-exif-data-options'."
:type 'file)
(make-obsolete-variable 'image-dired-cmd-read-exif-data-program
"use `exif-parse-file' and `exif-field' instead." "29.1")
(defcustom image-dired-cmd-read-exif-data-options '("-s" "-s" "-s" "-%t" "%f")
"Arguments of command used to read EXIF data.
Used with `image-dired-cmd-read-exif-data-program'.
Available format specifiers are: %f which is replaced
by the image file name and %t which is replaced by the tag name."
:version "26.1"
:type '(repeat (string :tag "Argument")))
(make-obsolete-variable 'image-dired-cmd-read-exif-data-options
"use `exif-parse-file' and `exif-field' instead." "29.1")
(defun image-dired-get-exif-data (file tag-name)
"From FILE, return EXIF tag TAG-NAME."
(declare (obsolete "use `exif-parse-file' and `exif-field' instead." "29.1"))
(image-dired--check-executable-exists
'image-dired-cmd-read-exif-data-program)
(let ((buf (get-buffer-create "*image-dired-get-exif-data*"))
(spec (list (cons ?f file) (cons ?t tag-name)))
tag-value)
(with-current-buffer buf
(delete-region (point-min) (point-max))
(if (not (eq (apply #'call-process image-dired-cmd-read-exif-data-program
nil t nil
(mapcar
(lambda (arg) (format-spec arg spec))
image-dired-cmd-read-exif-data-options))
0))
(error "Could not get EXIF tag")
(goto-char (point-min))
;; Clean buffer from newlines and carriage returns before
;; getting final info
(while (search-forward-regexp "[\n\r]" nil t)
(replace-match "" nil t))
(setq tag-value (buffer-substring (point-min) (point-max)))))
tag-value))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;; TEST-SECTION ;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -68,6 +68,7 @@
(defvar exif-tag-alist
'((11 processing-software)
(270 description)
(271 make)
(272 model)
(274 orientation)
@ -76,7 +77,8 @@
(296 resolution-unit)
(305 software)
(306 date-time)
(315 artist))
(315 artist)
(33432 copyright))
"Alist of tag values and their names.")
(defconst exif--orientation

View file

@ -0,0 +1,36 @@
;;; image-dired-tests.el --- Tests for image-dired.el -*- lexical-binding: t -*-
;; Copyright (C) 2021 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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 Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Code:
(require 'ert)
(require 'image-dired)
(defun image-dired-test-image-file (name)
(expand-file-name
name (expand-file-name "data/image"
(or (getenv "EMACS_TEST_DIRECTORY")
"../"))))
(ert-deftest image-dired-tests-get-exif-file-name ()
(let ((img (image-dired-test-image-file "black.jpg")))
(should (equal (image-dired-get-exif-file-name img)
"2019_09_21_16_22_13_black.jpg"))))
;;; image-dired-tests.el ends here