From: Eli Zaretskii Date: Sat, 1 Jun 2024 13:43:18 +0000 (+0300) Subject: Fix misc problems with thumbnails on MS-Windows X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=fc61466ab15a4fd1e49dbaff4a1db26d350c9e59;p=emacs.git Fix misc problems with thumbnails on MS-Windows * lisp/image/image-dired-external.el (image-dired-pngcrush-thumb): Fix deletion of intermediate file. (image-dired-cmd-pngcrush-options) (image-dired-cmd-create-standard-thumbnail-options): Use %u for file:// URI. (image-dired--file-URI): New function. (image-dired-create-thumb-1, image-dired-create-thumb-2) (image-dired-set-exif-data): Use it to generate correct URI on MS-Windows. * src/w32image.c (Fw32image_create_thumbnail): Copy the file names before mirroring their slashes. (cherry picked from commit d2dce513445d7235c9f751ea6d9b4847d62882e7) --- diff --git a/lisp/image/image-dired-external.el b/lisp/image/image-dired-external.el index 20438fa12e7..1fa94e06e02 100644 --- a/lisp/image/image-dired-external.el +++ b/lisp/image/image-dired-external.el @@ -103,21 +103,24 @@ It optimizes the compression of PNG images. It also adds PNG textual chunks with the information required by the Thumbnail Managing Standard." :type '(choice (const :tag "Not Set" nil) file)) +;; Note: the "-text" arguments below are according to specification in +;; https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#CREATION (defcustom image-dired-cmd-pngcrush-options `("-q" - "-text" "b" "Description" "Thumbnail of file://%f" - "-text" "b" "Software" ,(emacs-version) + "-text" "b" "Description" "Thumbnail of file://%u" + "-text" "b" "Software" ,(string-replace "\n" " " (emacs-version)) ;; "-text b \"Thumb::Image::Height\" \"%oh\" " ;; "-text b \"Thumb::Image::Mimetype\" \"%mime\" " ;; "-text b \"Thumb::Image::Width\" \"%ow\" " "-text" "b" "Thumb::MTime" "%m" ;; "-text b \"Thumb::Size\" \"%b\" " - "-text" "b" "Thumb::URI" "file://%f" + "-text" "b" "Thumb::URI" "file://%u" "%q" "%t") "Arguments for `image-dired-cmd-pngcrush-program'. The value can use the same %-format specifiers as in -`image-dired-cmd-create-thumbnail-options', with \"%q\" for a -temporary file name (typically generated by pnqnq)." +`image-dired-cmd-create-thumbnail-options', with \"%q\" standing for a +temporary file name (typically generated by pnqnq), +and \"%u\" standing for a file URI corresponding to file in \"%f\"." :version "26.1" :type '(repeat (string :tag "Argument"))) @@ -134,20 +137,22 @@ The value can use the same %-format specifiers as in :type '(repeat (string :tag "Argument")) :link '(url-link "man:optipng(1)")) +;; Note: the "-set" arguments below are according to specification in +;; https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#CREATION (defcustom image-dired-cmd-create-standard-thumbnail-options (let ((opts (list "-size" "%wx%h" "%f[0]" "-set" "Thumb::MTime" "%m" - "-set" "Thumb::URI" "file://%f" - "-set" "Description" "Thumbnail of file://%f" - "-set" "Software" (emacs-version) + "-set" "Thumb::URI" "file://%u" + "-set" "Description" "Thumbnail of file://%u" + "-set" "Software" (string-replace "\n" " " (emacs-version)) "-thumbnail" "%wx%h>" "png:%t"))) (if (executable-find "gm") (cons "convert" opts) opts)) "Options for creating thumbnails according to the Thumbnail Managing Standard. Used with `image-dired-cmd-create-thumbnail-program', if that is available. The value can use the same %-format specifiers as in `image-dired-cmd-create-thumbnail-options', with \"%m\" for file -modification time. +modification time and \"%u\" for the URI of the file in \"%f\". On MS-Windows, if the `convert' command is not available, and `w32image-create-thumbnail' is used instead, the textual chunks specified by the \"-set\" options will not be injected, and instead @@ -196,6 +201,12 @@ and %v which is replaced by the tag value." ;;; Util functions +(defun image-dired--file-URI (file) + ;; https://en.wikipedia.org/wiki/File_URI_scheme + (if (memq system-type '(windows-nt ms-dos)) + (concat "/" file) + file)) + (defun image-dired--probe-thumbnail-cmd (cmd) "Check whether CMD is usable for thumbnail creation." (cond @@ -327,11 +338,11 @@ on MS-Windows cannot have too many concurrent sub-processes.") (message "command %S %s" (process-command process) (string-replace "\n" "" status)) (message "command %S failed with status %s" - process status)) + process status))) (when (or (not (processp process)) (memq (process-status process) '(exit signal))) (let ((temp (cdr (assq ?q spec)))) - (delete-file temp)))))) + (delete-file temp))))) (proc (if (eq system-type 'windows-nt) ;; See above for the reasons we don't use 'start-process' @@ -385,6 +396,7 @@ on MS-Windows cannot have too many concurrent sub-processes.") (spec `((?s . ,size) (?w . ,size) (?h . ,size) (?m . ,modif-time) (?f . ,original-file) + (?u . ,(image-dired--file-URI original-file)) (?q . ,thumbnail-nq8-file) (?t . ,thumbnail-file))) (thumbnail-dir (file-name-directory thumbnail-file)) @@ -471,6 +483,7 @@ file is created by Emacs itself." (spec `((?s . ,size) (?w . ,size) (?h . ,size) (?m . ,modif-time) (?f . ,original-file) + (?u . ,(image-dired--file-URI original-file)) (?q . ,thumbnail-nq8-file) (?t . ,thumbnail-file)))) (cond @@ -611,6 +624,7 @@ default value at the prompt." (let ((spec (list (cons ?f (expand-file-name file)) + (cons ?u (image-dired--file-URI (expand-file-name file))) (cons ?t tag-name) (cons ?v tag-value)))) (apply #'call-process image-dired-cmd-write-exif-data-program nil nil nil diff --git a/src/w32image.c b/src/w32image.c index 6daf42c1916..e71471f4a7c 100644 --- a/src/w32image.c +++ b/src/w32image.c @@ -631,7 +631,8 @@ Return non-nil if thumbnail creation succeeds, nil otherwise. */) /* Create an image by reading from INPUT_FILE. */ wchar_t input_file_w[MAX_PATH]; - input_file = ENCODE_FILE (Fexpand_file_name (input_file, Qnil)); + input_file + = ENCODE_FILE (Fexpand_file_name (Fcopy_sequence (input_file), Qnil)); unixtodos_filename (SSDATA (input_file)); filename_to_utf16 (SSDATA (input_file), input_file_w); GpImage *file_image; @@ -652,7 +653,9 @@ Return non-nil if thumbnail creation succeeds, nil otherwise. */) { /* Save the thumbnail image to a file of specified TYPE. */ wchar_t thumb_file_w[MAX_PATH]; - thumb_file = ENCODE_FILE (Fexpand_file_name (thumb_file, Qnil)); + thumb_file + = ENCODE_FILE (Fexpand_file_name (Fcopy_sequence (thumb_file), + Qnil)); unixtodos_filename (SSDATA (thumb_file)); filename_to_utf16 (SSDATA (thumb_file), thumb_file_w); status = GdipSaveImageToFile (thumb_image, thumb_file_w,