Use GdkPoint in PAN_ITEM_TRIANGLE coord
[geeqie.git] / plugins / rotate / geeqie-rotate
index 7abe42b..703ba91 100755 (executable)
 #!/bin/sh
 
-# This is a helper script that rotate jpeg files using jpegtran
+## @file
+## @brief This is a helper script that rotates image files according to the metadata
+##
+## Requirements: ImageMagick, exiftran, exiv2
+##
 
-rotation=$1
-shift
+GQ_METADATA_DIR="$HOME/.local/share/geeqie/metadata"
 
-for file in "$@" ; do
-       tmp="$file".$$
-       if jpegtran -rotate "$rotation" -copy all -outfile "$tmp" "$file"; then
-               mv -f "$tmp" "$file";
+gq_exiftran()
+{
+       if ! [ -x "$(command -v exiftran)" ]
+       then
+               zenity --title="Geeqie rotate" --info --width=200 --text="Exiftran is not installed" --window-icon=/usr/local/share/pixmaps/geeqie.png 2> /dev/null
+               exit 0
+       fi
+
+       exiftran "$@"
+}
+
+gq_exiv2()
+{
+       if ! [ -x "$(command -v exiv2)" ]
+       then
+               zenity --title="Geeqie rotate" --info --width=200 --text="Exiv2 is not installed" --window-icon=/usr/local/share/pixmaps/geeqie.png 2> /dev/null
+               exit 0
+       fi
+
+       exiv2 "$@"
+}
+
+gq_mogrify()
+{
+       if ! [ -x "$(command -v mogrify)" ]
+       then
+               zenity --title="Geeqie rotate" --info --width=200 --text="ImageMagick is not installed" --window-icon=/usr/local/share/pixmaps/geeqie.png 2> /dev/null
+               exit 0
+       fi
+
+       mogrify "$@"
+}
+
+rotate()
+{
+       ext=$(echo "${1##*.}" | tr "[:upper:]" "[:lower:]")
+       [ "$ext" = "" ] && return 1 #no extension
+
+       gq_metadata="$GQ_METADATA_DIR/$1.gq.xmp"
+       if [ -f "$gq_metadata" ]
+       then
+               gq_orientation=$(gq_exiv2 -PXkv "$gq_metadata" | grep Xmp.tiff.Orientation | sed -e "s|Xmp.tiff.Orientation *||")
+               # shellcheck disable=2181
+               [ $? != 0 ] && exit 1
+       else
+               gq_orientation=
+       fi
+
+       case "$ext" in
+               jpg | jpeg)
+                       if [ -n "$gq_orientation" ]
+                       then
+                               gq_exiv2 -M "set Exif.Image.Orientation $gq_orientation" "$1"
+                               # shellcheck disable=2181
+                               [ $? != 0 ] && exit 1
+                       fi
+                       if gq_exiftran -aip "$1"
+                       then
+                               # exiftran ignores xmp, set it manually
+                               gq_exiv2 -M "set Xmp.tiff.Orientation 1" "$1"
+                               # shellcheck disable=2181
+                               [ $? != 0 ] && exit 1
+                               #http://dev.exiv2.org/issues/639
+                               if [ -n "$gq_orientation" ]
+                               then
+                                       gq_exiv2 -M "set Xmp.tiff.Orientation 1" \
+                                               -M "set Exif.Image.Orientation 1" "$gq_metadata"
+                                       # shellcheck disable=2181
+                                       [ $? != 0 ] && exit 1
+                               fi
+                               return 0
+                       else
+                               exit 1
+                       fi
+                       ;;
+
+               tif | tiff | png)
+                       if [ -n "$gq_orientation" ]
+                       then
+                               gq_exiv2 -M "set Exif.Image.Orientation $gq_orientation" "$1"
+                               # shellcheck disable=2181
+                               [ $? != 0 ] && exit 1
+                       fi
+                       if gq_mogrify -auto-orient "$1"
+                       then
+                               # mogrify ignores xmp, set it manually
+                               gq_exiv2 -M "set Xmp.tiff.Orientation 1" "$1"
+                               # shellcheck disable=2181
+                               [ $? != 0 ] && exit 1
+                               #http://dev.exiv2.org/issues/639
+                               if [ -n "$gq_orientation" ]
+                               then
+                                       gq_exiv2 -M "set Xmp.tiff.Orientation 1" \
+                                               -M "set Exif.Image.Orientation 1" "$gq_metadata"
+                                       # shellcheck disable=2181
+                                       [ $? != 0 ] && exit 1
+                               fi
+                               return 0
+                       else
+                               exit 1
+                       fi
+                       ;;
+               *) #not supported
+                       return 4
+                       ;;
+       esac
+}
+
+rotate_image_file()
+{
+       ext=$(echo "${3##*.}" | tr "[:upper:]" "[:lower:]")
+       [ "$ext" = "" ] && return 1 #no extension
+
+       case "$ext" in
+               jpg | jpeg)
+                       gq_exiftran -i "$1" "$3"
+                       # shellcheck disable=2181
+                       [ $? != 0 ] && return 6
+                       return 0
+                       ;;
+
+               tif | tiff | png)
+                       gq_mogrify "$2" "$3"
+                       # shellcheck disable=2181
+                       [ $? != 0 ] && return 7
+                       return 0
+                       ;;
+
+               *) #not supported
+                       return 4
+                       ;;
+       esac
+}
+
+get_sidecars=
+if [ "$1" = "-g" ]
+then
+       get_sidecars=yes
+       shift
+fi
+
+rotate_image_file=
+rotation=
+if [ "$1" = "-r" ]
+then
+       rotate_image_file=yes
+       shift
+       rotation="$1"
+       shift
+fi
+
+preserve_mtime=
+if [ "$1" = "-t" ]
+then
+       preserve_mtime=yes
+       shift
+fi
+
+if [ -n "$rotation" ]
+then
+       if [ "$rotation" = "0" ]
+       then
+               exit 0
+       fi
+       if [ "$rotation" = "2" ]
+       then
+               mogrify_param="-flop"
+               exiftran_param="-F"
+       fi
+       if [ "$rotation" = "3" ]
+       then
+               mogrify_param="-rotate 180"
+               exiftran_param="-1"
+       fi
+       if [ "$rotation" = "4" ]
+       then
+               mogrify_param="-flip"
+               exiftran_param="-f"
+       fi
+       if [ "$rotation" = "5" ]
+       then
+               mogrify_param="-transpose"
+               exiftran_param="-t"
+       fi
+       if [ "$rotation" = "6" ]
+       then
+               mogrify_param="-rotate 90"
+               exiftran_param="-9"
+       fi
+       if [ "$rotation" = "7" ]
+       then
+               mogrify_param="-transverse"
+               exiftran_param="-T"
+       fi
+       if [ "$rotation" = "8" ]
+       then
+               mogrify_param="-rotate -90"
+               exiftran_param="-2"
+       fi
+fi
+
+# iterate over files on commandline
+for file in "$@"
+do
+       if [ -n "$get_sidecars" ]
+       then
+               # we got only one file for each group, typically the main one
+               # get the sidecars:
+               geeqie --remote --get-sidecars="$file" | while read -r sidecar
+               do
+                       # the main file is included in the sidecar file list, no special handling is required
+                       [ ! -w "$sidecar" ] && exit 5
+                       rotate "$sidecar"
+                       ret=$?
+               done
+               # Bourne shell runs DO loops in a sub-shell
+               ret=$?
+               [ "$ret" != 0 ] && exit "$ret"
        else
-               rm -f "$tmp";
+               [ ! -w "$file" ] && exit 5
+               if [ -n "$rotate_image_file" ]
+               then
+                       if [ -n "$preserve_mtime" ]
+                       then
+                               mtime=$(mktemp "${TMPDIR:-/tmp}/geeqie-rotate.XXXXXXXXXX") || exit 3
+                               touch --reference="$file" "$mtime"
+                       fi
+
+                       rotate_image_file "$exiftran_param" "$mogrify_param" "$file"
+                       ret=$?
+
+                       if [ -n "$preserve_mtime" ]
+                       then
+                               touch --reference="$mtime" "$file"
+                               rm "$mtime"
+                       fi
+                       [ "$ret" != 0 ] && exit "$ret"
+               else
+                       rotate "$file"
+                       ret=$?
+                       [ "$ret" != 0 ] && exit "$ret"
+               fi
        fi
 done
+
+exit 0