From ad598c5f3394386efca676829f56e721bdcef552 Mon Sep 17 00:00:00 2001 From: Pekka Helenius Date: Mon, 11 Sep 2023 20:50:03 +0300 Subject: [PATCH] Update & clean up scripts a bit --- 4_scripts/PKGBUILD | 71 +- 4_scripts/imagetools_01_exif_statistics.sh | 1756 ++++++++++------- 4_scripts/imagetools_02_dualiso.sh | 187 +- .../imagetools_03_raw_resolution-baseline.sh | 767 +++---- 4_scripts/imagetools_04_mlvdump.sh | 27 +- 4_scripts/imagetools_05_mlvinfo.sh | 8 +- 4_scripts/imagetools_06_exif_deletedata.sh | 41 +- .../imagetools_06_exif_deletedata_critical.sh | 71 +- 4_scripts/imagetools_07_ale_stack.sh | 20 +- 4_scripts/imagetools_08_geotag.sh | 122 +- 4_scripts/imagetools_09_mtime.sh | 38 +- 11 files changed, 1728 insertions(+), 1380 deletions(-) diff --git a/4_scripts/PKGBUILD b/4_scripts/PKGBUILD index 53de5c2..2e1da13 100644 --- a/4_scripts/PKGBUILD +++ b/4_scripts/PKGBUILD @@ -1,49 +1,64 @@ -# Maintainer: Pekka Helenius - pkgname=kde-servicemenus-imagetools pkgver=1 pkgrel=1 pkgdesc="Useful combination of tools for processing various images (KDE5 Dolphin action)" -url=() arch=('any') license=('GPL') -install='' -source=(imagetools_01_exif_statistics.sh -imagetools_02_dualiso.sh -imagetools_03_raw_resolution-baseline.sh -imagetools_04_mlvdump.sh -imagetools_05_mlvinfo.sh -imagetools_06_exif_deletedata.sh -imagetools_06_exif_deletedata_critical.sh -imagetools_07_ale_stack.sh -01_imagetools-statistics.desktop -02_imagetools-dng-cr2.desktop -03_imagetools-mlv.desktop -04_imagetools-jpg-png.desktop -05_imagetools-imagestack.desktop) +source=( + imagetools_01_exif_statistics.sh + imagetools_02_dualiso.sh + imagetools_03_raw_resolution-baseline.sh + imagetools_04_mlvdump.sh + imagetools_05_mlvinfo.sh + imagetools_06_exif_deletedata.sh + imagetools_06_exif_deletedata_critical.sh + imagetools_07_ale_stack.sh + imagetools_09_mtime.sh + 01_imagetools-statistics.desktop + 02_imagetools-dng-cr2.desktop + 03_imagetools-mlv.desktop + 04_imagetools-jpg-png.desktop + 05_imagetools-imagestack.desktop +) #xwinkill) #Workaround for bug: https://sourceforge.net/p/gnuplot/bugs/1659/ -depends=('magiclantern-tools' 'perl-image-exiftool' 'ale' 'dcraw' 'netpbm' 'gnuplot' 'coreutils' 'dolphin') -optdepends=() -conflicts=() -makedepends=() -md5sums=('b4c1f2f5906a56c5cd5404415b26ad5b' - 'a84bf74fb67a5f6f2289ebee2ce4452e' - '6e81d48727e7fc6922a2aed0ce7810c1' +depends=( + magiclantern-tools + perl-image-exiftool + ale + dcraw + netpbm + gnuplot + coreutils + dolphin +) + +md5sums=('a4e9c260727723ebfecf986586c34880' + '758c9cc2ecc858350e041504f7d7ea12' + 'cdc5c555acb2b96411e16cfa9ea2f25d' 'a7e0c36553ff59d182460a2108163798' '01756513818969a07ff61a1ee648106b' '75588a9f375ac5c6f6f245d12cc315d5' 'c294e69b9f6e714a307306fd4301fd61' '88cbadd0f290c737f7f0660a7029029d' + '2b239ca3efac3713004635d29798b44d' '93bb82eec8ead83b5b5369822d44d780' - '940848e05d6c6400eac97a998fb0f26b' + 'a3e7650c1cbfd8d113f57f60d8699c6b' 'be883bb11a24c4f7ac6452f3cab6cf66' - '9170a5e116fc2eede5325d0a985931dc' + 'b42063458ada3002666280a5b06b1e92' '531f2b73b8514430a772a61a10de097f') package() { + mkdir -p $pkgdir/usr/share/kservices5/ServiceMenus/ - cp $srcdir/{imagetools_01_exif_statistics.sh,imagetools_02_dualiso.sh,imagetools_03_raw_resolution-baseline.sh,imagetools_04_mlvdump.sh,imagetools_05_mlvinfo.sh,imagetools_06_exif_deletedata.sh,imagetools_06_exif_deletedata_critical.sh,imagetools_07_ale_stack.sh,01_imagetools-statistics.desktop,02_imagetools-dng-cr2.desktop,03_imagetools-mlv.desktop,04_imagetools-jpg-png.desktop,05_imagetools-imagestack.desktop} $pkgdir/usr/share/kservices5/ServiceMenus/ - chmod 755 $pkgdir/usr/share/kservices5/ServiceMenus/{imagetools_01_exif_statistics.sh,imagetools_02_dualiso.sh,imagetools_03_raw_resolution-baseline.sh,imagetools_04_mlvdump.sh,imagetools_05_mlvinfo.sh,imagetools_06_exif_deletedata.sh,imagetools_06_exif_deletedata_critical.sh,imagetools_07_ale_stack.sh,01_imagetools-statistics.desktop,02_imagetools-dng-cr2.desktop,03_imagetools-mlv.desktop,04_imagetools-jpg-png.desktop,05_imagetools-imagestack.desktop} + + for t in sh desktop; do + for f in ${srcdir}/*.${t}; do + cp ${f} $pkgdir/usr/share/kservices5/ServiceMenus/ + done + done + + find $pkgdir/usr/share/kservices5/ServiceMenus/ -type f -iname "*.sh" -exec chmod 755 {} \; + #chmod +x $pkgdir/usr/share/kservices5/ServiceMenus/xwinkill } diff --git a/4_scripts/imagetools_01_exif_statistics.sh b/4_scripts/imagetools_01_exif_statistics.sh index c231910..25dc5a2 100644 --- a/4_scripts/imagetools_01_exif_statistics.sh +++ b/4_scripts/imagetools_01_exif_statistics.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Statistics of camera RAW images with GNU Plot & Exiftool -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -62,131 +62,143 @@ # You can run the script in bash (or execute Dolphin via bash) to get detailed script output (CLI messages, debug messages etc.) # -#BRACKETS AND QUOTATION MARKS ARE USED IN THIS SCRIPT BECAUSE FOLDER AND FILE PATHS MAY CONTAIN SPACES! - ####################################################################### -# VARIABLES FOR THE SCRIPT CSV_FILECOUNT=$(printf '%s\n' "${@}" | rev | cut -f 1 -d '.' | rev | grep -i "csv" | wc -l) RAW_FILECOUNT=$(printf '%s\n' "${@}" | rev | cut -f 1 -d '.' | rev | grep -i -E "cr2|nef|dng" | wc -l) -COLUMNCOUNT=24 #Count of all columns must be found in CSV file. This number must match with the number found in kdialog processing dialog below. +# Count of all columns must be found in CSV file. +# This number must match with the number found in kdialog processing dialog below. +COLUMNCOUNT=24 ####################################################################### -# 1ST FILE CHECK - -if [[ "${@}" == "" ]]; then - kdialog --error "Not any files selected!"; - exit -elif [[ ! $CSV_FILECOUNT == 0 ]] && [[ ! $RAW_FILECOUNT == 0 ]]; then - kdialog --error "Select only RAW files or a single CSV file!"; - exit -elif [[ $CSV_FILECOUNT -gt 1 ]]; then - kdialog --error "Select only one CSV file!"; - exit -elif [[ $RAW_FILECOUNT == 1 ]]; then - kdialog --error "Please select at least 2 valid RAW files or a CSV file!"; - exit -elif [[ $RAW_FILECOUNT == 0 ]] && [[ $CSV_FILECOUNT == 0 ]]; then - kdialog --error "Please select valid RAW files or a CSV file!"; - exit + +# The first file check + +if [[ "${@}" == "" ]] +then + kdialog --error "Not any files selected!"; + exit 1 + +elif \ + [[ ! "${CSV_FILECOUNT}" -eq 0 ]] && \ + [[ ! "${RAW_FILECOUNT}" -eq 0 ]] +then + kdialog --error "Select only RAW files or a single CSV file!"; + exit 1 + +elif [[ "${CSV_FILECOUNT}" -gt 1 ]] +then + kdialog --error "Select only one CSV file!"; + exit 1 + +elif [[ "${RAW_FILECOUNT}" -eq 1 ]] +then + kdialog --error "Please select at least 2 valid RAW files or a CSV file!"; + exit 1 + +elif \ + [[ "${RAW_FILECOUNT}" -eq 0 ]] && \ + [[ "${CSV_FILECOUNT}" -eq 0 ]] +then + kdialog --error "Please select valid RAW files or a CSV file!"; + exit 1 fi ####################################################################### -# KDIALOG CHECK LIST FORMATTED SELECTION WINDOW +# KDialog check list formatted selection window -if [[ $RAW_FILECOUNT == 0 ]] && [[ $CSV_FILECOUNT == 1 ]]; then +if \ + [[ $RAW_FILECOUNT == 0 ]] && \ + [[ $CSV_FILECOUNT == 1 ]] +then - SELECTION=$(kdialog --checklist "Select statistics to display:" \ - 1 "" off \ - 2 "" off \ + SELECTION=$(kdialog --checklist "Select statistics to display:" \ + 1 "Apertures, Exposures & ISOs" off \ + 2 "Focal Lengths & Lenses" off \ 3 "Temperatures & ISOs" on \ - 4 "" off \ - ); - - # 1 Apertures, Exposures & ISOs - # 2 Focal Lengths & Lenses - # 3 Temperatures & ISOs - # 4 Shooting & Focus Modes - - if [ "$?" = 0 ]; then - if [ $(expr length "$SELECTION") != 0 ]; then - for result in $SELECTION - do - if [ $result = '"1"' ]; then - SEL1=true - fi - if [ $result = '"2"' ]; then - SEL2=true - fi - if [ $result = '"3"' ]; then - SEL3=true - fi - if [ $result = '"4"' ]; then - SEL4=true - fi - done - else - kdialog --sorry "Aborted"; - fi - elif [ "$?" = 1 ]; then - exit 0 + 4 "Shooting & Focus Modes" off \ + ); + + # 1 Apertures, Exposures & ISOs + # 2 Focal Lengths & Lenses + # 3 Temperatures & ISOs + # 4 Shooting & Focus Modes + + if [[ "$?" = 0 ]]; then + if [[ $(expr length "$SELECTION") -ne 0 ]] + then + for result in $SELECTION + do + [[ "${result}" = '"1"' ]] && SEL1=true + [[ "${result}" = '"2"' ]] && SEL2=true + [[ "${result}" = '"3"' ]] && SEL3=true + [[ "${result}" = '"4"' ]] && SEL4=true + done + else - kdialog --error "Unexpected Error"; + kdialog --sorry "Aborted"; fi - SEL5=false + elif [[ "$?" -eq 1 ]] + then + exit 0 + else + kdialog --error "Unexpected Error"; + fi + SEL5=false fi -if [[ $RAW_FILECOUNT != 0 ]] && [[ $CSV_FILECOUNT == 0 ]]; then +if \ + [[ $RAW_FILECOUNT -ne 0 ]] && \ + [[ $CSV_FILECOUNT -eq 0 ]] +then - SELECTION=$(kdialog --checklist "Select statistics to display:" \ - 1 "" off \ - 2 "" off \ + SELECTION=$(kdialog --checklist "Select statistics to display:" \ + 1 "Apertures, Exposures & ISOs" off \ + 2 "Focal Lengths & Lenses" off \ 3 "Temperatures & ISOs" on \ - 4 "" off \ + 4 "Shooting & Focus Modes" off \ 5 "Export Only (CSV)" off \ - ); - - # 1 Apertures, Exposures & ISOs - # 2 Focal Lengths & Lenses - # 3 Temperatures & ISOs - # 4 Shooting & Focus Modes - # 5 Export Only (CSV) - - if [ "$?" = 0 ]; then - if [ $(expr length "$SELECTION") != 0 ]; then - for result in $SELECTION - do - if [ $result = '"1"' ]; then - SEL1=true - fi - if [ $result = '"2"' ]; then - SEL2=true - fi - if [ $result = '"3"' ]; then - SEL3=true - fi - if [ $result = '"4"' ]; then - SEL4=true - fi - if [ $result = '"5"' ]; then #If checked, we force all other values to be false - SEL5=true - SEL4=false - SEL3=false - SEL2=false - SEL1=false - fi - done - else - kdialog --sorry "Aborted"; + ); + + # 1 Apertures, Exposures & ISOs + # 2 Focal Lengths & Lenses + # 3 Temperatures & ISOs + # 4 Shooting & Focus Modes + # 5 Export Only (CSV) + + if [[ "$?" = 0 ]]; then + if [ $(expr length "$SELECTION") -ne 0 ] + then + for result in $SELECTION + do + [[ "${result}" = '"1"' ]] && SEL1=true + [[ "${result}" = '"2"' ]] && SEL2=true + [[ "${result}" = '"3"' ]] && SEL3=true + [[ "${result}" = '"4"' ]] && SEL4=true + + # If checked, we force all other values to be false + if [[ "${result}" = '"5"' ]] + then + SEL5=true + SEL4=false + SEL3=false + SEL2=false + SEL1=false fi - elif [ "$?" = 1 ]; then - exit 0 + done else - kdialog --error "Unexpected Error"; + kdialog --sorry "Aborted"; fi + + elif [[ "$?" -eq 1 ]] + then + exit 0 + else + kdialog --error "Unexpected Error"; + fi fi # SEL1 = "Apertures, Exposures & ISOs" true/false @@ -197,186 +209,263 @@ fi ####################################################################### -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... +# We get the directory just from the first filename. INPUT_DIR=$(dirname "${1}") DIR_BASENAME=$(echo -n "${INPUT_DIR}" | rev | cut -d'/' -f 1 | rev) -#First & Last file names (without suffixes) +# First & Last file names (without suffixes). for last; do true; done -FIRST=$(basename "${1}" | cut -f 1 -d '.') #Name of the first file passed into the script -LAST=$(basename "${last}" | cut -f 1 -d '.') #Name of the last file passed into the script -#File name is based on the folder where files exist +# Name of the first file passed into the script. +FIRST=$(basename "${1}" | cut -f 1 -d '.') +# Name of the last file passed into the script. +LAST=$(basename "${last}" | cut -f 1 -d '.') + +# File name is based on the folder where files exist FILENAME=$(echo "${DIR_BASENAME}-${FIRST}-${LAST}_metadata") FILE_EXT=.csv -#Sed is here to remove any trailing spaces and crap like blank lines -INPUT_FILESYSTEM=$(df -h "${1}" | awk -F ' ' 'FNR> 1 {print $1}' | grep -i -E "/dev/sd?|/dev/hd?|?rewritefs|?tmpfs|/dev/nvme?" | sed '/^\s*$/d' | wc -l) - ####################################################################### # 2ND FILE CHECK # Check if we are dealing with a CSV file or bunch of RAW files. -if [[ $CSV_FILECOUNT == 1 ]]; then +if [[ "${CSV_FILECOUNT}" -eq 1 ]]; then - FILENAME=$(basename "${1}" | sed 's/\.\w*$//') #without a suffix. #We use valid existing CSV file name here - CSVFOLDER="${INPUT_DIR}" #We don't need to redirect this folder path to $HOME because we assume this file already exists + # Without a suffix. We use valid existing CSV file name here. + FILENAME=$(basename "${1}" | sed 's/\.\w*$//') + CSVFOLDER="${INPUT_DIR}" -# If the first input file is not CSV but a RAW file, then we check the filesystem of this file and decide whether to use $HOME folder or picture folder for a new CSV file. -# We don't need this check for any CSV files, because we just extract information from them, not any write operations are required. -elif [[ $RAW_FILECOUNT != 0 ]]; then - echo "Multiple RAW files." - if [[ "${INPUT_FILESYSTEM}" -eq 0 ]]; then #if input file (first file printed in bash) filesystem does not start with /dev/sdX - CSVFOLDER="${HOME}" - kdialog --msgbox "Images are in a SD Card. Writing EXIF CSV data file to ${HOME}/" - # TODO If we have exactly same files selected in SD card but we don't have CSV file in home folder, this doesn't work as expected. It assumes the file to be checked is in home folder. - else - CSVFOLDER="${INPUT_DIR}" - fi +elif [[ "${RAW_FILECOUNT}" -ne 0 ]]; then + echo "Multiple RAW files." fi RAWDATA_TMP="${CSVFOLDER}/${FILENAME}${FILE_EXT}" ####################################################################### -# 1) CHECK CSV FILE VALIDITY AGAINST THE SCRIPT OUTPUT -# 2) GET VALUE FOR 'INPUT_FILES_MD5SUM' VARIABLE +# 1) Check CSV file validity against the script output. +# 2) Get value for 'INPUT_FILES_MD5SUM' variable. -# NOTE: We don't check MD5Sums, if we use CSV file as an input. Though this file can exist in the same folder with the pictures, we want to keep CSV files as portable as possible in general. -# Thus, we don't do the following check: CSV file list MD5Sums vs actual corresponding files in the folder (if only CSV is selected as input). This can arise other problems such as images -# with equivalent names listed in CSV file but they are actually different files. This causes mismatch between CSV file content and folder content. So, no go. +# NOTE: We don't check MD5Sums, if we use CSV file as an input. +# Though this file can exist in the same folder with the pictures, +# we want to keep CSV files as portable as possible in general. +# Thus, we don't do the following check: CSV file list MD5Sums +# vs actual corresponding files in the folder (if only CSV is selected as input). +# This can arise other problems such as images with equivalent names listed in +# CSV file but they are actually different files. +# This causes mismatch between CSV file content and folder content. So, no go. # 1) Check validity of the selected CSV file for analysis purposes. Not RAW files selected. -if [[ -e "${RAWDATA_TMP}" ]]; then # Referring to existing CSV file here. User input may or may not be a CSV file, so we don't check it. - - echo "This is a valid CSV file. Checking columns." - - FILE_COLUMNCOUNT=$(echo -n $(awk -F ',' '{print NF}' "${RAWDATA_TMP}" | sort -nu)) #This *must* return only one value (equal to COLUMNCOUNT). If many values are returned CSV file can't be used because, therefore, there are mismatch between column numbers in rows. - FILE_HASMD5COLUMN=$(awk -F ',' '{print $2}' "${RAWDATA_TMP}" | head -n 1) - FILE_MD5_CHARNUM=$(echo -n $(awk -F ',' ' FNR > 1 {print length($2)}' "${RAWDATA_TMP}" | sort -nu)) #This *must* return only one value. Value 32. - - # If the input csv file has valid count of columns and the second column includes md5sums. - if [[ $FILE_COLUMNCOUNT -eq $COLUMNCOUNT ]] && [[ $FILE_HASMD5COLUMN == "File MD5Sum" ]] && [[ $FILE_MD5_CHARNUM == 32 ]]; then - COLUMNS_OK=true - echo "Columns OK, continuing." - elif [[ $RAW_FILECOUNT == 0 ]]; then - echo -e "Charnum is:$FILE_MD5_CHARNUM" - echo "Error in columns." - kdialog --error "Error in CSV file columns!"; - exit - else - echo "Error in matching file columns. RAW files as input." - COLUMNS_OK=false #This is a case where we have detected a pattern matcing CSV file but it has invalid columns. - fi + +# Referring to existing CSV file here. User input may or may not be a CSV file, so we don't check it. +if [[ -e "${RAWDATA_TMP}" ]] +then + + echo "This is a valid CSV file. Checking columns." + + # This *must* return only one value (equal to COLUMNCOUNT). + # If many values are returned CSV file can't be used because, + # therefore, there are mismatch between column numbers in rows. + FILE_COLUMNCOUNT=$(echo -n $(awk -F ',' '{print NF}' "${RAWDATA_TMP}" | sort -nu)) + + FILE_HASMD5COLUMN=$(awk -F ',' '{print $2}' "${RAWDATA_TMP}" | head -n 1) + FILE_MD5_CHARNUM=$(echo -n $(awk -F ',' ' FNR > 1 {print length($2)}' "${RAWDATA_TMP}" | sort -nu)) #This *must* return only one value. Value 32. + + # If the input csv file has valid count of columns and the second column includes md5sums. + if \ + [[ "${FILE_COLUMNCOUNT}" -eq "${COLUMNCOUNT}" ]] && \ + [[ "${FILE_HASMD5COLUMN}" == "File MD5Sum" ]] && \ + [[ "${FILE_MD5_CHARNUM}" -eq 32 ]] + then + COLUMNS_OK=true + echo "Columns OK, continuing." + + elif [[ "${RAW_FILECOUNT}" -eq 0 ]] + then + echo -e "Charnum is: ${FILE_MD5_CHARNUM}" + echo "Error in columns." + kdialog --error "Error in CSV file columns!"; + exit 0 + + else + echo "Error in matching file columns. RAW files as input." + + # This is a case where we have detected a pattern matcing CSV file but it has invalid columns. + COLUMNS_OK=false + fi fi # 2) Instead of single CSV file, if multiple RAW files have been selected, then -if [[ $RAW_FILECOUNT != 0 ]]; then - - echo "Getting MD5Sums for RAW files..." - - #get md5sums for the files and print output - #Syntax: IMG_8217,IMG_8408,IMG_8544 ... (replace these file names just with md5sums and you get the idea) - INPUT_FILES_MD5SUM=$(echo -n $(printf '%s\n' $(md5sum "${@}") | sed '$!N;s/\n/ /' | awk -F ' ' '{print $2,$1}' | sed -e 's/^.*\///' | sort -n | awk -F ' ' '{print $2}' | tr '\n' ',' | sed 's/,*\r*$//')) - - echo "Comparing MD5Sums..." - - MAINCSV=$(find "${CSVFOLDER}" -maxdepth 1 -iname "${FILENAME}*${FILE_EXT}") - MAINCSV_COUNT=$(find "${CSVFOLDER}" -maxdepth 1 -iname "${FILENAME}*${FILE_EXT}" | wc -l) - - OTHER_CSV=$(find "${CSVFOLDER}" -maxdepth 1 -iname "*${FILE_EXT}") - OTHER_CSV_COUNT=$(find "${CSVFOLDER}" -maxdepth 1 -iname "*${FILE_EXT}" | wc -l) - - # Main CSV file - if [[ $COLUMNS_OK == true ]]; then +if [[ "${RAW_FILECOUNT}" -ne 0 ]] +then - COMPAREFILE_MD5SUM=$(echo -n $(awk -F ',' 'FNR> 1 {print $1,$2}' "${RAWDATA_TMP}" |sort -n | awk -F ' ' '{print $2}' | tr '\n' ',' | sed 's/,*\r*$//')) - - #if md5sums match OK, then... - if [[ "$INPUT_FILES_MD5SUM" == "$COMPAREFILE_MD5SUM" ]]; then - echo -e "MD5Sums match OK." - USEMAINCSV=true + echo "Getting MD5Sums for RAW files..." + + # Get md5sums for the files and print output. + # Syntax: IMG_8217,IMG_8408,IMG_8544 ... + # (replace these file names just with md5sums and you get the idea) + INPUT_FILES_MD5SUM=$( + echo -n $(printf '%s\n' $(md5sum "${@}") | \ + sed '$!N;s/\n/ /' | \ + awk -F ' ' '{print $2,$1}' | \ + sed -e 's/^.*\///' | \ + sort -n | \ + awk -F ' ' '{print $2}' | \ + tr '\n' ',' | \ + sed 's/,*\r*$//' + ) + ) + + echo "Comparing MD5Sums..." + + MAINCSV=$(find "${CSVFOLDER}" -maxdepth 1 -iname "${FILENAME}*${FILE_EXT}") + MAINCSV_COUNT=$(find "${CSVFOLDER}" -maxdepth 1 -iname "${FILENAME}*${FILE_EXT}" | wc -l) + + OTHER_CSV=$(find "${CSVFOLDER}" -maxdepth 1 -iname "*${FILE_EXT}") + OTHER_CSV_COUNT=$(find "${CSVFOLDER}" -maxdepth 1 -iname "*${FILE_EXT}" | wc -l) + + # Main CSV file + if [[ "${COLUMNS_OK}" == true ]]; then + + COMPAREFILE_MD5SUM=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $1,$2}' "${RAWDATA_TMP}" | \ + sort -n | \ + awk -F ' ' '{print $2}' | \ + tr '\n' ',' | \ + sed 's/,*\r*$//' + ) + ) + + # If md5sums match OK, then + if [[ "${INPUT_FILES_MD5SUM}" == "${COMPAREFILE_MD5SUM}" ]] + then + echo -e "MD5Sums match OK." + USEMAINCSV=true + else + echo -e "MD5Sums match not OK." + USEMAINCSV=false + fi + fi + + # Other CSV files, including variant of the CSV "file template". + if \ + [[ ! -e "${RAWDATA_TMP}" ]] || \ + [[ "${OTHER_CSV_COUNT}" -ne 0 ]] || \ + [[ "${USEMAINCSV}" == false ]] + then + + # Check for CSV variants (which match the filename syntax). + if [[ "${MAINCSV_COUNT}" -gt 0 ]] + then + + for m in ${MAINCSV} + do + + COMPAREFILE_MD5SUM=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $1,$2}' "${m}" | \ + sort -n | \ + awk -F ' ' '{print $2}' | \ + tr '\n' ',' | \ + sed 's/,*\r*$//' + ) + ) + + if [[ "${INPUT_FILES_MD5SUM}" == "${COMPAREFILE_MD5SUM}" ]] + then + RAWDATA_TMP="${m}" + + # We get the existing file name template and remove extension. + FILENAME=$(basename "${m}" | cut -f 1 -d '.') + USEMAINCSV=true + break else - echo -e "MD5Sums match not OK." - USEMAINCSV=false + USEMAINCSV=false fi + done fi - - # Other CSV files, including variant of the CSV "file template" - if [[ ! -e "${RAWDATA_TMP}" ]] || [[ ! $OTHER_CSV_COUNT == 0 ]] || [[ $USEMAINCSV == false ]]; then - - # Check for CSV variants (which match the filename syntax) - if [[ $MAINCSV_COUNT -gt 0 ]]; then - - for m in $MAINCSV; do - echo "DEBUG: Do we get here 1?" - - COMPAREFILE_MD5SUM=$(echo -n $(awk -F ',' 'FNR> 1 {print $1,$2}' "${m}" |sort -n | awk -F ' ' '{print $2}' | tr '\n' ',' | sed 's/,*\r*$//')) - - if [[ "$INPUT_FILES_MD5SUM" == "$COMPAREFILE_MD5SUM" ]]; then - RAWDATA_TMP="${m}" - FILENAME=$(basename "${m}" | cut -f 1 -d '.') #We get the existing file name template and remove extension. - echo "DEBUG: Do we get here 2?" - USEMAINCSV=true - break - else - echo "DEBUG: Do we get here 3?" - USEMAINCSV=false - fi - done - fi - - # Check for other CSVs - if [[ $MAINCSV_COUNT -eq 0 ]] || [[ ! $OTHER_CSV_COUNT == 0 ]] && [[ $USEMAINCSV == false ]]; then - - for f in $OTHER_CSV; do - echo "DEBUG: Do we get here 4?" - COMPAREFILE_MD5SUM=$(echo -n $(awk -F ',' 'FNR> 1 {print $1,$2}' "${f}" |sort -n | awk -F ' ' '{print $2}' | tr '\n' ',' | sed 's/,*\r*$//')) - - if [[ "$INPUT_FILES_MD5SUM" == "$COMPAREFILE_MD5SUM" ]]; then - RAWDATA_TMP="${f}" - FILENAME=$(basename "${f}" | cut -f 1 -d '.') #We get the existing file name template and remove extension. - echo "DEBUG: Do we get here 5?" - USEOTHERCSV=true - break - else - echo "DEBUG: Do we get here 6?" - USEOTHERCSV=false - fi - done + + # Check for other CSVs. + if \ + [[ "${MAINCSV_COUNT}" -eq 0 ]] || \ + [[ "${OTHER_CSV_COUNT}" -ne 0 ]] && \ + [[ "${USEMAINCSV}" == false ]] + then + + for f in ${OTHER_CSV} + do + COMPAREFILE_MD5SUM=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $1,$2}' "${f}" | \ + sort -n | \ + awk -F ' ' '{print $2}' | \ + tr '\n' ',' | \ + sed 's/,*\r*$//' + ) + ) + + if [[ "${INPUT_FILES_MD5SUM}" == "${COMPAREFILE_MD5SUM}" ]] + then + RAWDATA_TMP="${f}" + + # We get the existing file name template and remove extension. + FILENAME=$(basename "${f}" | cut -f 1 -d '.') + USEOTHERCSV=true + break + else + USEOTHERCSV=false fi + done fi + fi fi -if [[ $USEMAINCSV == false ]] && [[ $USEOTHERCSV == false ]]; then - - echo "DEBUG: Do we get here 7?" - x=1 - while [[ -e "${CSVFOLDER}/${FILENAME}-${x}${FILE_EXT}" ]]; do - let x++ - done - FILENAME="${FILENAME}-${x}" +if \ + [[ ${USEMAINCSV} == false ]] && \ + [[ ${USEOTHERCSV} == false ]] +then + + x=1 + while [[ -e "${CSVFOLDER}/${FILENAME}-${x}${FILE_EXT}" ]] + do + let x++ + done + FILENAME="${FILENAME}-${x}" fi echo -e "MD5Sums checked.\n" -if [[ $USEMAINCSV == true ]] || [[ $USEOTHERCSV == true ]]; then - echo -e "Found an existing CSV file with MD5Sums.\n" - -elif [[ $USEMAINCSV == true ]] && [[ $USEOTHERCSV == false ]]; then - echo -e "Using existing CSV with correct file template.\n" - -elif [[ $USEMAINCSV == true ]] && [[ $USEOTHERCSV == false ]]; then - echo -e "Using a custom named CSV file.\n" - -elif [[ $USEMAINCSV == false ]] || [[ $USEOTHERCSV == false ]]; then - echo -e "Creating a new CSV file.\n" +if \ + [[ $USEMAINCSV == true ]] || \ + [[ $USEOTHERCSV == true ]] +then + echo -e "Found an existing CSV file with MD5Sums.\n" + +elif \ + [[ $USEMAINCSV == true ]] && \ + [[ $USEOTHERCSV == false ]] +then + echo -e "Using existing CSV with correct file template.\n" + +elif \ + [[ $USEMAINCSV == true ]] && \ + [[ $USEOTHERCSV == false ]] +then + echo -e "Using a custom named CSV file.\n" + +elif \ + [[ $USEMAINCSV == false ]] || \ + [[ $USEOTHERCSV == false ]] +then + echo -e "Creating a new CSV file.\n" fi ####################################################################### -#We need to redefine bash variables to overwrite the old values! + +# We need to redefine bash variables to overwrite the old values! FILENAME2="${FILENAME}-temp" FILENAME3="${FILENAME}-iso" @@ -385,433 +474,544 @@ RAWDATA_TMP2="/tmp/${FILENAME2}${FILE_EXT}" RAWDATA_TMP3="/tmp/${FILENAME3}${FILE_EXT}" ################# + #DEBUGGING echo "We use file named $RAWDATA_TMP" -if [[ $SEL3 == true ]]; then - echo "We use isofile named $RAWDATA_TMP2" - echo "We use tempfile named $RAWDATA_TMP3" +if [[ "${SEL3}" == true ]] +then + echo "We use isofile named $RAWDATA_TMP2" + echo "We use tempfile named $RAWDATA_TMP3" fi -#echo -#exit -################# -############################################################################################################################################## +####################################################################### -# KDIALOG PROCESSING WINDOW - BEGIN +# PROGRESSBAR CODE - BEGIN -####PROGRESSBAR STUFF - BEGIN -LABELTEXT='Exporting statistics...' +LABELTEXT="Exporting statistics..." numargs=$# # Number of all files -tics=100 # Percentage tics -inc=0 # Current file number -mltp=1000 # Percentage multiplier for bash +tics=100 # Percentage tics +inc=0 # Current file number +mltp=1000 # Percentage multiplier for bash -if [[ ! -e "${RAWDATA_TMP}" ]]; then #If the file already exists, we don't want overwrite it. Instead, we skip these steps to speed up the process. +# If the file already exists, we don't want overwrite it. +# Instead, we skip these steps to speed up the process. +if [[ ! -e "${RAWDATA_TMP}" ]] +then + dbusRef=$(kdialog --title "Metadata Extraction (${DIR_BASENAME}: images ${FIRST}-${LAST})" --progressbar "${LABELTEXT}" "${tics}") + qdbus $dbusRef showCancelButton true - dbusRef=$(kdialog --title "Metadata Extraction ($DIR_BASENAME: images $FIRST-$LAST)" --progressbar "$LABELTEXT" $tics) - qdbus $dbusRef showCancelButton true -####PROGRESSBAR STUFF - END +# PROGRESSBAR CODE - END - while [[ $# -gt 0 ]] && [[ $(qdbus $dbusRef wasCancelled) == "false" ]]; do +while \ + [[ $# -gt 0 ]] && \ + [[ $(qdbus $dbusRef wasCancelled) == "false" ]] +do - i="${1}" + i="${1}" ############################################## # 1 COLUMN - # ENABLE THIS IF STATEMENT ONLY IF FILE NAMES CONTAINING 'IMG_' ARE ONLY ACCEPTED - #if [[ ! $(echo $(basename "${1}" | cut -f 1 -d '.')) == *"IMG_"* ]]; then - # echo $(basename "${1}" | cut -f 1 -d '.') - # ERRFILE=1 #PRINT INVALID INPUT AS THE LAST COLUMN DUE TO DATE/TIME COLUMNS! SEE BELOW! - #else - echo $(basename "${i}" | cut -f 1 -d '.') #| sed -e 's/IMG_//g') #echo ${i##*/} | sed -e 's/.CR2//g' -e 's/.DNG//g') - # ERRFILE=0 - #fi + # ENABLE THIS IF STATEMENT ONLY IF FILE NAMES CONTAINING 'IMG_' ARE THE ONLY ONES ACCEPTED + + #if [[ ! $(echo $(basename "${1}" | cut -f 1 -d '.')) == *"IMG_"* ]] + #then + # echo $(basename "${1}" | cut -f 1 -d '.') + # ERRFILE=1 #PRINT INVALID INPUT AS THE LAST COLUMN DUE TO DATE/TIME COLUMNS! SEE BELOW! + #else + echo $(basename "${i}" | cut -f 1 -d '.') #| sed -e 's/IMG_//g') #echo ${i##*/} | sed -e 's/.CR2//g' -e 's/.DNG//g') + # ERRFILE=0 + #fi ############################################## -# 2 COLUMN - #Write md5sum of a file for checking purposes! - md5sum "${i}" | awk -F ' ' '{print $1}' +# 2 COLUMN - md5sum + + # Write md5sum of a file for checking purposes! + md5sum "${i}" | awk -F ' ' '{print $1}' ############################################## -# 3 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Temperature" | sed -e 's/[^0-9]*//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Camera Temperature" | sed -e 's/[^0-9]*//g' - else - echo "errtag" - fi +# 3 COLUMN - temperature + + if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Temperature" | sed -e 's/[^0-9]*//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Camera Temperature" | sed -e 's/[^0-9]*//g' + else + echo "errtag" + fi ############################################## -# 4 COLUMN - # ISO Speed setting (yeah, we get it from "Recommended Exposure Index" tag. - if [[ $(exiftool "${i}" | grep -v "Sensitivity" | grep --max-count=1 "Recommended Exposure Index" | sed 's/[^0-9]*//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" | grep -v "Sensitivity" | grep --max-count=1 "Recommended Exposure Index" | sed 's/[^0-9]*//g' - else - echo "errtag" - fi +# 4 COLUMN - sensitivity + + # ISO Speed setting (yeah, we get it from "Recommended Exposure Index" tag. + + if [[ $(exiftool "${i}" | grep -v "Sensitivity" | grep --max-count=1 "Recommended Exposure Index" | sed 's/[^0-9]*//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" | grep -v "Sensitivity" | grep --max-count=1 "Recommended Exposure Index" | sed 's/[^0-9]*//g' + else + echo "errtag" + fi ############################################## -# 5 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' - else - echo "errtag" - fi +# 5 COLUMN - exposure time + + if [[ $(exiftool "${i}" |grep --max-count=1 "Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 6 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Target Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Target Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' - else - echo "errtag" - fi +# 6 COLUMN - target exposure time + + if [[ $(exiftool "${i}" |grep --max-count=1 "Target Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Target Exposure Time" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 7 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Exposure Compensation" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Exposure Compensation" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' - else - echo "errtag" - fi +# 7 COLUMN - exposure compensation + + if [[ $(exiftool "${i}" |grep --max-count=1 "Exposure Compensation" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Exposure Compensation" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 8 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Aperture Value" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Aperture Value" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' - else - echo "errtag" - fi +# 8 COLUMN - aperture + + if [[ $(exiftool "${i}" |grep --max-count=1 "Aperture Value" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Aperture Value" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 9 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Target Aperture" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Target Aperture" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' - else - echo "errtag" - fi +# 9 COLUMN - target aperture + + if [[ $(exiftool "${i}" |grep --max-count=1 "Target Aperture" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Target Aperture" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' + else + echo "errtag" + fi ############################################## # 10 COLUMN + # Average histogram value for image (brightness etc.) # For documentation, see http://netpbm.sourceforge.net/doc/pgmhist.html # we need to convert the image into grayscale with dcraw -d option # dcraw "manual" is found here: http://www.inweb.ch/foto/dcrawhelp.txt - if [[ $(dcraw -d -4 -j -c "${i}" | pgmhist -median | wc -l) -eq 1 ]]; then - dcraw -d -4 -j -c "${i}" | pgmhist -median | sed 's/[^0-9]*//g' - else - echo "errtag" - fi + if [[ $(dcraw -d -4 -j -c "${i}" | pgmhist -median | wc -l) -eq 1 ]] + then + dcraw -d -4 -j -c "${i}" | pgmhist -median | sed 's/[^0-9]*//g' + else + echo "errtag" + fi ############################################## -# 11 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Focal Length" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' -e 's/ //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Focal Length" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' -e 's/ //g' #sed 's/ mm//g' - else - echo "errtag" - fi +# 11 COLUMN - focal length + + if [[ $(exiftool "${i}" |grep --max-count=1 "Focal Length" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' -e 's/ //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Focal Length" | sed -e 's/[A-Za-z]*//g' -e 's/.*: //g' -e 's/ //g' + else + echo "errtag" + fi ############################################## -# 12 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Hyperfocal Distance" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Hyperfocal Distance" | sed -e 's/.*: //g' -e 's/ m//g' - else - echo "errtag" - fi +# 12 COLUMN - hyperfocal distance + + if [[ $(exiftool "${i}" |grep --max-count=1 "Hyperfocal Distance" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Hyperfocal Distance" | sed -e 's/.*: //g' -e 's/ m//g' + else + echo "errtag" + fi ############################################## -# 13 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Distance Upper" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Focus Distance Upper" | sed -e 's/.*: //g' -e 's/ m//g' - else - echo "errtag" - fi +# 13 COLUMN - upper focus distance + + if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Distance Upper" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Focus Distance Upper" | sed -e 's/.*: //g' -e 's/ m//g' + else + echo "errtag" + fi ############################################## -# 14 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Distance Lower" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Focus Distance Lower" | sed -e 's/.*: //g' -e 's/ m//g' - else - echo "errtag" - fi +# 14 COLUMN - lower focus distance + + if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Distance Lower" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Focus Distance Lower" | sed -e 's/.*: //g' -e 's/ m//g' + else + echo "errtag" + fi ############################################## -# 15 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Depth Of Field" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Depth Of Field" | sed -e 's/.*: //g' -e 's/ m//g' - else - echo "errtag" - fi +# 15 COLUMN - depth of field + + if [[ $(exiftool "${i}" |grep --max-count=1 "Depth Of Field" | sed -e 's/.*: //g' -e 's/ m//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Depth Of Field" | sed -e 's/.*: //g' -e 's/ m//g' + else + echo "errtag" + fi ############################################## -# 16 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Model Name" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Camera Model Name" | sed 's/.*: //g' - else - echo "errtag" - fi +# 16 COLUMN - camera model + + if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Model Name" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Camera Model Name" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 17 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Lens Type" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Lens Type" | sed 's/.*: //g' - else - echo "errtag" - fi +# 17 COLUMN - lens type + + if [[ $(exiftool "${i}" |grep --max-count=1 "Lens Type" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Lens Type" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 18 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Mode" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Focus Mode" | sed 's/.*: //g' - else - echo "errtag" - fi +# 18 COLUMN - focus mode + + if [[ $(exiftool "${i}" |grep --max-count=1 "Focus Mode" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Focus Mode" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 19 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Shooting Mode" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Shooting Mode" | sed 's/.*: //g' - else - echo "errtag" - fi +# 19 COLUMN - shooting mode + + if [[ $(exiftool "${i}" |grep --max-count=1 "Shooting Mode" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Shooting Mode" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 20 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Live View Shooting" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Live View Shooting" | sed 's/.*: //g' - else - echo "errtag" - fi +# 20 COLUMN - live view shooting + + if [[ $(exiftool "${i}" |grep --max-count=1 "Live View Shooting" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Live View Shooting" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 21 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Orientation" | sed 's/.*: //g' | wc -l) -eq 1 ]]; then - exiftool "${i}" |grep --max-count=1 "Camera Orientation" | sed 's/.*: //g' - else - echo "errtag" - fi +# 21 COLUMN - camera orientation + + if [[ $(exiftool "${i}" |grep --max-count=1 "Camera Orientation" | sed 's/.*: //g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Camera Orientation" | sed 's/.*: //g' + else + echo "errtag" + fi ############################################## -# 21 COLUMN -# Subject Tags +# 21 COLUMN - subject - if [ $(exiftool "${i}" |grep --max-count=1 "Subject" | sed -e 's/.*: //g' | wc -l) == 0 ]; then + if [[ $(exiftool "${i}" |grep --max-count=1 "Subject" | sed -e 's/.*: //g' | wc -l) -eq 0 ]] + then - # If Subject tag is empty, get input file filetype (CR2 or cr2 // DNG or dng) - if [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed '/^\s*$/d')) == "CR2" ]] || [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed '/^\s*$/d')) == "cr2" ]]; then - echo "Single ISO CR2" + # If Subject tag is empty, get input file filetype (CR2 or cr2 // DNG or dng) + if [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed -e '/^\s*$/d' -e 's/\(.*\)/\U\1/')) == "CR2" ]] + then + echo "Single ISO CR2" - elif [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed '/^\s*$/d')) == "DNG" ]] || [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed '/^\s*$/d')) == "dng" ]]; then - echo "Single ISO DNG" - fi + elif [[ $(echo $(basename "${i}" | cut -f 2 -d '.' | sed -e '/^\s*$/d' -e 's/\(.*\)/\U\1/')) == "DNG" ]] + then + echo "Single ISO DNG" + fi - #If we have a real Subject tag, extract info from it - else - exiftool "${i}" |grep --max-count=1 "Subject" | sed -e 's/.*: //g' - fi + # If we have a real Subject tag, extract info from it + else + exiftool "${i}" |grep --max-count=1 "Subject" | sed -e 's/.*: //g' + fi ############################################## -# 23 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f1 | awk -F ":" '{print $3, $2, $1}' | sed -e 's/ /\//g' | wc -l) -eq 1 ]]; then +# 23 COLUMN - datetime original - exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f1 | awk -F ":" '{print $3, $2, $1}' | sed -e 's/ /\//g' - else - echo "errtag" - fi + if [[ $(exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f1 | awk -F ":" '{print $3, $2, $1}' | sed -e 's/ /\//g' | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f1 | awk -F ":" '{print $3, $2, $1}' | sed -e 's/ /\//g' + else + echo "errtag" + fi ############################################## -# 24 COLUMN - if [[ $(exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f2 | wc -l) -eq 1 ]]; then - - exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f2 - else - echo "errtag" - fi +# 24 COLUMN - datetime original + if [[ $(exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f2 | wc -l) -eq 1 ]] + then + exiftool "${i}" |grep --max-count=1 "Date/Time Original" | sed -e 's/.*: //g' | cut -d' ' -f2 + else + echo "errtag" + fi ############################################## # ENABLE THIS FOR CHECKING FILE NAMES. IF ENABLED, ALL FILES MUST CONTAIN 'IMG_' STRING OR OTHERWISE, THEY ARE EXCLUDED FROM THE STATISTICS! - #Write this line/column only, if an invalid file name has been detected -# if [[ "$ERRFILE" -eq 1 ]]; then -# echo "errname" -# fi + +# Write this line/column only, if an invalid file name has been detected +# if [[ "$ERRFILE" -eq 1 ]]; then +# echo "errname" +# fi ############################################## - echo "newline" #this is written just as a dummy separator for each processed files for further line separation done below. + # This is written just as a dummy separator for each processed files for further line separation done below. + echo "newline" ############################################## - ####PROGRESSBAR STUFF - BEGIN - # This section is increasing values seen in the kdialog processing window. - - let inc++ + # PROGRESSBAR CODE - BEGIN + + # This section is increasing values seen in the kdialog processing window. + + let inc++ + + #Percentage needs to be calculated like this due to bash rounding limitations... + PERCENT_VALUE=$(((${mltp}*${tics})/(200*${numargs}/${inc} % 2 + ${mltp}*${numargs}/${inc}))) + + qdbus $dbusRef Set "" "value" "${PERCENT_VALUE}"; + qdbus $dbusRef setLabelText "${LABELTEXT} (${inc}/${numargs})"; + + # PROGRESSBAR CODE - END + + shift - #Percentage needs to be calculated like this due to bash rounding limitations... - PERCENT_VALUE=$((($mltp*$tics)/(200*$numargs/$inc % 2 + $mltp*$numargs/$inc))) +############################################## - qdbus $dbusRef Set "" "value" $PERCENT_VALUE; - qdbus $dbusRef setLabelText "$LABELTEXT ($inc/$numargs)"; + # Sort output: + # replace newlines with commas + # remove more commas + # replace 'newline' with a new line + # trim the first and the last commas of any line + # sort lines by Date & Time (23th & 24th column) + # write output - ####PROGRESSBAR STUFF - END +done | \ +tr '\n' ',' | \ +sed -e 's/,[^,]*$//' -e 's/newline/\n/g' | \ +sed -e 's/^,//g' -e 's/\(.*\),/\1/' | \ +sort -t ',' -n -k23 -k24 | \ +sed 's/inf/∞/g' \ +> "${RAWDATA_TMP}" - shift +#| sed 's/newline/\n/g' | sort -u ############################################## - # Sort output: replace newlines with commas, remove more commas, replace 'newline' with a new line, trim the first and the last commas of any line. Sort lines by Date & Time (23th & 24th column) and write output - done | tr '\n' ',' | sed -e 's/,[^,]*$//' -e 's/newline/\n/g' | sed -e 's/^,//g' -e 's/\(.*\),/\1/' | sort -t ',' -n -k23 -k24 | sed 's/inf/∞/g' > "${RAWDATA_TMP}" #| sed 's/newline/\n/g' | sort -u +# Close processing window if cancelled event has been triggered. -############################################## +# PROGRESSBAR CODE - BEGIN -#Close processing window if cancelled event has been triggered. +# If the process was cancelled, remove tmp file and exit the script. +if [[ ! $(qdbus $dbusRef wasCancelled) == "false" ]]; then + + # We can delete the file because its existence has been checked before the processing + # window has been opened. Thus we don't get here, if the file already exists. + rm -f "${RAWDATA_TMP}" + exit 0 +fi + +# PROGRESSBAR CODE - END - ####PROGRESSBAR STUFF - BEGIN - # If the process was cancelled, remove tmp file and exit the script. - if [[ ! $(qdbus $dbusRef wasCancelled) == "false" ]]; then - rm "${RAWDATA_TMP}" #We can delete the file because its existence has been checked before the processing window has been opened. Thus we don't get here, if the file already exists. - exit - fi - ####PROGRESSBAR STUFF - END ########################################### - #Add correct titles to the first row in RAWDATA_TMP file: - sed -i '1s/^/Image File,File MD5Sum,Camera Temperature,ISO,Shutter Speed,Target Exposure,Exposure Compensation,Aperture,Target Aperture,Histogram Median,Focal Length,Hyperfocal Distance,Upper Focus Distance,Lower Focus Distance,Depth Of Field,Camera Model,Lens Model,Focus Mode,Exposure Mode,Live View,Camera Orientation,ISO Type,Date,Time\n/' "${RAWDATA_TMP}" +#Add correct titles to the first row in RAWDATA_TMP file: +sed -i '1s/^/Image File,File MD5Sum,Camera Temperature,ISO,Shutter Speed,Target Exposure,Exposure Compensation,Aperture,Target Aperture,Histogram Median,Focal Length,Hyperfocal Distance,Upper Focus Distance,Lower Focus Distance,Depth Of Field,Camera Model,Lens Model,Focus Mode,Exposure Mode,Live View,Camera Orientation,ISO Type,Date,Time\n/' "${RAWDATA_TMP}" - #Close processing window if not cancelled and processing finished. - ####PROGRESSBAR STUFF - BEGIN - qdbus $dbusRef close - ####PROGRESSBAR STUFF - END +#Close processing window if not cancelled and processing finished. +# PROGRESSBAR CODE - BEGIN - # SEL1 = "Apertures, Exposures & ISOs" true/false - # SEL2 = "Focal Lengths & Lenses" true/false - # SEL3 = "Temperatures & ISOs" true/false - # SEL4 = "Shooting & Focus Modes" true/false - # SEL5 = "Export Only (CSV)" true/false +qdbus $dbusRef close - if [[ $SEL5 == true ]]; then - kdialog --msgbox "EXIF data exported successfully"; - exit - fi +# PROGRESSBAR CODE - END + +# SEL1 = "Apertures, Exposures & ISOs" true/false +# SEL2 = "Focal Lengths & Lenses" true/false +# SEL3 = "Temperatures & ISOs" true/false +# SEL4 = "Shooting & Focus Modes" true/false +# SEL5 = "Export Only (CSV)" true/false + +if [[ "${SEL5}" == true ]] +then + kdialog --msgbox "EXIF data exported successfully"; + exit 0 +fi -elif [[ -e "${RAWDATA_TMP}" ]] && [[ $SEL5 == true ]]; then - kdialog --msgbox "EXIF data exported already.\n\nFile:\n\n${RAWDATA_TMP}"; - exit +elif \ + [[ -e "${RAWDATA_TMP}" ]] && \ + [[ "${SEL5}" == true ]] +then + kdialog --msgbox "EXIF data exported already.\n\nFile:\n\n${RAWDATA_TMP}"; + exit 0 fi -#KDIALOG PROCESSING WINDOW - END +# KDIALOG PROCESSING WINDOW - END ############################################## # Check RAWDATA_TMP for bad line outputs - # 1) BADFILES: Open written (or existing) CSV file - # 2) BADFILES: List all lines matching pattern "errname" or "errtag" - # 3) BADFILES: Write output as a single line, using comma mark to separate the written output (file names). Remove the last extra comma. +# 1) BADFILES: Open written (or existing) CSV file +# 2) BADFILES: List all lines matching pattern "errname" or "errtag" +# 3) BADFILES: Write output as a single line, using comma mark to separate the written output (file names). +# Remove the last extra comma. BADFILES=$(cat "${RAWDATA_TMP}" | sed -ne '/errname/p' -ne '/errtag/p' | sed 's/,.*$//') BADFILES_COUNT=$(cat "${RAWDATA_TMP}" | sed -ne '/errname/p' -ne '/errtag/p' | sed 's/,.*$//' | wc -l) -#Count lines found in the output of BADFILES. If not zero (e.g. bad strings found), then... -if [[ $BADFILES_COUNT != 0 ]]; then - - cat "${RAWDATA_TMP}" | sed -e '/errname/d' -e '/errtag/d' > "/tmp/${FILENAME}-errtags${FILE_EXT}" - RAWDATA_TMP_ERR="/tmp/${FILENAME}-errtags${FILE_EXT}" #We don't want to overwrite the original file. - - if [[ $(cat "${RAWDATA_TMP_ERR}" | wc -l) == 1 ]]; then #If not any valid output image files. Minimum count of lines is 2. - kdialog --error "Could not process any input file:\n\n$BADFILES\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nExiting."; - rm "${RAWDATA_TMP_ERR}" - exit - elif [[ $(cat "${RAWDATA_TMP_ERR}" | wc -l) -le 2 ]]; then #if we have just a single file here. Minimum count of lines is 3. - kdialog --error "Could not process a valid number of input files. Minimum count of valid files is 2.\n\nFiles that could not be processed:\n\n$BADFILES\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nExiting." - rm "${RAWDATA_TMP_ERR}" - exit - else - mv "/tmp/${FILENAME}-errtags${FILE_EXT}" "${CSVFOLDER}/${FILENAME}-errtags${FILE_EXT}" - RAWDATA_TMP="${CSVFOLDER}/${FILENAME}-errtags${FILE_EXT}" - kdialog --msgbox "Could not process files:\n\n$BADFILES\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease exclude these files or check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nNew CSV file written as (bad files excluded):\n${RAWDATA_TMP}"; - fi +#Count lines found in the output of BADFILES. If not zero (e.g. bad strings found), then +if [[ "${BADFILES_COUNT}" -ne 0 ]] +then + + cat "${RAWDATA_TMP}" | sed -e '/errname/d' -e '/errtag/d' > "/tmp/${FILENAME}-errtags${FILE_EXT}" + + # We don't want to overwrite the original file. + RAWDATA_TMP_ERR="/tmp/${FILENAME}-errtags${FILE_EXT}" + + # If not any valid output image files. Minimum count of lines is 2. + if [[ $(cat "${RAWDATA_TMP_ERR}" | wc -l) == 1 ]] + then + + kdialog --error "Could not process any input file:\n\n${BADFILES}\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nExiting."; + + rm "${RAWDATA_TMP_ERR}" + exit 1 + + # If we have just a single file here. Minimum count of lines is 3. + elif [[ $(cat "${RAWDATA_TMP_ERR}" | wc -l) -le 2 ]] + then + + kdialog --error "Could not process a valid number of input files. Minimum count of valid files is 2.\n\nFiles that could not be processed:\n\n$BADFILES\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nExiting." + + rm "${RAWDATA_TMP_ERR}" + exit 1 + + else + + mv "/tmp/${FILENAME}-errtags${FILE_EXT}" "${CSVFOLDER}/${FILENAME}-errtags${FILE_EXT}" + RAWDATA_TMP="${CSVFOLDER}/${FILENAME}-errtags${FILE_EXT}" + + kdialog --msgbox "Could not process files:\n\n${BADFILES}\n\nThis can be due to missing EXIF data such as Temperature, ISO, Date or Time.\n\nPlease exclude these files or check CSV file (${FILENAME}${FILE_EXT}) contents to study the problem.\n\nNew CSV file written as (bad files excluded):\n${RAWDATA_TMP}"; + + fi fi ###################################################################################### -FILELIST=$(echo -n $(awk -F ',' 'FNR> 1 {print $1}' "${RAWDATA_TMP}" |sort -n |tr ' ' '\n' | sort -n | tr '\n' ',' | sed 's/,*\r*$//')) - -#Total count of accepted pictures, used for further data representation in gnuplot. We reduce it by 1 due to file header (column titles are not counted): +FILELIST=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $1}' "${RAWDATA_TMP}" | \ + sort -n | \ + tr ' ' '\n' | \ + sort -n | \ + tr '\n' ',' | \ + sed 's/,*\r*$//' + ) +) + +#Total count of accepted pictures, used for further data representation in gnuplot. +# We reduce it by 1 due to file header (column titles are not counted): ACCEPTED_TOTAL=$(echo -n $(($(cat "${RAWDATA_TMP}" | wc -l) - 1))) -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## +###################################################################################### -####GNUPLOT STUFF - BEGIN +# GNUPLOT CODE - BEGIN -GNUPLOT_MAINWINDOW_TITLE=$(echo "$DIR_BASENAME ($ACCEPTED_TOTAL images, $FILENAME)") +GNUPLOT_MAINWINDOW_TITLE=$(echo "${DIR_BASENAME} (${ACCEPTED_TOTAL} images, ${FILENAME})") ########################################################### -# GNUPLOT TIME VALUES - -#PLOT 1 -# Should we use time values in the first plot? If too many images, basically rendered unreadable -# Rotate x labels if there are too many of them - -if [[ $ACCEPTED_TOTAL -lt 10 ]]; then #Do not rotate x labels, if we have less than 10 images selected - X_ROTATELABELS=$(echo -n "") - if [[ $ACCEPTED_TOTAL -le 6 ]]; then #Time values are only if max 6 images selected - X2_TIMESTRINGS=$(echo -n "set x2tics offset 0,-0.5") - else - X2_TIMESTRINGS=$(echo -n "unset x2tics") - fi +# GNUPlot time values + +# PLOT 1 + +# Should we use time values in the first plot? +# If too many images, plot is basically rendered unreadable. +# Rotate x labels if there are too many items to be shown. + +# Do not rotate x labels, if we have less than 10 images selected. +if [[ $ACCEPTED_TOTAL -lt 10 ]] +then + + X_ROTATELABELS=$(echo -n "") + + # Time values are only if max 6 images selected. + if [[ $ACCEPTED_TOTAL -le 6 ]] + then + X2_TIMESTRINGS=$(echo -n "set x2tics offset 0,-0.5") + else + X2_TIMESTRINGS=$(echo -n "unset x2tics") + fi else - X_ROTATELABELS=$(echo -n "set xtics rotate 90") + X_ROTATELABELS=$(echo -n "set xtics rotate 90") fi ############################################################ -#IMAGE COUNT/UNIT SCALES FOR GNUPLOT PLOTS 2 & 3 - -if [[ $ACCEPTED_TOTAL -le 10 ]]; then - SCALE=1 -elif [[ $ACCEPTED_TOTAL -gt 10 ]] && [[ $ACCEPTED_TOTAL -le 20 ]]; then - SCALE=2 -elif [[ $ACCEPTED_TOTAL -gt 20 ]] && [[ $ACCEPTED_TOTAL -le 40 ]]; then - SCALE=4 -elif [[ $ACCEPTED_TOTAL -gt 40 ]] && [[ $ACCEPTED_TOTAL -le 60 ]]; then - SCALE=6 -elif [[ $ACCEPTED_TOTAL -gt 60 ]] && [[ $ACCEPTED_TOTAL -le 80 ]]; then - SCALE=8 -elif [[ $ACCEPTED_TOTAL -gt 80 ]] && [[ $ACCEPTED_TOTAL -le 200 ]]; then - SCALE=10 -elif [[ $ACCEPTED_TOTAL -gt 200 ]] && [[ $ACCEPTED_TOTAL -le 400 ]]; then - SCALE=20 -elif [[ $ACCEPTED_TOTAL -ge 400 ]]; then - SCALE=40 +# Image count/unit scales for GNUPlot plots 2 & 3 + +if [[ "${ACCEPTED_TOTAL}" -le 10 ]]; then + SCALE=1 +elif [[ "${ACCEPTED_TOTAL}" -gt 10 ]] && [[ "${ACCEPTED_TOTAL}" -le 20 ]]; then + SCALE=2 +elif [[ "${ACCEPTED_TOTAL}" -gt 20 ]] && [[ "${ACCEPTED_TOTAL}" -le 40 ]]; then + SCALE=4 +elif [[ "${ACCEPTED_TOTAL}" -gt 40 ]] && [[ "${ACCEPTED_TOTAL}" -le 60 ]]; then + SCALE=6 +elif [[ "${ACCEPTED_TOTAL}" -gt 60 ]] && [[ "${ACCEPTED_TOTAL}" -le 80 ]]; then + SCALE=8 +elif [[ "${ACCEPTED_TOTAL}" -gt 80 ]] && [[ "${ACCEPTED_TOTAL}" -le 200 ]]; then + SCALE=10 +elif [[ "${ACCEPTED_TOTAL}" -gt 200 ]] && [[ "${ACCEPTED_TOTAL}" -le 400 ]]; then + SCALE=20 +elif [[ "${ACCEPTED_TOTAL}" -ge 400 ]]; then + SCALE=40 fi -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## - -# ISO VALUES - -#Do the following stuff only, if we have checked for any ISO related stuff in the kdialog selection. -if [[ $SEL1 == true ]] || [[ $SEL3 == true ]]; then +############################################################ +# GNUPlot ISO values -#ISO min max values +# Do the following, if we have selected ISO related items in kdialog selection window. +if \ + [[ ${SEL1} == true ]] || \ + [[ ${SEL3} == true ]] +then + +# ISO min max values # 1) Use awk to print field 3 from RAWDATA_TMP. Ignore the first row with FNR> 1 option. -# 2) awk prints equivalent numbers as output. Merge them with "|sort -n" pipe. sort prints numbers starting from the smallest (first line) and ending to the greatest (last line) +# 2) awk prints equivalent numbers as output. Merge them with "|sort -n" pipe. +# sort prints numbers starting from the smallest (first line) and ending to the greatest (last line). # 3) Strip the output, either first line (head -1) or the last one (tail -1). - ISO_MIN_VALUE=$(echo -n $(awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | sort -n | head -1)) - ISO_MAX_VALUE=$(echo -n $(awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | sort -n | tail -1)) - -#################################################################################################################### + ISO_MIN_VALUE=$(echo -n $(awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | sort -n | head -1)) + ISO_MAX_VALUE=$(echo -n $(awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | sort -n | tail -1)) -# ISO VALUES GENERATING RAWDATA_TMP2 +############################################################ -#Get percentages for ISO values usage +# Get percentages for ISO values usage, generate RAWDATA_TMP2 file. # OUTPUT template for RAWDATA_TMP3 is as follows: @@ -822,28 +1022,57 @@ if [[ $SEL1 == true ]] || [[ $SEL3 == true ]]; then # 1) Use awk to print field 3 from RAWDATA_TMP. Ignore the first row with FNR> 1 option. # 2) awk prints equivalent numbers as output. Count and merge them with "|sort -n | uniq -c" pipe # 3) Output results leading white spaces. For each line, delete them with sed. -# 4) use awk as pipe (awk starting with '{b[$2]=$1;sum=sum ...) to calculate percentage for the first column. First column has count number for each ISO value ("how many times ISO XX is used"). ISOs are defined in column 2. Print the output to a new column 3. -# 5) In step 4, the output has too many decimals. As the output of this step is written to column 3, we use another awk pipe to strip too many decimals of the current column 3. To keep two first decimals, we use %.2f option. Print column 1 ($1) and 2 ($2) as they are, respectively. Add % mark and start a new line (\n) after each printf function. -# 6) Replace spaces with commas for the final output, and write the final output to RAWDATA_TMP3. +# 4) use awk as pipe (awk starting with '{b[$2]=$1;sum=sum ...) to calculate percentage +# for the first column. First column has count number for each ISO value ("how many times ISO XX is used"). +# ISOs are defined in column 2. Print the output to a new column 3. +# 5) In step 4, the output has too many decimals. As the output of this step is written to column 3, +# we use another awk pipe to strip too many decimals of the current column 3. +# To keep two first decimals, we use %.2f option. Print column 1 ($1) and 2 ($2) as they are, +# respectively. Add % mark and start a new line (\n) after each printf function. +# 6) Replace spaces with commas for the final output, and write the final output to RAWDATA_TMP2. - awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" |sort -n | uniq -c | sed "s/^[ \t]*//" | awk '{b[$2]=$1;sum=sum+$1} END{for (i in b) print b[i],i,(b[i]/sum)*100}' | awk '{printf "%.0f %.0f %.2f'%'\n", $1,$2,$3}' | tr ' ' ',' > "${RAWDATA_TMP2}" + awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | \ + sort -n | \ + uniq -c | \ + sed "s/^[ \t]*//" | \ + awk '{b[$2]=$1;sum=sum+$1} END{for (i in b) print b[i],i,(b[i]/sum)*100}' | \ + awk '{printf "%.0f %.0f %.2f'%'\n", $1,$2,$3}' | \ + tr ' ' ',' \ + > "${RAWDATA_TMP2}" #################################################################################################################### -# ISO VALUES - MINIMUM, MAXIMUM, LEAST USED, MOST USED AND AVERAGE - -#What is the maximum number of matches for a single ISO value? - MAX_MATCH_FOR_ISO=$(echo -n $(awk -F ',' '{print $1}' "${RAWDATA_TMP2}" | sort -n | tail -1)) - -#We store current min/max ISOvalues to a string variables - WHATIS_REAL_MAX_ISO=$(echo -en "Max: $ISO_MAX_VALUE") # Returns column 3 value of RAWDATA_TMP E.G. 3200, based on max column 3 value of RAWDATA_TMP - WHATIS_REAL_MIN_ISO=$(echo -en "Min: $ISO_MIN_VALUE") # Returns column 3 value of RAWDATA_TMP E.G. 200, based on min column 3 value of RAWDATA_TMP - -#Format: (1*400)+(1*1600)+(2*3200) ... - ISO_DIVIDEND=$(echo -n $(($(awk -F ',' '{print "("$1,$2")"}' "${RAWDATA_TMP2}" | sort -n | sed -e 's/ /*/g' | tr '\n' '+' | sed 's/+[^+]*$//')))) - -#Just a basic average calculation - ISO_AVERAGE=$(echo -e $(awk 'BEGIN {print "'"$ISO_DIVIDEND"'"/"'"$ACCEPTED_TOTAL"'"}' | awk '{printf "%.0f", $1}')) +# ISO values - minimum, maximum, least used, most used, average + + # What is the maximum number of matches for a single ISO value? + MAX_MATCH_FOR_ISO=$(echo -n $(awk -F ',' '{print $1}' "${RAWDATA_TMP2}" | sort -n | tail -1)) + + # We store current min/max ISOvalues to a string variables + + # Returns column 3 value of RAWDATA_TMP E.G. 3200, based on max column 3 value of RAWDATA_TMP + WHATIS_REAL_MAX_ISO=$(echo -en "Max: $ISO_MAX_VALUE") + # Returns column 3 value of RAWDATA_TMP E.G. 200, based on min column 3 value of RAWDATA_TMP + WHATIS_REAL_MIN_ISO=$(echo -en "Min: $ISO_MIN_VALUE") + + # Format: (1*400)+(1*1600)+(2*3200) ... + ISO_DIVIDEND=$( + echo -n $( + ($( + awk -F ',' '{print "("$1,$2")"}' "${RAWDATA_TMP2}" | \ + sort -n | \ + sed -e 's/ /*/g' | \ + tr '\n' '+' | \ + sed 's/+[^+]*$//' + )) + ) + ) + + # Just a basic average calculation + ISO_AVERAGE=$( + echo -e $( + awk 'BEGIN {print "'"$ISO_DIVIDEND"'"/"'"$ACCEPTED_TOTAL"'"}' | awk '{printf "%.0f", $1}' + ) + ) ########################################################## @@ -853,117 +1082,172 @@ if [[ $SEL1 == true ]] || [[ $SEL3 == true ]]; then # 2) Sort percentage values from lowest to greatest, starting from the lowest # 3) Get the match count for each percentage value (column 3 value) with 'uniq -c' # 4) Trim all leading white spaces for each printed line -# 5) We have now two columns, separated by space. Get the first column with awk pipe, use space as a column separator, and print column 1 ($1) -# 6) Get the first line. Output represents the number of matches for listed percentage. We check if it's not 1 in the following if statement. - -# The whole idea is that we can't give a true statement for "What is the least/most used ISO value" if multiple ISO values equal same percentage for usage - - MOSTUSED_ISO_CHECK=$(echo -n $(awk -F ',' '{print $3}' "${RAWDATA_TMP2}" | sort -n | uniq -c | sed "s/^[ \t]*//" | awk -F ' ' '{print $1}' | tail -1)) - LEASTUSED_ISO_CHECK=$(echo -n $(awk -F ',' '{print $3}' "${RAWDATA_TMP2}" | sort -n | uniq -c | sed "s/^[ \t]*//" | awk -F ' ' '{print $1}' | head -1)) - -#The following gives a correct value ONLY IF there are unique values for EACH ISOs. Otherwise, the output is not as expected. That's why we need to check the values of MOST/LEASTUSED_ISO_CHECK first. - MOSTUSED_ISO=$(echo -n $(awk -F ',' '{print $3,$2}' "${RAWDATA_TMP2}" | sort -n | awk -F ' ' '{print $2}' | tail -1)) - LEASTUSED_ISO=$(echo -n $(awk -F ',' '{print $3,$2}' "${RAWDATA_TMP2}" | sort -n | awk -F ' ' '{print $2}' | head -1)) +# 5) We have now two columns, separated by space. Get the first column with awk pipe, +# use space as a column separator, and print column 1 ($1) +# 6) Get the first line. Output represents the number of matches for listed percentage. +# We check if it's not 1 in the following if statement. + + # The whole idea is that we can't give a true statement for + # "What is the least/most used ISO value" if multiple ISO values equal same percentage for usage + + MOSTUSED_ISO_CHECK=$( + echo -n $( + awk -F ',' '{print $3}' "${RAWDATA_TMP2}" | sort -n | uniq -c | sed "s/^[ \t]*//" | awk -F ' ' '{print $1}' | tail -1 + ) + ) + LEASTUSED_ISO_CHECK=$( + echo -n $( + awk -F ',' '{print $3}' "${RAWDATA_TMP2}" | sort -n | uniq -c | sed "s/^[ \t]*//" | awk -F ' ' '{print $1}' | head -1 + ) + ) + + # The following gives a correct value ONLY IF there are unique values for EACH ISOs. + # Otherwise, the output is not as expected. That's why we need to check the values + # of MOST/LEASTUSED_ISO_CHECK first. + MOSTUSED_ISO=$( + echo -n $( + awk -F ',' '{print $3,$2}' "${RAWDATA_TMP2}" | sort -n | awk -F ' ' '{print $2}' | tail -1 + ) + ) + LEASTUSED_ISO=$( + echo -n $( + awk -F ',' '{print $3,$2}' "${RAWDATA_TMP2}" | sort -n | awk -F ' ' '{print $2}' | head -1 + ) + ) ########################################################## -#In addition, we consider that minimum of 10 pictures must be accepted as input. Otherwise, user can read this info pretty easily just checking the gnuplot graphs. +# In addition, we consider that minimum of 10 pictures must be accepted as input. +# Otherwise, user can read this info pretty easily just checking the gnuplot graphs. - if [[ "$LEASTUSED_ISO_CHECK" -ne 1 ]]; then #If more than one, then... - WHATIS_LEASTUSED_ISO=$(echo -n "") #Output string, nothing to say. - elif [[ "$LEASTUSED_ISO_CHECK" -eq 1 ]]; then #Else if it's one, then... - if [[ "$ACCEPTED_TOTAL" -gt 10 ]]; then #...we check the number of pictures. If it's greater than 10, then print the following string. - WHATIS_LEASTUSED_ISO=$(echo -n ", Least used: $LEASTUSED_ISO") #Returns column 2 value of RAWDATA_TMP3 E.G. 400, based on max column 3 value of RAWDATA_TMP3 - elif [[ "$ACCEPTED_TOTAL" -le 10 ]]; then #...we check the number of pictures. If it's equal or less than 10, we print nothing. - WHATIS_LEASTUSED_ISO=$(echo -n "") #Output string, nothing to say - fi - fi + # Least used ISO + # If more than one, then + if [[ "$LEASTUSED_ISO_CHECK" -ne 1 ]] + then + # Output string, nothing to say. + WHATIS_LEASTUSED_ISO=$(echo -n "") - if [[ "$MOSTUSED_ISO_CHECK" -ne 1 ]]; then #If more than one, then... - WHATIS_MOSTUSED_ISO=$(echo -n "") #Output string, nothing to say. - elif [[ "$MOSTUSED_ISO_CHECK" -eq 1 ]]; then #Else if it's one, then... - if [[ "$ACCEPTED_TOTAL" -gt 10 ]]; then #...we check the number of pictures. If it's greater than 10, then print the following string. - WHATIS_MOSTUSED_ISO=$(echo -n ", Most used: $MOSTUSED_ISO") #Returns column 2 value of RAWDATA_TMP3 E.G. 400, based on max column 3 value of RAWDATA_TMP3 - elif [[ "$ACCEPTED_TOTAL" -le 10 ]]; then #...we check the number of pictures. If it's equal or less than 10, we print nothing. - WHATIS_MOSTUSED_ISO=$(echo -n "") #Output string, nothing to say - fi + # Else if it's one, then + elif [[ "$LEASTUSED_ISO_CHECK" -eq 1 ]] + then + + # We check the number of pictures. If it's greater than 10, then print the following string. + if [[ "$ACCEPTED_TOTAL" -gt 10 ]] + then + + # Returns column 2 value of RAWDATA_TMP2 E.G. 400, based on max column 3 value of RAWDATA_TMP2 + WHATIS_LEASTUSED_ISO=$(echo -n ", Least used: $LEASTUSED_ISO") + + # We check the number of pictures. If it's equal or less than 10, we print nothing. + elif [[ "$ACCEPTED_TOTAL" -le 10 ]] + then + # Output string, nothing to say. + WHATIS_LEASTUSED_ISO=$(echo -n "") fi - -# Max ISO string: $WHATIS_REAL_MAX_ISO -# Min ISO string: $WHATIS_REAL_MIN_ISO -# Least used ISO string: $WHATIS_LEASTUSED_ISO -# Most used ISO string: $WHATIS_MOSTUSED_ISO + fi + + # Most used ISO + # If more than one, then + if [[ "$MOSTUSED_ISO_CHECK" -ne 1 ]] + then + # Output string, nothing to say. + WHATIS_MOSTUSED_ISO=$(echo -n "") + + # Else if it's one, then + elif [[ "$MOSTUSED_ISO_CHECK" -eq 1 ]] + then + + # We check the number of pictures. If it's greater than 10, then print the following string. + if [[ "$ACCEPTED_TOTAL" -gt 10 ]]; then + + # Returns column 2 value of RAWDATA_TMP2 E.G. 400, based on max column 3 value of RAWDATA_TMP2 + WHATIS_MOSTUSED_ISO=$(echo -n ", Most used: $MOSTUSED_ISO") + + elif [[ "$ACCEPTED_TOTAL" -le 10 ]] + then + # We check the number of pictures. If it's equal or less than 10, we print nothing. + WHATIS_MOSTUSED_ISO=$(echo -n "") #Output string, nothing to say + fi + fi ########################################################### -# ISO VALUES - SHIFT ISO RANGE VALUES FOR GNUPLOT - -# We shift down minimum ISO values to get a proper scale for gnuplot. Use "Less than" integer comparison because there can be ISO values such as 160, 250... - -#DO NOT CHANGE THE CHECK (ELIF EXECUTION) ORDER!! - - if [[ "$ISO_MIN_VALUE" -le 100 ]]; then #Less or equal than... - ISO_MIN_VALUE_GNU=0 #Just scaling down, not a true ISO value - elif [[ "$ISO_MIN_VALUE" -le 200 ]]; then - ISO_MIN_VALUE_GNU=100 - elif [[ "$ISO_MIN_VALUE" -le 400 ]]; then - ISO_MIN_VALUE_GNU=200 - elif [[ "$ISO_MIN_VALUE" -le 800 ]]; then - ISO_MIN_VALUE_GNU=400 - elif [[ "$ISO_MIN_VALUE" -le 1600 ]]; then - ISO_MIN_VALUE_GNU=800 - elif [[ "$ISO_MIN_VALUE" -le 3200 ]]; then - ISO_MIN_VALUE_GNU=1600 - elif [[ "$ISO_MIN_VALUE" -le 6400 ]]; then - ISO_MIN_VALUE_GNU=3200 - elif [[ "$ISO_MIN_VALUE" -le 8000 ]]; then - ISO_MIN_VALUE_GNU=6400 - fi - - if [[ "$ISO_MAX_VALUE" -ge 8000 ]]; then #Greater or equal than... - ISO_MAX_VALUE_GNU=12800 - elif [[ "$ISO_MAX_VALUE" -ge 6400 ]]; then - ISO_MAX_VALUE_GNU=8000 - elif [[ "$ISO_MAX_VALUE" -ge 3200 ]]; then - ISO_MAX_VALUE_GNU=6400 - elif [[ "$ISO_MAX_VALUE" -ge 1600 ]]; then - ISO_MAX_VALUE_GNU=3200 - elif [[ "$ISO_MAX_VALUE" -ge 800 ]]; then - ISO_MAX_VALUE_GNU=1600 - elif [[ "$ISO_MAX_VALUE" -ge 400 ]]; then - ISO_MAX_VALUE_GNU=800 - elif [[ "$ISO_MAX_VALUE" -ge 200 ]]; then - ISO_MAX_VALUE_GNU=400 - elif [[ "$ISO_MAX_VALUE" -ge 100 ]]; then - ISO_MAX_VALUE_GNU=200 - fi +# ISO values - shift ISO range values for GNUPlot + +# We shift down minimum ISO values to get a proper scale for gnuplot. +# Use "Less than" integer comparison because there can be ISO values such as 160, 250. + +# DO NOT CHANGE THE CHECK ORDER! + + if [[ "${ISO_MIN_VALUE}" -le 100 ]]; then + # Just scaling down, not a true ISO value + ISO_MIN_VALUE_GNU=0 + elif [[ "${ISO_MIN_VALUE}" -le 200 ]]; then + ISO_MIN_VALUE_GNU=100 + elif [[ "${ISO_MIN_VALUE}" -le 400 ]]; then + ISO_MIN_VALUE_GNU=200 + elif [[ "${ISO_MIN_VALUE}" -le 800 ]]; then + ISO_MIN_VALUE_GNU=400 + elif [[ "${ISO_MIN_VALUE}" -le 1600 ]]; then + ISO_MIN_VALUE_GNU=800 + elif [[ "${ISO_MIN_VALUE}" -le 3200 ]]; then + ISO_MIN_VALUE_GNU=1600 + elif [[ "${ISO_MIN_VALUE}" -le 6400 ]]; then + ISO_MIN_VALUE_GNU=3200 + elif [[ "${ISO_MIN_VALUE}" -le 8000 ]]; then + ISO_MIN_VALUE_GNU=6400 + fi + + if [[ "${ISO_MAX_VALUE}" -ge 8000 ]]; then + ISO_MAX_VALUE_GNU=12800 + elif [[ "${ISO_MAX_VALUE}" -ge 6400 ]]; then + ISO_MAX_VALUE_GNU=8000 + elif [[ "${ISO_MAX_VALUE}" -ge 3200 ]]; then + ISO_MAX_VALUE_GNU=6400 + elif [[ "${ISO_MAX_VALUE}" -ge 1600 ]]; then + ISO_MAX_VALUE_GNU=3200 + elif [[ "${ISO_MAX_VALUE}" -ge 800 ]]; then + ISO_MAX_VALUE_GNU=1600 + elif [[ "${ISO_MAX_VALUE}" -ge 400 ]]; then + ISO_MAX_VALUE_GNU=800 + elif [[ "${ISO_MAX_VALUE}" -ge 200 ]]; then + ISO_MAX_VALUE_GNU=400 + elif [[ "${ISO_MAX_VALUE}" -ge 100 ]]; then + ISO_MAX_VALUE_GNU=200 + fi ########################################################### -#Export all used ISO values - GET_ISO_VALUES=$(echo -n $(awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | awk '!seen[$0]++' |sort -n | tr '\n' ',' | sed -e 's/,[^,]*$//')) +# Export all used ISO values + GET_ISO_VALUES=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $4}' "${RAWDATA_TMP}" | \ + awk '!seen[$0]++' | \ + sort -n | \ + tr '\n' ',' | \ + sed -e 's/,[^,]*$//' + ) + ) - ISO_TICSRANGE=$(echo -n $ISO_MIN_VALUE_GNU,$GET_ISO_VALUES,$ISO_MAX_VALUE_GNU) + ISO_TICSRANGE=$(echo -n "${ISO_MIN_VALUE_GNU},${GET_ISO_VALUES,$ISO_MAX_VALUE_GNU}") ########################################################### fi -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## +########################################################### -# TEMPERATURE VALUES +# GNUPlot Temperature values -#Do the following stuff only, if we have checked for any ISO related stuff in the kdialog selection. -if [[ $SEL3 == true ]]; then +# Do the following, if we have selected temperature related items in kdialog selection window. +if [[ "${SEL3}" == true ]]; then -#################################################################################################################### +########################################################### -#RAWDATA_TMP2 -#Get percentages for temperature values +# RAWDATA_TMP3 +# Get percentages for temperature values -# OUTPUT template for RAWDATA_TMP2 is as follows: +# OUTPUT template for RAWDATA_TMP3 is as follows: # ,, @@ -972,70 +1256,108 @@ if [[ $SEL3 == true ]]; then # 1) Use awk to print field 2 from RAWDATA_TMP. Ignore the first row with FNR> 1 option. # 2) awk prints equivalent numbers as output. Count and merge them with "|sort -n | uniq -c" pipe # 3) Output results leading white spaces. For each line, delete them with sed. -# 4) use awk as pipe (awk starting with '{b[$2]=$1;sum=sum ...) to calculate percentage for the first column. First column has count number for each temperature value ("how many matches for XX temperature"). Temperature values are defined in column 2. Print the output to a new column 3. -# 5) In step 4, the output has too many decimals. As the output of this step is written to column 3, we use another awk pipe to strip too many decimals of the current column 3. To keep two first decimals, we use %.2f option. Print column 1 ($1) and 2 ($2) as they are, respectively. Add % mark and start a new line (\n) after each printf function. -# 6) Replace spaces with commas for the final output, and write the final output to RAWDATA_TMP2. +# 4) use awk as pipe (awk starting with '{b[$2]=$1;sum=sum ...) to calculate percentage +# for the first column. First column has count number for each temperature value +# ("how many matches for XX temperature"). Temperature values are defined in column 2. +# Print the output to a new column 3. +# 5) In step 4, the output has too many decimals. As the output of this step is written to column 3, +# we use another awk pipe to strip too many decimals of the current column 3. +# To keep two first decimals, we use %.2f option. Print column 1 ($1) and 2 ($2) as they are, +# respectively. Add % mark and start a new line (\n) after each printf function. +# 6) Replace spaces with commas for the final output, and write the final output to RAWDATA_TMP3. - awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" |sort -n | uniq -c | sed "s/^[ \t]*//" | awk '{b[$2]=$1;sum=sum+$1} END{for (i in b) print b[i],i,(b[i]/sum)*100}' | awk '{printf "%.0f %.0f %.2f'%'\n", $1,$2,$3}' | tr ' ' ',' > "${RAWDATA_TMP3}" + awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" | \ + sort -n | \ + uniq -c | \ + sed "s/^[ \t]*//" | \ + awk '{b[$2]=$1;sum=sum+$1} END{for (i in b) print b[i],i,(b[i]/sum)*100}' | \ + awk '{printf "%.0f %.0f %.2f'%'\n", $1,$2,$3}' | \ + tr ' ' ',' \ + > "${RAWDATA_TMP3}" -#################################################################################################################### +########################################################### -#Temperature min max values (actual values from the file) - TEMP_MIN=$(echo -n $(awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" | sort -n | head -1)) #Min Temp string - TEMP_MAX=$(echo -n $(awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" | sort -n | tail -1)) #Max Temp string + # Temperature min max values (actual values from the file) + TEMP_MIN=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" | sort -n | head -1 + ) + ) + TEMP_MAX=$( + echo -n $( + awk -F ',' 'FNR> 1 {print $3}' "${RAWDATA_TMP}" | sort -n | tail -1 + ) + ) + + # Format: (1*31)+(1*38)+(2*39) ... + TEMP_DIVIDEND=$( + echo -n $( + ($( + awk -F ',' '{print "("$1,$2")"}' "${RAWDATA_TMP3}" | sort -n | sed -e 's/ /*/g' | tr '\n' '+' | sed 's/+[^+]*$//' + )) + ) + ) + + # Just a basic average calculation + TEMP_AVERAGE=$(echo -e $(awk 'BEGIN {print "'"$TEMP_DIVIDEND"'"/"'"$ACCEPTED_TOTAL"'"}' | awk '{printf "%.2f", $1}')) -#Format: (1*31)+(1*38)+(2*39) ... - TEMP_DIVIDEND=$(echo -n $(($(awk -F ',' '{print "("$1,$2")"}' "${RAWDATA_TMP3}" | sort -n | sed -e 's/ /*/g' | tr '\n' '+' | sed 's/+[^+]*$//')))) +########################################################### -#Just a basic average calculation - TEMP_AVERAGE=$(echo -e $(awk 'BEGIN {print "'"$TEMP_DIVIDEND"'"/"'"$ACCEPTED_TOTAL"'"}' | awk '{printf "%.2f", $1}')) + # What is the maximum number of matches for a single temperature? + MAX_MATCH_FOR_TEMP=$( + echo -n $(awk -F ',' '{print $1}' "${RAWDATA_TMP3}" | sort -n | tail -1) + ) -############################################## + # Round temperature scale. + # Multiplier for temperature scale for plot 1. + TEMP_MULTP=2 -#What is the maximum number of matches for a single temperature? - MAX_MATCH_FOR_TEMP=$(echo -n $(awk -F ',' '{print $1}' "${RAWDATA_TMP3}" | sort -n | tail -1)) + # Temperature increment steps. For example, with value of 2, + # we get ...0, 2...10, 12, 14, 16...24... etc. + # TEMP_INCREMENT=2 -#Round temperature scale - TEMP_MULTP=2 #Multiplier for temperature scale for plot 1. (scale only!) + # We set minimum temperature to - 2, rounding down + UNROUNDED_MIN=$(echo -n $((${TEMP_MIN} - ${TEMP_MULTP}))) -#TEMP_INCREMENT=2 #Temperature increment steps. For example, with value of 2, we get ...0, 2...10, 12, 14, 16...24... etc. + # Basic layout for the following awk stuff: + # awk '{i=int($0/4);print((i==$0||$0>0)?i:i-1)*4}' + # Ref: https://stackoverflow.com/questions/33085008/bash-round-to-nearest-multiple-of-4 -# We set minimum temperature to - 2, rounding down -UNROUNDED_MIN=$(echo -n $(($TEMP_MIN - $TEMP_MULTP))) - -# BASE LAYOUT FOR THE FOLLOWING AWK STUFF: -# awk '{i=int($0/4);print((i==$0||$0>0)?i:i-1)*4}' -# https://stackoverflow.com/questions/33085008/bash-round-to-nearest-multiple-of-4 - MINVALUE_TEMP=$(echo -n $UNROUNDED_MIN | awk '{i=int("'"$UNROUNDED_MIN"'"/"'"$TEMP_MULTP"'");print((i=="'"$UNROUNDED_MIN"'"||"'"$UNROUNDED_MIN"'">0)?i:i-1)*"'"$TEMP_MULTP"'"}') + MINVALUE_TEMP=$( + echo -n $UNROUNDED_MIN | \ + awk '{i=int("'"$UNROUNDED_MIN"'"/"'"$TEMP_MULTP"'");print((i=="'"$UNROUNDED_MIN"'"||"'"$UNROUNDED_MIN"'">0)?i:i-1)*"'"$TEMP_MULTP"'"}' + ) -# We set maximum temperature to + 2, rounding up - UNROUNDED_MAX=$(echo -n $(($TEMP_MAX + $TEMP_MULTP))) - -# BASE LAYOUT FOR THE FOLLOWING AWK STUFF: -# awk '{print$0+(n-$0%n)%n}' -# https://stackoverflow.com/questions/33085008/bash-round-to-nearest-multiple-of-4 - MAXVALUE_TEMP=$(echo -n $UNROUNDED_MAX | awk '{print"'"$UNROUNDED_MAX"'"+("'"$TEMP_MULTP"'"-"'"$UNROUNDED_MAX"'"%"'"$TEMP_MULTP"'")%"'"$TEMP_MULTP"'"}') + # We set maximum temperature to + 2, rounding up + UNROUNDED_MAX=$(echo -n $((${TEMP_MAX} + ${TEMP_MULTP}))) + + # Basic layout for the following awk stuff: + # awk '{print$0+(n-$0%n)%n}' + # Ref: https://stackoverflow.com/questions/33085008/bash-round-to-nearest-multiple-of-4 + + MAXVALUE_TEMP=$( + echo -n $UNROUNDED_MAX | \ + awk '{print"'"$UNROUNDED_MAX"'"+("'"$TEMP_MULTP"'"-"'"$UNROUNDED_MAX"'"%"'"$TEMP_MULTP"'")%"'"$TEMP_MULTP"'"}' + ) fi -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## +########################################################### -# SELECTION 3 - TEMPERATURES & ISOS +# GNUPlot selection 3 - Temperatures & ISOs -######################################################################################## +########################################################### # PLOT 1 (Images & Temperatures & ISOS) -if [[ $SEL3 == true ]]; then +if [[ "${SEL3}" == true ]]; then -#GNUPLOT, ACTUAL PROGRAM EXECUTION STARTS HERE: +# GNUPlot program execution starts here. gnuplot < 1 {print $1}' "${RAWDATA_TMP}" |sort -n |tr ' ' '\n' | sort -n | tr '\n' ',' | sed 's/,*\r*$//')) -#DEPRECATED - -# This syntax is used for md5sums check as well... - -####################################################################### - -#(For temperatures?) Deprecated: -#awk -F ',' 'FNR> 1 {print $2}' "${RAWDATA_TMP}" |sort -n | uniq -c | sed "s/^[ \t]*//" | tr ' ' ',' > "${RAWDATA_TMP2}" - -#Add some ISO and temperature statistics - -#paste <(echo "${ISO_ALL_COUNT}") <(echo "${TEMP_ALL_COUNT}") -d , > "${RAWDATA_TMP2}" - -#RAWDATA 2 FILE DATA ORDER AS FOLLOWS: - -#TEMPERATURE_COUNTS,TEMPERATURE_VALUE,ISO_USAGE_COUNTS,ISO_SPEED_VALUES - -# |awk '{print "("$0")"}' --brackets - -#ARG1=$1 -#ARG2=$2 -#ARG3=$3 -#ARG4=$4 -#ARG5=$5 -#ARG6=$6 - -#gnuplot --persist -e "TITLE='${GNUPLOT_TITLE}'; RAWFILE='${RAWDATA_TMP}'; WINDOWTITLE='${GNUPLOT_MAINWINDOW_TITLE}'; ISO_MIN='${ISO_MIN_VALUE}'; ISO_MAX='${ISO_MAX_VALUE}'; ISO_VALUES='${GET_ISO_VALUES}';" $GNUPLOT_SCRIPT #ARG3='${ARG3}'; ARG4='${ARG4}'; ARG5='${ARG5}'; ARG6='${ARG6}'" $GNUPLOT_FILE - -# Max ISO string: $WHATIS_REAL_MAX_ISO -# Min ISO string: $WHATIS_REAL_MIN_ISO -# Least used ISO string: $WHATIS_LEASTUSED_ISO -# Most used ISO string: $WHATIS_MOSTUSED_ISO - +exit 0 diff --git a/4_scripts/imagetools_02_dualiso.sh b/4_scripts/imagetools_02_dualiso.sh index acc70ec..a8dc16b 100644 --- a/4_scripts/imagetools_02_dualiso.sh +++ b/4_scripts/imagetools_02_dualiso.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Batch convert multiple Magic Lantern dual ISO image files on Linux -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,155 +19,150 @@ # ############################################### -# NOTE: This script REQUIRES a patched cr2hdr tool with '--dry-run' parameter support!! -# Required patch file is provided in the same repository with this script - -#Brackets and quotation marks in variables prevent errors occuring if file paths with spaces is used. - -################################################################################################ - -# File system check -# We don't allow writing to SD card. - -#Sed is here to remove any trailing spaces and crap like blank lines -INPUT_FILESYSTEM=$(df -h "${1}" | awk -F ' ' 'FNR> 1 {print $1}' | grep -i -E "/dev/sd?|/dev/hd?|?rewritefs|?tmpfs|/dev/nvme?" | sed '/^\s*$/d' | wc -l) - -if [[ "${INPUT_FILESYSTEM}" -eq 0 ]]; then #if input file (first file printed in bash) filesystem does not start with /dev/sdX - kdialog --error "Image(s) are in a SD Card. Please move them your local or external storage and try again." - exit -fi - -################################################################################################ - -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... +# We get the directory just from the first filename. INPUT_DIR=$(dirname "${1}") DIR_BASENAME=$(echo "${INPUT_DIR}" | rev | cut -d/ -f 1 | rev) -echo "DEBUG: Input dir is $INPUT_DIR" - -mkdir -p "${INPUT_DIR}"/converted_dual_iso - -echo "DEBUG: 'converted_dual_iso' directory created" +mkdir -p "${INPUT_DIR}/converted_dual_iso" ############################################################################################ -####PROGRESSBAR STUFF - BEGIN -LABELTEXT='Processing RAW images...' +# PROGRESSBAR CODE - BEGIN + +LABELTEXT="Processing RAW images..." numargs=$# # Number of all files -tics=100 # Percentage tics -inc=0 # Current file number -mltp=1000 # Percentage multiplier for bash +tics=100 # Percentage tics +inc=0 # Current file number +mltp=1000 # Percentage multiplier for bash -dbusRef=$(kdialog --title "Dual ISO (folder: ${DIR_BASENAME})" --progressbar "$LABELTEXT" $tics) +dbusRef=$(kdialog --title "Dual ISO (folder: ${DIR_BASENAME})" --progressbar "${LABELTEXT}" "${tics}") qdbus $dbusRef showCancelButton true -####PROGRESSBAR STUFF - END +# PROGRESSBAR CODE - END -while [[ $# -gt 0 ]] && [[ $(qdbus $dbusRef wasCancelled) == "false" ]]; do +while \ + [[ $# -gt 0 ]] && \ + [[ $(qdbus $dbusRef wasCancelled) == "false" ]] +do - INPUT="${1}" #Input file path, full path like: /home/myhome/IMG_4021.CR2 - OLDFILE_CR2=$(basename "${INPUT}") #Output as IMG_4021.CR2 (for example) + INPUT="${1}" + OLDFILE_CR2=$(basename "${INPUT}") - # Once we do this, it's very clear which kind of CR2 file we're talking about here. - NEWFILE_CR2=$(basename "${INPUT}" | sed 's/\.\w*$/_dualiso.CR2/') + # Once we do this, it's very clear which kind of CR2 file we're talking about here. + NEWFILE_CR2=$(basename "${INPUT}" | sed 's/\.\w*$/_dualiso.CR2/') - # Converted Dual ISO file. - NEWFILE_DNG=$(basename "${INPUT}" | sed 's/\.\w*$/_dualiso.DNG/') + # Converted Dual ISO file. + NEWFILE_DNG=$(basename "${INPUT}" | sed 's/\.\w*$/_dualiso.DNG/') - #If converted Dual ISO exists already, we skip the conversion process. This passes only if the file doesn't exist. - if [[ ! -e "${INPUT_DIR}"/converted_dual_iso/"${NEWFILE_DNG}" ]]; then + # If converted Dual ISO exists already, we skip the conversion process. + # This test passes only if the file doesn't exist. + if [[ ! -e "${INPUT_DIR}/converted_dual_iso/${NEWFILE_DNG}" ]] + then - if [[ $(cr2hdr --dry-run "${INPUT}" | grep "Interlaced ISO detected" | wc -l) == 1 ]]; then # Test an input file for Dual ISO. + # Test an input file for Dual ISO. + if [[ $(cr2hdr --dry-run "${INPUT}" | grep "Interlaced ISO detected" | wc -l) -eq 1 ]] + then - echo "Interlaced ISO detected: ${OLDFILE_CR2}" + echo "Interlaced ISO detected: ${OLDFILE_CR2}" - #Rename detected dual ISO CR2 file with a proper prefix (so that we can distinguish Dual ISO images from "normal" CR2 files) - mv "${INPUT_DIR}"/"${OLDFILE_CR2}" "${INPUT_DIR}"/"${NEWFILE_CR2}" + # Rename detected dual ISO CR2 file with a proper prefix + # (so that we can distinguish Dual ISO images from "normal" CR2 files) + mv "${INPUT_DIR}/${OLDFILE_CR2}" "${INPUT_DIR}/${NEWFILE_CR2}" - #Input we will use from this point is the renamed file, so we set INPUT variable to point to the renamed file. - INPUT="${INPUT_DIR}"/"${NEWFILE_CR2}" + # Input we will use from this point is the renamed file, + # so we set INPUT variable to point to the renamed file. + INPUT="${INPUT_DIR}/${NEWFILE_CR2}" - cr2hdr --process "${INPUT}" # Process a valid input file. + # Process a valid input file. + cr2hdr --process "${INPUT}" - mv "${INPUT_DIR}"/"${NEWFILE_DNG}" "${INPUT_DIR}"/converted_dual_iso/ # Move converted Dual ISO. + # Move converted dual iso file. + mv "${INPUT_DIR}/${NEWFILE_DNG}" "${INPUT_DIR}/converted_dual_iso/" - # Add Subject=Dual-ISO tag for every Dual ISO CR2 file. - echo "Writing new EXIF/XMP tag Subject: Dual ISO CR2" - exiftool -xmp:subject='Dual ISO CR2' "${INPUT_DIR}"/"${NEWFILE_CR2}" -overwrite_original + # Add Subject=Dual-ISO tag for every Dual ISO CR2 file. + echo "Writing new EXIF/XMP tag Subject: Dual ISO CR2" + exiftool -xmp:subject="Dual ISO CR2" "${INPUT_DIR}/${NEWFILE_CR2}" -overwrite_original - fi fi + fi ############################################## - ####PROGRESSBAR STUFF - BEGIN + # PROGRESSBAR CODE - BEGIN let inc++ - #Percentage needs to be calculated like this due to bash rounding limitations... - PERCENT_VALUE=$((($mltp*$tics)/(200*$numargs/$inc % 2 + $mltp*$numargs/$inc))) - #Output: 20, 40, 59, 80, 100 etc. + # Percentage needs to be calculated like this due to bash rounding limitations. + PERCENT_VALUE=$(((${mltp}*${tics})/(200*${numargs}/${inc} % 2 + ${mltp}*${numargs}/${inc}))) + # Output: 20, 40, 59, 80, 100 etc. + + qdbus $dbusRef Set "" "value" "${PERCENT_VALUE}"; + qdbus $dbusRef setLabelText "$LABELTEXT (${inc}/${numargs})"; - qdbus $dbusRef Set "" "value" $PERCENT_VALUE; - qdbus $dbusRef setLabelText "$LABELTEXT ($inc/$numargs)"; - ####PROGRESSBAR STUFF - END + # PROGRESSBAR CODE - END - shift #Process next CR2/DNG file... + # Move to the next file. + shift done ############################################## -#Close processing window if cancelled event has been triggered. +# Close processing window if cancelled event has been triggered. + +# PROGRESSBAR CODE - BEGIN -####PROGRESSBAR STUFF - BEGIN # If the process was cancelled, remove tmp file and exit the script. -if [[ ! $(qdbus $dbusRef wasCancelled) == "false" ]]; then - exit +if [[ ! $(qdbus $dbusRef wasCancelled) == "false" ]] +then + exit 0 fi -############################################## - -#Close processing window if not cancelled and processing finished. +# Close processing window if not cancelled and processing finished. qdbus $dbusRef close -####PROGRESSBAR STUFF - END + +# PROGRESSBAR CODE - END ############################################## -if [ $(pgrep -x 'cr2hdr' | wc -l) == 0 ]; then - notify-send 'Dual ISO' -i image-x-krita 'Conversion done!' +if [[ $(pgrep -x 'cr2hdr' | wc -l) == 0 ]] +then + notify-send 'Dual ISO' -i image-x-krita 'Conversion done!' fi ############################################################################################ QUESTCOUNT=0 #Ask this question only once -#Dual ISO (Subject only defined in converted Dual ISO DNG images) -for i in $(find "${INPUT_DIR}" -maxdepth 1 -type f -iname "*.DNG"); do - if [[ ! -z $(echo -n $i) ]] && [[ $(exiftool $i |grep --max-count=1 "Subject" | sed -e 's/.*: //g') == *"Dual-ISO"* ]] ; then - - if [[ $QUESTCOUNT == 0 ]]; then - QUESTION=$(kdialog --yesno "More Dual ISO files detected in '$(echo ${INPUT_DIR} | rev | cut -d/ -f1 | rev)' main folder. Do you want to move these files into 'converted_dual_iso' folder?";) - echo $QUESTION - MOVEALL=true - let QUESTCOUNT++ - else - MOVEALL=false - fi - - if [[ $MOVEALL == true ]]; then - mv $i "${INPUT_DIR}"/converted_dual_iso/ - echo "DEBUG: all detected Dual ISO images moved to 'converted_dual_iso' folder" - fi +# Dual ISO (Subject only defined in converted Dual ISO DNG images) +for i in $(find "${INPUT_DIR}" -maxdepth 1 -type f -iname "*.DNG") +do + if \ + [[ ! -z $(echo -n "${i}") ]] && \ + [[ $(exiftool "${i}" |grep --max-count=1 "Subject" | sed -e 's/.*: //g') == *"Dual-ISO"* ]] + then + + if [[ "${QUESTCOUNT}" -eq 0 ]]; then + QUESTION=$(kdialog --yesno "More Dual ISO files detected in '$(echo ${INPUT_DIR} | rev | cut -d/ -f1 | rev)' main folder. Do you want to move these files into 'converted_dual_iso' folder?";) + echo "${QUESTION}" + MOVEALL=true + let QUESTCOUNT++ + else + MOVEALL=false + fi + if [[ "${MOVEALL}" == true ]]; then + mv "${i}" "${INPUT_DIR}/converted_dual_iso/" + echo "DEBUG: all detected Dual ISO images moved to 'converted_dual_iso' folder" fi + fi done ############################################################################################ -#If there are no files converted, we delete converted_dual_iso folder -if [[ $(ls "${INPUT_DIR}"/converted_dual_iso | wc -l) == 0 ]]; then - rm -Rf "${INPUT_DIR}"/converted_dual_iso - echo "DEBUG: 'converted_dual_iso' empty, so deleted" +# If there are no files converted, we delete converted_dual_iso folder +if [[ $(ls "${INPUT_DIR}/converted_dual_iso" | wc -l) -eq 0 ]] +then + rm -Rf "${INPUT_DIR}/converted_dual_iso" fi -exit +exit 0 diff --git a/4_scripts/imagetools_03_raw_resolution-baseline.sh b/4_scripts/imagetools_03_raw_resolution-baseline.sh index 60bce66..cfe1d11 100644 --- a/4_scripts/imagetools_03_raw_resolution-baseline.sh +++ b/4_scripts/imagetools_03_raw_resolution-baseline.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Add CR2 tags: Baseline, Subject (to distinguish Single & Dual ISOs) -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,501 +19,502 @@ # ############################################### -# File system check -# We don't allow writing to SD card. - -#Sed is here to remove any trailing spaces and crap like blank lines -INPUT_FILESYSTEM=$(df -h "${1}" | awk -F ' ' 'FNR> 1 {print $1}' | grep -i -E "/dev/sd?|/dev/hd?|?rewritefs|?tmpfs|/dev/nvme?" | sed '/^\s*$/d' | wc -l) - -if [[ "${INPUT_FILESYSTEM}" -eq 0 ]]; then #if input file (first file printed in bash) filesystem does not start with /dev/sdX - kdialog --error "Image(s) are in a SD Card. Please move them your local or external storage and try again." - exit -fi - -################################################################################################ - - -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... +# We get the directory just from the first filename. INPUT_DIR=$(dirname "${1}") DIR_BASENAME=$(echo "${INPUT_DIR}" | rev | cut -d/ -f 1 | rev) -#Camera resolution in pixels (absolute limit, we can't exceed these pixel values!) +# Camera resolution in pixels (absolute limit, we can't exceed these pixel values!) C5DMK3_WIDTH=5796 C5DMK3_HEIGHT=3870 -# In a case or emergency (can't open a picture etc), revert this values to 5760 x 3840 +# In a case or emergency (can't open a picture etc), revert these values to 5760 x 3840. ################################################################################################ -####PROGRESSBAR STUFF - BEGIN -LABELTEXT='Processing RAW images...' +# PROGRESSBAR CODE - BEGIN + +LABELTEXT="Processing RAW images..." numargs=$# # Number of all files -tics=100 # Percentage tics -inc=0 # Current file number -mltp=1000 # Percentage multiplier for bash +tics=100 # Percentage tics +inc=0 # Current file number +mltp=1000 # Percentage multiplier for bash + +dbusRef=$( + kdialog \ + --title "EXIF Tags (folder: ${DIR_BASENAME})" \ + --progressbar "$LABELTEXT" "${tics}" +) -dbusRef=$(kdialog --title "EXIF Tags (folder: ${DIR_BASENAME})" --progressbar "$LABELTEXT" $tics) qdbus $dbusRef showCancelButton true -####PROGRESSBAR STUFF - END +# PROGRESSBAR CODE - END -while [[ $# -gt 0 ]] && [[ $(qdbus $dbusRef wasCancelled) == "false" ]]; do +while \ + [[ $# -gt 0 ]] && \ + [[ $(qdbus $dbusRef wasCancelled) == "false" ]] +do ################################################################ -# Values that change during the while loop (differ from file to file) - - INPUT="${1}" + # Values that change during the while loop (differ from file to file) - INPUT_BASENAME=$(basename "${INPUT}" | cut -f 1 -d '.') - INPUT_EXTENSION=$(echo $(basename "${INPUT}" | cut -f 2 -d '.' | sed '/^\s*$/d')) #Get the correct file extension for an input file (so the new one will use the same) + INPUT="${1}" - SUBJECT=$(exiftool "${INPUT}" | grep "Subject") - SUBJECT_SINGLEISO=$(exiftool "${INPUT}" | grep "Subject" | grep "Single ISO") - SUBJECT_DUALISO=$(exiftool "${INPUT}" | grep "Subject" | grep "Dual ISO") + INPUT_BASENAME=$(basename "${INPUT}" | cut -f 1 -d '.') - #This is just for compatibility - SUBJECT_DUALISO_OLD=$(exiftool "${INPUT}" | grep "Subject" | grep "Dual-ISO") + # Get the correct file extension for an input file, to be used for the new file. + INPUT_EXTENSION=$(echo $(basename "${INPUT}" | cut -f 2 -d '.' | sed -e '/^\s*$/d' -e 's/\(.*\)/\U\1/')) - BASELINES=$(exiftool "${INPUT}" | grep "Baseline Exposure") + SUBJECT=$(exiftool "${INPUT}" | grep "Subject") + SUBJECT_SINGLEISO=$(exiftool "${INPUT}" | grep "Subject" | grep "Single ISO") + SUBJECT_DUALISO=$(exiftool "${INPUT}" | grep "Subject" | grep "Dual ISO") - C5DMK3_CHECK=$(exiftool "${INPUT}" |grep -i "5D Mark III" |wc -l) - CROPHEIGHT_CHECK_VALUE=$(echo -n $(exiftool "${INPUT}" |grep -i "Cropped Image Height" | sed 's/[^0-9]*//g')) + # This is just for compatibility. + SUBJECT_DUALISO_OLD=$(exiftool "${INPUT}" | grep "Subject" | grep "Dual-ISO") - ISO_VALUE=$(echo -n $(exiftool "${INPUT}" | grep "Recommended Exposure Index" | grep -v "Sensitivity Type" | sed 's/[^0-9]*//g')) + BASELINES=$(exiftool "${INPUT}" | grep "Baseline Exposure") -################################################################ - -# FIRST CHECK FOR INDIVIDUAL FILE - - ################################ - # CR2 FILES - # - # Input file is CR2 or cr2 - - if [[ "${INPUT_EXTENSION}" == "CR2" ]] || [[ "${INPUT_EXTENSION}" == "cr2" ]]; then + C5DMK3_CHECK=$(exiftool "${INPUT}" |grep -i "5D Mark III" |wc -l) + CROPHEIGHT_CHECK_VALUE=$(echo -n $(exiftool "${INPUT}" |grep -i "Cropped Image Height" | sed 's/[^0-9]*//g')) - ########### - # Dual ISO - unprocessed CR2 (NOTE: THIS CHECK IS SLOW) - - if [[ $(cr2hdr --dry-run "${INPUT}" | grep "Interlaced ISO detected" | wc -l) == 1 ]]; then # Test an input file for Dual ISO. - - echo "${INPUT_BASENAME}: Dual ISO CR2 image. Skipping." - IS_SINGLE_CR2=false + ISO_VALUE=$(echo -n $(exiftool "${INPUT}" | grep "Recommended Exposure Index" | grep -v "Sensitivity Type" | sed 's/[^0-9]*//g')) - else - IS_SINGLE_CR2=true - fi - - if [[ $IS_SINGLE_CR2 == true ]]; then - ########### - # Single ISO - CR2 - - # Subject Tag - # - if [[ $(echo "${SUBJECT}" | sed '/^\s*$/d' | wc -l) == 0 ]]; then - - echo "${INPUT_BASENAME}: Add a new Subject tag." - SUBJECT_TAG='Single ISO CR2' - PROCESS_SUBJECT=true - - else - - echo "${INPUT_BASENAME} is a Single ISO image and has a Subject tag already." - PROCESS_SUBJECT=false - - fi - - # Baseline Tags - # - if [[ $(echo "${BASELINES}" | sed '/^\s*$/d' | wc -l) == 0 ]]; then - - echo "${INPUT_BASENAME}: Add new Baseline tags." - PROCESS_BASELINE=true - - else - - echo "${INPUT_BASENAME}: Baseline tags exist. Skipping." - PROCESS_BASELINE=false +################################################################ - fi + # FIRST CHECK FOR INDIVIDUAL FILE - if [[ $CROPHEIGHT_CHECK_VALUE != $C5DMK3_HEIGHT ]]; then + ################################ + # CR2 FILES + # + # Input file is CR2 or cr2 - echo "${INPUT_BASENAME}: New resolution, $C5DMK3_WIDTH x $C5DMK3_HEIGHT." - PROCESS_SIZE=true + if [[ "${INPUT_EXTENSION}" == "CR2" ]] + then - else + # Dual ISO - unprocessed CR2 (NOTE: THIS CHECK IS SLOW) + # Test an input file for Dual ISO. + if [[ $(cr2hdr --dry-run "${INPUT}" | grep "Interlaced ISO detected" | wc -l) -eq 1 ]] + then + echo "${INPUT_BASENAME}: Dual ISO CR2 image. Skipping." + IS_SINGLE_CR2=false + else + IS_SINGLE_CR2=true + fi - echo "${INPUT_BASENAME}: Has correct resolution already." - PROCESS_SIZE=false + # Single ISO - CR2 + if [[ "${IS_SINGLE_CR2}" == true ]] + then + + # Subject Tag + if [[ $(echo "${SUBJECT}" | sed '/^\s*$/d' | wc -l) -eq 0 ]] + then + echo "${INPUT_BASENAME}: Add a new Subject tag." + SUBJECT_TAG="Single ISO CR2" + PROCESS_SUBJECT=true + else + echo "${INPUT_BASENAME} is a Single ISO image and has a Subject tag already." + PROCESS_SUBJECT=false + fi + + # Baseline Tags + if [[ $(echo "${BASELINES}" | sed '/^\s*$/d' | wc -l) -eq 0 ]] + then + echo "${INPUT_BASENAME}: Add new Baseline tags." + PROCESS_BASELINE=true + else + echo "${INPUT_BASENAME}: Baseline tags exist. Skipping." + PROCESS_BASELINE=false + fi + + # Image size + if [[ "${CROPHEIGHT_CHECK_VALUE}" -ne "${C5DMK3_HEIGHT}" ]] + then + echo "${INPUT_BASENAME}: New resolution, ${C5DMK3_WIDTH} x ${C5DMK3_HEIGHT}." + PROCESS_SIZE=true + else + echo "${INPUT_BASENAME}: Has correct resolution already." + PROCESS_SIZE=false + fi - fi - fi + fi - ################################ - # DNG FILES - # - # Input file is DNG or dng + ################################ + # DNG FILES + # + # Input file is DNG or dng - elif [[ "${INPUT_EXTENSION}" == "DNG" ]] || [[ "${INPUT_EXTENSION}" == "dng" ]]; then + elif [[ "${INPUT_EXTENSION}" == "DNG" ]] + then ########### - # DNG with missing Subject Tag + # DNG with missing Subject Tag - if [[ $(echo "${SUBJECT}" | sed '/^\s*$/d' | wc -l) == 0 ]]; then + if [[ $(echo "${SUBJECT}" | sed '/^\s*$/d' | wc -l) -eq 0 ]] + then - echo "${INPUT_BASENAME}: Add a new Subject tag." - SUBJECT_TAG='Single ISO CR2' - PROCESS_SUBJECT=true + echo "${INPUT_BASENAME}: Add a new Subject tag." + SUBJECT_TAG="Single ISO CR2" + PROCESS_SUBJECT=true - #We don't update size tags. See reason below. - #Baseline tags have already been written by Adobe converter. - PROCESS_SIZE=false - PROCESS_BASELINE=false + # We don't update size tags. See reason below. + # Baseline tags have already been written by Adobe converter. + PROCESS_SIZE=false + PROCESS_BASELINE=false ########### - # DNG with updated Subject Tag + # DNG with updated Subject Tag - elif [[ $(echo "${SUBJECT_SINGLEISO}" | sed '/^\s*$/d' | wc -l) != 0 ]]; then + elif [[ $(echo "${SUBJECT_SINGLEISO}" | sed '/^\s*$/d' | wc -l) -ne 0 ]] + then + echo "${INPUT_BASENAME}: Subject tag exists. Skipping." + PROCESS_SUBJECT=false - echo "${INPUT_BASENAME}: Subject tag exists. Skipping." - PROCESS_SUBJECT=false - - #We don't update size tags. See reason below. - #Baseline tags have already been written by Adobe converter. - PROCESS_SIZE=false - PROCESS_BASELINE=false + # We don't update size tags. See reason below. + # Baseline tags have already been written by Adobe converter. + PROCESS_SIZE=false + PROCESS_BASELINE=false ########### - # New Dual ISO - DNG + # New Dual ISO - DNG - elif [[ $(echo "${SUBJECT_DUALISO}" | sed '/^\s*$/d' | wc -l) != 0 ]]; then + elif [[ $(echo "${SUBJECT_DUALISO}" | sed '/^\s*$/d' | wc -l) -ne 0 ]] + then - echo "${INPUT_BASENAME}: Dual ISO image with proper tags. Skipping." + echo "${INPUT_BASENAME}: Dual ISO image with proper tags. Skipping." - # Tags have already be written by updated cr2hdr. - PROCESS_SUBJECT=false - PROCESS_SIZE=false - PROCESS_BASELINE=false + # Tags have already be written by updated cr2hdr. + PROCESS_SUBJECT=false + PROCESS_SIZE=false + PROCESS_BASELINE=false ########### - # Old Dual ISO - DNG - - elif [[ $(echo "${SUBJECT_DUALISO_OLD}" | sed '/^\s*$/d' | wc -l) != 0 ]]; then + # Old Dual ISO - DNG - echo "${INPUT_BASENAME}: old Dual ISO image. Update Subject & Baseline tags." - exiftool -xmp:subject= "${INPUT}" -overwrite_original #Clear old tag + elif [[ $(echo "${SUBJECT_DUALISO_OLD}" | sed '/^\s*$/d' | wc -l) -ne 0 ]] + then - PROCESS_SUBJECT=true - SUBJECT_TAG='Dual ISO DNG' + echo "${INPUT_BASENAME}: old Dual ISO image. Update Subject & Baseline tags." + exiftool -xmp:subject= "${INPUT}" -overwrite_original #Clear old tag - PROCESS_SIZE=false - PROCESS_BASELINE=true #Old dual ISOs don't have this one. + PROCESS_SUBJECT=true + SUBJECT_TAG="Dual ISO DNG" - ################################ + PROCESS_SIZE=false - fi + # Old dual ISOs don't have this one. + PROCESS_BASELINE=true fi + fi ################################################################ -# Suffix for the new file name - -# U = Uncropped (PROCESS_SIZE) -# S = Subject Tag (PROCESS_SUBJECT) -# B = Baseline Tags (PROCESS_BASELINE) - - # false, false, false - if [[ $PROCESS_SUBJECT == false ]] && [[ $PROCESS_BASELINE == false ]] && [[ $PROCESS_SIZE == false ]]; then - - #WRITENEWFILE=false - SUFFIX= - - # true, true, true - elif [[ $PROCESS_SUBJECT == true ]] && [[ $PROCESS_BASELINE == true ]] && [[ $PROCESS_SIZE == true ]]; then - #WRITENEWFILE=true - SUFFIX=_USB + # Suffix for the new file name + + # U = Uncropped (PROCESS_SIZE) + # S = Subject Tag (PROCESS_SUBJECT) + # B = Baseline Tags (PROCESS_BASELINE) + + # false, false, false + if \ + [[ "${PROCESS_SUBJECT}" == false ]] && \ + [[ "${PROCESS_BASELINE}" == false ]] && \ + [[ "${PROCESS_SIZE}" == false ]] + then + SUFFIX= + + # true, true, true + elif \ + [[ "${PROCESS_SUBJECT}" == true ]] && \ + [[ "${PROCESS_BASELINE}" == true ]] && \ + [[ "${PROCESS_SIZE}" == true ]] + then + SUFFIX=_USB + + # true, true, false + elif \ + [[ "${PROCESS_SUBJECT}" == true ]] && \ + [[ "${PROCESS_BASELINE}" == true ]] && \ + [[ "${PROCESS_SIZE}" == false ]] + then + SUFFIX=_SB + + # false, true, true + elif \ + [[ "${PROCESS_SUBJECT}" == false ]] && \ + [[ "${PROCESS_BASELINE}" == true ]] && \ + [[ "${PROCESS_SIZE}" == true ]] + then + SUFFIX=_UB + + # true, false, true + elif \ + [[ "${PROCESS_SUBJECT}" == true ]] && \ + [[ "${PROCESS_BASELINE}" == false ]] && \ + [[ "${PROCESS_SIZE}" == true ]] + then + SUFFIX=_US + + # false, true, false + elif \ + [[ "${PROCESS_SUBJECT}" == false ]] && \ + [[ "${PROCESS_BASELINE}" == true ]] && \ + [[ "${PROCESS_SIZE}" == false ]] + then + SUFFIX=_B + + # true, false, false + elif \ + [[ "${PROCESS_SUBJECT}" == true ]] && \ + [[ "${PROCESS_BASELINE}" == false ]] && \ + [[ "${PROCESS_SIZE}" == false ]] + then + SUFFIX=_S + + # false, false, true + elif \ + [[ "${PROCESS_SUBJECT}" == false ]] && \ + [[ "${PROCESS_BASELINE}" == false ]] && \ + [[ "${PROCESS_SIZE}" == true ]] + then + SUFFIX=_U + + fi - # true, true, false - elif [[ $PROCESS_SUBJECT == true ]] && [[ $PROCESS_BASELINE == true ]] && [[ $PROCESS_SIZE == false ]]; then - - #WRITENEWFILE=true - SUFFIX=_SB +################################################################ - # false, true, true - elif [[ $PROCESS_SUBJECT == false ]] && [[ $PROCESS_BASELINE == true ]] && [[ $PROCESS_SIZE == true ]]; then + # RESOLUTION TAGS MANIPULATION - non-Dual ISO CR2 only - #WRITENEWFILE=true - SUFFIX=_UB + # 1) Check if Size process variable is true + # 2) If question "Do we have a 5D Mark string in the file?" does not + # return 0, E.G. the camera model is 5D Mark 3. - # true, false, true - elif [[ $PROCESS_SUBJECT == true ]] && [[ $PROCESS_BASELINE == false ]] && [[ $PROCESS_SIZE == true ]]; then + if \ + [[ "${PROCESS_SIZE}" == true ]] && \ + [[ "${C5DMK3_CHECK}" -ne 0 ]] + then - #WRITENEWFILE=true - SUFFIX=_US + # According to file analysis done with CR2 and DNG files, + # Cropped & Exif Width/Height tags should be written into CR2 files. + # CR2 files require only Cropped Image Height/Width values, + # but if we convert an uncropped CR2 file into DNG, we get wrong picture size. + # To correct this for DNG files, Exif Height/Witdh values are required, too. - # false, true, false - elif [[ $PROCESS_SUBJECT == false ]] && [[ $PROCESS_BASELINE == true ]] && [[ $PROCESS_SIZE == false ]]; then + # WHY WE DON'T CHANGE EXIF TAGS FOR DNG FILES HERE? + # We can't uncrop DNG file procuded by Adobe algorithms (Adobe DNG Converter or raw2dng). + # This is because Adobe's method writes a tag name "Default Crop Size" which can't be + # changed afterwards without rendering the image unusable in Adobe Camera Raw software. + # + # My hypothesis about the issue is as follows: + # Camera Raw may do some comparison check between dimensions defined in "Default Crop Size" + # and some of the exif-unwritable Width/Height values. If there's a mismatch, the file can't + # be opened in Adobe Camera Raw software. An image that can't be opened in ACR, is still + # usable in some other RAW processing software (because their check for EXIF value tags differ). + # + # Every time I edited "Default Crop Size" value in DNG file, ACR gave me an error about + # unsupported or corrupted file. - #WRITENEWFILE=true - SUFFIX=_B + exiftool \ + -CroppedImageWidth="${C5DMK3_WIDTH}" \ + -CroppedImageHeight="${C5DMK3_HEIGHT}" \ + -ExifImageWidth="${C5DMK3_WIDTH}" \ + -ExifImageHeight="${C5DMK3_HEIGHT}" \ + "${INPUT}" \ + -overwrite_original - # true, false, false - elif [[ $PROCESS_SUBJECT == true ]] && [[ $PROCESS_BASELINE == false ]] && [[ $PROCESS_SIZE == false ]]; then + echo -e "${INPUT_BASENAME}: Image dimensions updated to ${C5DMK3_WIDTH} x ${C5DMK3_HEIGHT}.\n" - #WRITENEWFILE=true - SUFFIX=_S + # Other useful Height/Width tags are as follows: - # false, false, true - elif [[ $PROCESS_SUBJECT == false ]] && [[ $PROCESS_BASELINE == false ]] && [[ $PROCESS_SIZE == true ]]; then + # -OriginalImageWidth + # -OriginalImageHeight - #WRITENEWFILE=true - SUFFIX=_U + # -RelatedImageWidth + # -RelatedImageHeight - fi + fi ################################################################ - # RESOLUTION TAGS MANIPULATION - non-Dual ISO CR2 only - - # 1) Check if Size process variable is true - # 2) If question "Do we have a 5D Mark string in the file?" does not return 0, E.G. the camera model is 5D Mark 3... - # And if all previous checks pass, then we do our tricks here. - - if [[ $PROCESS_SIZE == true ]] && [[ $C5DMK3_CHECK != 0 ]]; then + # BASELINE TAGS ADDITION - non-Dual ISO CR2 only - # According to file analysis done with CR2 and DNG files, Cropped & Exif Width/Height tags should be written in a CR2 files. - # CR2 files require only Cropped Image Height/Width values, but if we convert an uncropped CR2 file into DNG, we get wrong picture size. - # To correct this for DNG files, Exif Height/Witdh values are required, too. + # 1) We can request that PROCESS variable returns true though it's set to + # false in Dual ISO CR2 images too. These CR2 images have Baseline values + # already added into EXIF metadata since 01/07/2017 (cr2hdr code patched). - # WHY WE DON'T CHANGE EXIF TAGS FOR DNG FILES HERE? - # We can't uncrop DNG file procuded by Adobe algorithms (Adobe DNG Converter or raw2dng). This is because Adobe's method writes a tag named - #"Default Crop Size" which can't be changed afterwards without rendering the image unusable in Adobe Camera Raw software. I assume Camera Raw - # does some comparison check between dimensions defined in "Default Crop Size" and some of the exif-unwritable Width/Height values, and if - # there's a mismatch, the file can't be opened in Adobe Camera Raw software. I tested it so an image that can't be opened in ACR, is still - # usable in some other RAW processing software (because their check for EXIF value tags differ). + # 2) We check for Canon 5D Mark 3 here - # Every time I edited "Default Crop Size" value in DNG, ACR gave me an error claiming the file is unsupported or corrupted. + # NOTE: We don't care about the image resolution here. - exiftool -CroppedImageWidth=$C5DMK3_WIDTH -CroppedImageHeight=$C5DMK3_HEIGHT -ExifImageWidth=$C5DMK3_WIDTH -ExifImageHeight=$C5DMK3_HEIGHT "${INPUT}" -overwrite_original - echo -e "${INPUT_BASENAME}: Image dimensions updated to $C5DMK3_WIDTH x $C5DMK3_HEIGHT.\n" - # Other useful Height/Width tags are as follows: + if \ + [[ "${PROCESS_BASELINE}" == true ]] && \ + [[ "${C5DMK3_CHECK}" -ne 0 ]] + then - # -OriginalImageWidth - # -OriginalImageHeight + # The following tags (with their respective values) are being used in DNG files + # converted from CR2 files of Canon 5D Mark 3. Because CR2 files are mostly + # equal to DNG files but these tags don't exist inside CR2 files, we can add them + # as shown in the following section. - # -RelatedImageWidth - # -RelatedImageHeight - - fi - - ################################################################ - - # BASELINE TAGS ADDITION - non-Dual ISO CR2 only - - # 1) We can request that PROCESS variable returns true though it's set to false in Dual ISO CR2 images too. These CR2 images have Baseline values - # already added into EXIF metadata since 01/07/2017 (cr2hdr code patched). - - # 2) We check for Canon 5D Mark 3 here - - # NOTE: We don't care about the image resolution here. - - if [[ $PROCESS_BASELINE == true ]] && [[ $C5DMK3_CHECK != 0 ]]; then - - # The following tags (with their respective values) are being used in DNG files converted from CR2 files of Canon 5D Mark 3 camera. Because CR2 files are mostly equal to - # DNG files but these tags don't exist inside CR2 files, we can add them as done in the following lines. - - # ###################################################### - # - # Camera Model: Canon EOS 5D Mark III - - # ISO Value Baseline Exposure Value - # - # 100 0.25 - # 125 0.25 - # 200 0.25 - # 250 0.25 - # 400 0.25 - # 500 0.25 - # 800 0.25 - # 1000 0.25 - # 1600 0.25 - # 2000 0.25 - # 3200 0.25 - # 4000 0.25 - # 6400 0.25 - # 8000 0.25 - # 12800 0.25 - # 16000 0.25 - # 25600 0.25 - # - # 50 -0.75 - # 160 0.02 - # 320 0.01 - # 640 0.01 - # 1250 0.01 - # 2500 0.01 - # 5000 0.01 - # 10000 0.01 - # 20000 0.01 - # 51200 0.36 - # 102400 0.36 - # - # ###################################################### - # - # Same values for all ISOs: - # - # Baseline Noise 0.8 - # Baseline Sharpness 1.2 - # Bayer Green Split 100 - # - # ###################################################### - # - # Camera Profiles in Adobe Camera RAW - Baseline Exposure Offsets: - # - # All Canon EOS 5D Mark 3 profiles (Standard, Neutral, Landscape etc.): -0.25 - # Adobe Standard Profile: 0.00 - # - # ###################################################### - - # We Do ISO check with Exposure Index value (It returns the same value than used ISO, and works with ISO 102400, too) - - if [[ $ISO_VALUE == 50 ]]; then - BL_EXP=-0.75 - - elif [[ $ISO_VALUE == 160 ]]; then - BL_EXP=0.02 - - elif [[ $ISO_VALUE == 51200 ]] || [[ $ISO_VALUE == 102400 ]]; then - BL_EXP=0.36 - - elif [[ $ISO_VALUE == 320 ]] || [[ $ISO_VALUE == 640 ]] || [[ $ISO_VALUE == 1250 ]] || [[ $ISO_VALUE == 2500 ]] || [[ $ISO_VALUE == 5000 ]] || [[ $ISO_VALUE == 10000 ]] || [[ $ISO_VALUE == 20000 ]]; then - BL_EXP=0.01 - - else - BL_EXP=0.25 - fi - - exiftool -BaselineExposure=$BL_EXP -BaselineNoise=0.8 -BaselineSharpness=1.2 -BayerGreenSplit=100 "${INPUT}" -overwrite_original - - echo -e "${INPUT_BASENAME}: Baseline tags added.\n" + # ###################################################### + # + # Camera Model: Canon EOS 5D Mark III + # ISO Value Baseline Exposure Value + # + # 100 0.25 + # 125 0.25 + # 200 0.25 + # 250 0.25 + # 400 0.25 + # 500 0.25 + # 800 0.25 + # 1000 0.25 + # 1600 0.25 + # 2000 0.25 + # 3200 0.25 + # 4000 0.25 + # 6400 0.25 + # 8000 0.25 + # 12800 0.25 + # 16000 0.25 + # 25600 0.25 + # + # 50 -0.75 + # 160 0.02 + # 320 0.01 + # 640 0.01 + # 1250 0.01 + # 2500 0.01 + # 5000 0.01 + # 10000 0.01 + # 20000 0.01 + # 51200 0.36 + # 102400 0.36 + # + # ###################################################### + # + # Same values for all ISOs: + # + # Baseline Noise 0.8 + # Baseline Sharpness 1.2 + # Bayer Green Split 100 + # + # ###################################################### + # + # Camera Profiles in Adobe Camera RAW - Baseline Exposure Offsets: + # + # All Canon EOS 5D Mark 3 profiles (Standard, Neutral, Landscape etc.): -0.25 + # Adobe Standard Profile: 0.00 + # + # ###################################################### + + # We Do ISO check with Exposure Index value (It returns the same + # value than used ISO, and works with ISO 102400, too). + + if [[ "${ISO_VALUE}" -eq 50 ]] + then + BL_EXP=-0.75 + + elif [[ "${ISO_VALUE}" -eq 160 ]] + then + BL_EXP=0.02 + + elif \ + [[ "$ISO_VALUE}" -eq 51200 ]] || \ + [[ "$ISO_VALUE}" -eq 102400 ]] + then + BL_EXP=0.36 + + elif \ + [[ "${ISO_VALUE}" -eq 320 ]] || \ + [[ "${ISO_VALUE}" -eq 640 ]] || \ + [[ "${ISO_VALUE}" -eq 1250 ]] || \ + [[ "${ISO_VALUE}" -eq 2500 ]] || \ + [[ "${ISO_VALUE}" -eq 5000 ]] || \ + [[ "${ISO_VALUE}" -eq 10000 ]] || \ + [[ "${ISO_VALUE}" -eq 20000 ]] + then + BL_EXP=0.01 + + else + BL_EXP=0.25 fi - # ###################################################### + exiftool \ + -BaselineExposure="${BL_EXP}" \ + -BaselineNoise=0.8 \ + -BaselineSharpness=1.2 \ + -BayerGreenSplit=100 \ + "${INPUT}" \ + -overwrite_original - ################################################################ + echo -e "${INPUT_BASENAME}: Baseline tags added.\n" - # SUBJECT TAG ADDITION + fi - if [[ $PROCESS_SUBJECT == true ]] && [[ $C5DMK3_CHECK != 0 ]]; then +################################################################ - exiftool -xmp:subject="$SUBJECT_TAG" "${INPUT}" -overwrite_original + # SUBJECT TAG ADDITION - echo -e "${INPUT_BASENAME}: New Subject tag added: $SUBJECT_TAG\n" + if \ + [[ "${PROCESS_SUBJECT}" == true ]] && \ + [[ "${C5DMK3_CHECK}" -ne 0 ]] + then + exiftool -xmp:subject="${SUBJECT_TAG}" "${INPUT}" -overwrite_original + echo -e "${INPUT_BASENAME}: New Subject tag added: $SUBJECT_TAG\n" + fi - fi +################################################################ - ################################################################ + # FILE SUFFIX ADDITION - # FILE SUFFIX ADDITION + exiftool "-FileModifyDate&1 | grep -E 'opened|frames' | awk '{print $2}' | sed 's/.*\///' | sed -e '1 i\Files:' -e '4 i\\nDNG Frames:' )" --title "MLV Information"; +kdialog \ + --msgbox "$(mlv_dump $1 2>&1 | grep -E 'opened|frames' | awk '{print $2}' | sed 's/.*\///' | sed -e '1 i\Files:' -e '4 i\\nDNG Frames:' )" \ + --title "MLV Information"; diff --git a/4_scripts/imagetools_06_exif_deletedata.sh b/4_scripts/imagetools_06_exif_deletedata.sh index f80da2b..f964fdc 100644 --- a/4_scripts/imagetools_06_exif_deletedata.sh +++ b/4_scripts/imagetools_06_exif_deletedata.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Delete all exif metadata from selected images with Exiftool -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,26 +19,35 @@ # ############################################### -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... -INPUT_DIR=$(dirname $1) +# We get the directory just from the first filename. +INPUT_DIR=$(dirname "${1}") -mkdir -p $INPUT_DIR/nometadata +mkdir -p "${INPUT_DIR}"/nometadata #kdialog --yesnocancel "Do you really want to delete EXIF data for the selection?"; -#if [ "$?" = 0 ]; then - while [ $# -gt 0 ]; do +#if [[ "$?" = 0 ]] +#then + while [[ $# -gt 0 ]] + do - EXTENSION=$(echo $1 | rev | cut -f 1 -d '.' | rev) #Get the correct file extension for an input file (so the new one will use the same) + # Get the correct file extension for an input file, to be used for the new file. + EXTENSION=$(echo "${1}" | rev | cut -f 1 -d '.' | rev) - OLDFILE=$(basename $1 | sed "s/\.\w*$/.$EXTENSION/") - NEWFILE=$(basename "$OLDFILE" | sed "s/\.\w*$/_nometadata.$EXTENSION/") + OLDFILE=$(basename "${1}" | sed "s/\.\w*$/.$EXTENSION/") + NEWFILE=$(basename "$OLDFILE" | sed "s/\.\w*$/_nometadata.$EXTENSION/") - exiftool -all= $INPUT_DIR/$OLDFILE -o $INPUT_DIR/nometadata/$NEWFILE - shift - done + exiftool -all= "${INPUT_DIR}/${OLDFILE}" -o "${INPUT_DIR}/nometadata/${NEWFILE}" -#Delete empty metadata folder (if it is) -if [[ $(ls $INPUT_DIR/nometadata/ | wc -l) == 0 ]]; then - rm -Rf $INPUT_DIR/nometadata/ + # Move to the next file. + shift + done +# else +# exit 0 +# fi + +# Delete empty metadata folder. +if [[ $(ls "${INPUT_DIR}/nometadata/" | wc -l) == 0 ]] +then + rm -Rf "${INPUT_DIR}/nometadata/" fi diff --git a/4_scripts/imagetools_06_exif_deletedata_critical.sh b/4_scripts/imagetools_06_exif_deletedata_critical.sh index a348cdf..61e9d76 100644 --- a/4_scripts/imagetools_06_exif_deletedata_critical.sh +++ b/4_scripts/imagetools_06_exif_deletedata_critical.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Delete critical metadata from an image or images using Exiftool -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,22 +19,67 @@ # ############################################### -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... -INPUT_DIR=$(dirname $1) +# We get the directory just from the first filename. +INPUT_DIR=$(dirname "${1}") #kdialog --yesnocancel "Do you really want to delete EXIF data for the selection?"; -#if [ "$?" = 0 ]; then - while [ $# -gt 0 ]; do +#if [[ "$?" = 0 ]] +#then + while [[ $# -gt 0 ]] + do - EXTENSION=$(echo $1 | rev | cut -f 1 -d '.' | rev) #Get the correct file extension for an input file (so the new one will use the same) + # Get the correct file extension for an input file, to be used for the new file. + EXTENSION=$(echo "${1}" | rev | cut -f 1 -d '.' | rev) + FILE=$(basename "${1}" | sed "s/\.\w*$/.$EXTENSION/") - FILE=$(basename $1 | sed "s/\.\w*$/.$EXTENSION/") + exiftool \ + -ApertureValue= \ + -ColorSpace= \ + -ExposureCompensation= \ + -ExposureMode= \ + -ExposureProgram= \ + -ExposureTime= \ + -FNumber= \ + -Flash= \ + -FocalLength= \ + -FocalPlaneResolutionUnit= \ + -FocalPlaneXResolution= \ + -FocalPlaneYResolution= \ + -Lens= \ + -LensInfo= \ + -LensModel= \ + -LensSerialNumber= \ + -Make= \ + -MaxApertureValue= \ + -MeteringMode= \ + -Model= \ + -PhotoshopThumbnail= \ + -RecommendedExposureIndex= \ + -ResolutionUnit= \ + -SensitivityType= \ + -SerialNumber= \ + -ShutterSpeedValue= \ + -Software= \ + -Version= \ + -WhiteBalance= \ + -XResolution= \ + -YResolution= \ + -creatortool= \ + -historysoftwareagent= \ + -iso= \ + -adobe:all= \ + -xmp:subject= \ + -xmp:all= \ + -photoshop:all= \ + "${INPUT_DIR}/${FILE}" \ + -overwrite_original - exiftool -xmp:subject= -Software= -Version= -creatortool= -historysoftwareagent= -PhotoshopThumbnail= -FocalLength= -Lens= -FNumber= -ApertureValue= -LensInfo= -LensModel= -ExposureTime= -MaxApertureValue= -SerialNumber= -Make= -ExposureMode= -WhiteBalance= -Flash= -MeteringMode= -ExposureCompensation= -ShutterSpeedValue= -RecommendedExposureIndex= -SensitivityType= -LensSerialNumber= -FocalPlaneYResolution= -FocalPlaneXResolution= -FocalPlaneResolutionUnit= -XResolution= -YResolution= -ResolutionUnit= -iso= -ColorSpace= -Model= -ExposureProgram= -adobe:all= -xmp:all= -photoshop:all= $INPUT_DIR/$FILE -overwrite_original - shift - done -# kdialog --msgbox "Exif metadata deleted!" + # Move to the next file. + shift + done + +# kdialog --msgbox "Exif metadata deleted!" #else -# exit 0 +# exit 0 #fi diff --git a/4_scripts/imagetools_07_ale_stack.sh b/4_scripts/imagetools_07_ale_stack.sh index 8e60526..3fa0002 100644 --- a/4_scripts/imagetools_07_ale_stack.sh +++ b/4_scripts/imagetools_07_ale_stack.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Stack TIFF images with Anti-Lamenessing Engine (ALE) -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,15 +19,17 @@ # ############################################### -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... -INPUT_DIR=$(dirname $1) +# We get the directory just from the first filename. +INPUT_DIR=$(dirname "${1}") -#First & Last file names (without suffixes) -for last; do true; done -FIRST=$(basename $1 | cut -f 1 -d '.' | sed 's/IMG_//g') #Name of the first file passed into the script -LAST=$(basename $last | cut -f 1 -d '.' | sed 's/IMG_//g') #Name of the last file passed into the script +# First & Last file names (without suffixes) +for _LAST; do true; done +# Name of the first file passed into the script. +FIRST=$(basename "${1}" | cut -f 1 -d '.' | sed 's/IMG_//g') +# Name of the last file passed into the script. +LAST=$(basename "${_LAST}" | cut -f 1 -d '.' | sed 's/IMG_//g') -echo 'Starting image stacking process using temporary TIFF files.' && \ +echo "Starting image stacking process using temporary TIFF files." ale ./temp_tiff/*.tiff output.tif diff --git a/4_scripts/imagetools_08_geotag.sh b/4_scripts/imagetools_08_geotag.sh index 8fcf86e..7ca222c 100644 --- a/4_scripts/imagetools_08_geotag.sh +++ b/4_scripts/imagetools_08_geotag.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/env bash # Geotag images -# Copyright (C) 2017 Pekka Helenius +# Copyright (C) 2017,2023 Pekka Helenius # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -20,65 +20,83 @@ ############################################### # TODO Coordinate threshold = Grid size is 30x30m? -# TODO Find API for ASTER DEM v2 (better data) +# TODO Find API for ASTER DEM v2 (provides better data) -USERNAME=Fincer #For API (data request) +# Username for REST API data request +USERNAME= ############################ -INTERNET_TEST=$(ping -c 3 nominatim.openstreetmap.org 2>&1 | grep -c "unknown host") #Ping Github three times and look for string 'unknown host' +# Ping openstreetmap.org three times. +PING_ADDRESS="nominatim.openstreetmap.org" +INTERNET_TEST=$(ping -c 3 "${PING_ADDRESS}" 2>&1 | grep -c "unknown host") -if [[ ! $INTERNET_TEST -eq 0 ]]; then #If 'unknown host' string is found, then - echo -e "\nCan't connect to geoservice provider (Nominatim). Please check your internet connection and try again.\n" - exit 1 +if [[ ! "${INTERNET_TEST}" -eq 0 ]] +then + echo -e "\nCan't connect to the Geo Service provider '${PING_ADDRESS}'. Please check your internet connection and try again.\n" + exit 1 fi ############################ -for IMAGE in $(echo "${@}"); do +for IMAGE in $(echo "${@}") +do + + IMAGE_BASENAME=$(basename "${IMAGE}" | cut -f 1 -d '.') + IMAGE_EXTENSION=$(echo $(basename "${IMAGE}" | cut -f 2 -d '.' | sed '/^\s*$/d')) + + if [[ $(exiftool -n -p '$GPSLatitude,$GPSLongitude' "${IMAGE}" | awk -F ',' '{print NF}') != 2 ]] + then + echo -e "$IMAGE_BASENAME: Missing coordinates. Are you sure you have geotagged the photo?\n" + exit 0 + else + + LATITUDE=$(exiftool -n -p '$GPSLatitude' "${IMAGE}") + LONGITUDE=$(exiftool -n -p '$GPSLongitude' "${IMAGE}") + + # Clear previous geonames information. + exiftool \ + -Location= \ + -LocationShownCity= \ + -LocationShownCountryName= \ + -LocationShownProvinceState= \ + -LocationShownSublocation= \ + -Country-PrimaryLocationName= \ + -Sub-location= \ + -Country= \ + -City= \ + -State= \ + -Province-State= \ + -GPSAltitude= \ + "${IMAGE}" \ + -overwrite_original + + echo -e "$IMAGE_BASENAME: retrieving country information.\n" + reversegeo "${IMAGE}" + + # Reference: http://www.geonames.org/export/web-services.html + # Get elevation by retrieving a ASTER DEM value from GeoNames API server, grid size 30x30m + # There are several error factors: + # DEM Grid size + # General inaccurancies in DEM model + # Geoid model & projection errors + # Coordinate errors + # Variations in (estimated) height values + + # So the retrieved elevation value is just a rough estimation here. + + ALTITUDE=$(curl -s "http://api.geonames.org/astergdem?lat=$LATITUDE&lng=$LONGITUDE&username=$USERNAME") + + # If we have a successful answer, then + if [[ "${ALTITUDE}" =~ '^[0-9]+$' ]] + then + + exiftool -GPSAltitude="${ALTITUDE}" "${IMAGE}" -overwrite_original + echo -e "${IMAGE_BASENAME}: Altitude value updated.\n" - IMAGE_BASENAME=$(basename "${IMAGE}" | cut -f 1 -d '.') - IMAGE_EXTENSION=$(echo $(basename "${IMAGE}" | cut -f 2 -d '.' | sed '/^\s*$/d')) - - if [[ $(exiftool -n -p '$GPSLatitude,$GPSLongitude' "${IMAGE}" | awk -F ',' '{print NF}') != 2 ]]; then - echo -e "$IMAGE_BASENAME: Missing coordinates. Are you sure you have geotagged the photo?\n" - exit - else - - LATITUDE=$(exiftool -n -p '$GPSLatitude' "${IMAGE}") - LONGITUDE=$(exiftool -n -p '$GPSLongitude' "${IMAGE}") - - # Clear previous geonames information - exiftool -Location= -LocationShownCity= -LocationShownCountryName= -LocationShownProvinceState= -LocationShownSublocation= -Country-PrimaryLocationName= -Sub-location= -Country= -City= -State= -Province-State= -GPSAltitude= "${IMAGE}" -overwrite_original - - #if [[ $(exiftool -p '$Country-PrimaryLocationName' "${IMAGE}" | awk '{print NF}') != 1 ]]; then - echo -e "$IMAGE_BASENAME: retrieving country information.\n" - reversegeo "${IMAGE}" - #fi - - # Reference: http://www.geonames.org/export/web-services.html - # Get elevation by retrieving a ASTER DEM value from GeoNames API server, grid size 30x30m - # There are several error factors: - # DEM Grid size - # General inaccurancies in DEM model - # Geoid model & projection errors - # Coordinate errors - # Variations in (estimated) height values - - # So the retrieved elevation value is just a rough estimation here - - ALTITUDE=$(curl -s "http://api.geonames.org/astergdem?lat=$LATITUDE&lng=$LONGITUDE&username=$USERNAME") - - # IF successful answer, then - if [[ $ALTITUDE =~ '^[0-9]+$' ]]; then - - exiftool -GPSAltitude=$ALTITUDE "${IMAGE}" -overwrite_original - echo -e "$IMAGE_BASENAME: Altitude value updated.\n" - - else - # TODO IF NOT successful, try again for 2 times, then abort - - echo -e "$IMAGE_BASENAME: Couldn't retrieve altitude value.\n" - + # TODO: If not successful, try again for 2 times, then abort. + echo -e "${IMAGE_BASENAME}: Couldn't retrieve altitude value.\n" + fi + fi done diff --git a/4_scripts/imagetools_09_mtime.sh b/4_scripts/imagetools_09_mtime.sh index 95ce5f7..cecca65 100644 --- a/4_scripts/imagetools_09_mtime.sh +++ b/4_scripts/imagetools_09_mtime.sh @@ -1,35 +1,13 @@ -#!/bin/bash - -################################################################################################ - -# File system check -# We don't allow writing to SD card. - -#Sed is here to remove any trailing spaces and crap like blank lines -INPUT_FILESYSTEM=$(df -h "${1}" | awk -F ' ' 'FNR> 1 {print $1}' | grep -i -E "/dev/sd?|/dev/hd?|?rewritefs|?tmpfs|/dev/nvme?" | sed '/^\s*$/d' | wc -l) - -if [[ "${INPUT_FILESYSTEM}" -eq 0 ]]; then #if input file (first file printed in bash) filesystem does not start with /dev/sdX - kdialog --error "Image(s) are in a SD Card. Please move them your local or external storage and try again." - exit -fi - -################################################################################################ - - -#We get the directory just from the first filename. Pwd should be easier, but bugged, so... -INPUT_DIR=$(dirname "${1}") -DIR_BASENAME=$(echo "${INPUT_DIR}" | rev | cut -d/ -f 1 | rev) - -while [[ $# -gt 0 ]]; do - -################################################################ - -# Values that change during the while loop (differ from file to file) +#!/bin/env bash +while [[ $# -gt 0 ]] +do INPUT="${1}" - MTIME=$(exiftool -d "%s" -DateTimeOriginal -s -S "${INPUT}") - touch --date=@${MTIME} "${INPUT}" + if [[ ! -z "${MTIME}" ]]; then + touch --date=@${MTIME} "${INPUT}" + fi - shift # Move to the next file + # Move to the next file. + shift done