]> git.eshelyaron.com Git - emacs.git/commitdiff
Partially remove exiftool dependency from image-dired.el
authorStefan Kangas <stefan@marxist.se>
Sat, 23 Oct 2021 04:49:09 +0000 (06:49 +0200)
committerStefan Kangas <stefan@marxist.se>
Sat, 23 Oct 2021 06:31:03 +0000 (08:31 +0200)
* 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.

etc/NEWS
lisp/image-dired.el
lisp/image/exif.el
test/lisp/image-dired-tests.el [new file with mode: 0644]

index 7f61cf952af69e20e0732e9ae957e6b6d70a4d52..294181635e7ac3fe1fb9a0b96b931600ddc416b1 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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.
+
 \f
 * Lisp Changes in Emacs 29.1
 
index 921215c603ea3d830f439c35f62cb6ce4d7357ee..863cd0fde2f03544e18fc667dca9a10ee5bca385 100644 (file)
 ;; * 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
 ;;; 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 ;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index 67b00844d36edc4416bfa5f449740d068e099228..372e2d25553700ddd9262172726174f818905ef6 100644 (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
diff --git a/test/lisp/image-dired-tests.el b/test/lisp/image-dired-tests.el
new file mode 100644 (file)
index 0000000..0f1dbe5
--- /dev/null
@@ -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