Heavy modularization for ease of development! convmlv.sh is now just a chooser, triggering functions in src. More work to do.

modularize
Sofus Albert Høgsbro Rose 2016-12-06 00:56:08 -05:00
parent 309c70c3d5
commit 369d928368
Signed by: so-rose
GPG Key ID: 3D01BE95F3EFFEB9
15 changed files with 2360 additions and 2229 deletions

2327
convmlv.sh

File diff suppressed because it is too large Load Diff

24
deploy.sh 100755
View File

@ -0,0 +1,24 @@
#!/bin/bash
VERSION=$(echo "$(./convmlv.sh -v)" | sed -e 's/\./\_/g')
REMOTE=sofus@yeti
if [[ $OSTYPE == "linux-gnu" ]]; then
PLATFORM="linux"
elif [[ $OSTYPE == "darwin11" ]]; then
PLATFORM="mac"
else
echo "Platform not yet supported! Contact me at contact@sofusrose.com."
fi
rsync -avzP release/convmlv-${VERSION}-${PLATFORM}.tar.gz $REMOTE:/data/main/convmlv/
ssh $REMOTE VERSION=$VERSION PLATFORM=$PLATFORM 'bash -s' << 'ENDSSH'
cd /data/main/convmlv
tar -xvzf /data/main/convmlv/convmlv-$VERSION-$PLATFORM.tar.gz
rm /data/main/convmlv/convmlv-$VERSION-$PLATFORM.tar.gz
ENDSSH
echo -e "\nRemember to update apt dependencies on $REMOTE"!

View File

@ -12,6 +12,7 @@ VERSION=$(echo "$(./convmlv.sh -v)" | sed -e 's/\./\_/g')
REP_PATH="$(pwd)"
BINPATH="${REP_PATH}/binaries"
SRCPATH="${REP_PATH}/src"
RELEASE="${REP_PATH}/release"
mkdir -p "$RELEASE"
@ -24,5 +25,5 @@ else
echo "Platform not yet supported! Contact me at contact@sofusrose.com."
fi
cd "$BINPATH"
tar -czvf $RELEASE/convmlv-${VERSION}-${PLATFORM}.tar.gz ../balance.py mlv2badpixels.sh mlv_dump raw2dng cr2hdr ../sRange.py ../CHANGELOG ../licence ../convmlv.sh ../color-core/ ../color-ext ../DEPENDENCIES ../docs/MANPAGE ../docs/docs.pdf ../docs/workflow.txt ../configs/*
cd $REP_PATH
tar -czvf $RELEASE/convmlv-${VERSION}-${PLATFORM}.tar.gz binaries/ src/ CHANGELOG licence convmlv.sh color-core/ color-ext DEPENDENCIES docs/MANPAGE docs/docs.pdf docs/workflow.txt configs/*

808
src/core/develop.sh 100644
View File

@ -0,0 +1,808 @@
setRange() {
#FRAMES must be set at this point.
if [[ $isFR == true ]]; then #Ensure that FRAME_RANGE is set with $FRAMES.
FRAME_RANGE="1-${FRAMES}"
FRAME_START="1"
FRAME_END=$FRAMES
else
base=$(echo $RANGE_BASE | sed -e 's:s:0:g' | sed -e "s:e:$(echo "$FRAMES - 1" | bc):g") #FRAMES is incremented in a moment.
#~ FRAME_RANGE_ZERO="$(echo $base | cut -d"-" -f1)-$(echo $base | cut -d"-" -f2)" #Number from 0. Useless as of now.
FRAME_RANGE="$(echo "$(echo $base | cut -d"-" -f1) + 1" | bc)-$(echo "$(echo $base | cut -d"-" -f2) + 1" | bc)" #Number from 1.
FRAME_START=$(echo ${FRAME_RANGE} | cut -d"-" -f1)
FRAME_END=$(echo ${FRAME_RANGE} | cut -d"-" -f2)
#Some error checking - out of range values default to start and end.
if [[ $FRAME_END -gt $FRAMES || $FRAME_END -lt $FRAME_START || $FRAME_END -lt 1 ]]; then FRAME_END=$FRAMES; fi
if [[ $FRAME_START -lt 1 || $FRAME_START -gt $FRAME_END ]]; then FRAME_START=1; fi
FRAME_RANGE="${FRAME_START}-${FRAME_END}"
fi
}
develop() {
trap "rm -rf ${TMP}; exit 1" INT #TMP will be removed if you CTRL+C.
for ARG in "${FILE_ARGS_ARRAY[@]}"; do #Go through FILE_ARGS_ARRAY array, copied from parsed $@ because $@ is going to be changing on 'set --'
ARG=$(readlinkF "$ARG") #Use platform-independent readline.
#The Very Basics
BASE="$(basename "$ARG")"
EXT="${BASE##*.}"
if [[ "${EXT}" == ".${BASE}" ]]; then EXT=""; fi #This means the input is a folder, which has no extension.
DIRNAME=$(dirname "$ARG")
TRUNC_ARG="${BASE%.*}"
SCALE=`echo "($(echo "${PROXY_SCALE}" | sed 's/%//') / 100) * 2" | bc -l` #Get scale as factor for halved video, *2 for 50%
setBL=true
#Evaluate local configuration file for file-specific blocks.
parseConf "$LCONFIG" true
#Check that ARG exists and works.
local action=$(checkArg)
if [[ $action = "skip" ]]; then
let ARGNUM--; continue
fi
#Color Management - The Color LUT is chosen + applied.
#We define what "STANDARD" means. Gamma 2.2 if it's not specifically defined.
if [[ $COLOR_GAMUT != "xyz" ]]; then
#~ if [[ $COLOR_GAMUT == "aces" ]]; then #List of Linear Only gamuts. XYZ excluded, in that that's default output; no filtering needed.
#~ COLOR_GAMMA="lin"
#~ fi
if [[ $COLOR_GAMMA == "STANDARD" ]]; then
if [[ $COLOR_GAMUT == "argb" || $COLOR_GAMUT == "ssg3c" ]]; then #List of gamuts with Gamma 2.2 .
COLOR_GAMMA="y2*2"
else
COLOR_GAMMA=$COLOR_GAMUT
fi
fi
for source in "${COLOR_LUTS[@]}"; do
colorName="${source}/lin_xyz--${COLOR_GAMMA}_${COLOR_GAMUT}.cube"
if [[ -f $colorName ]]; then
COLOR_VF="lut3d=$colorName"
colorDesc="Color Management LUT"
FFMPEG_FILTERS=true
fi
done
if [[ $COLOR_VF == "" ]]; then
echo -e "\033[0;31m\033[1mSpecified LUT not found! Is color-ext loaded?.\033[0m\n"
fi
fi #COLOR_VF is nothing if the gamut is xyz - it'll pass directly out of dcraw/IM, without LUT application.
#Construct the FFMPEG filters.
FINAL_SCALE="scale=trunc(iw/2)*${SCALE}:trunc(ih/2)*${SCALE}"
if [[ $FFMPEG_FILTERS == true ]]; then
V_FILTERS="-vf $(joinArgs , ${COLOR_VF} ${LUTS[@]} ${HQ_NOISE} ${TEMP_NOISE} ${REM_NOISE} ${SHARP} ${DESHAKE})"
V_FILTERS_PROX="-vf $(joinArgs , ${COLOR_VF} ${LUTS[@]} ${HQ_NOISE} ${TEMP_NOISE} ${REM_NOISE} ${SHARP} ${DESHAKE} ${FINAL_SCALE})" #Proxy filter set adds the FINAL_SCALE component.
#Created formatted array of filters, FILTER_ARR.
compFilters=()
declare -a compFilters=("${colorDesc}" "${sharpDesc}" "${hqDesc}" "${tempDesc}" "${remDesc}" "${deshakeDesc}" "${lutDesc}")
for v in "${compFilters[@]}"; do if test "$v"; then FILTER_ARR+=("$v"); fi; done
else
V_FILTERS_PROX="-vf ${FINAL_SCALE}"
fi
#List remaining files to process.
remFiles=${@:`echo "$# - ($ARGNUM - 1)" | bc`:$#}
remArr=$(echo $remFiles)
list=""
for item in $remArr; do
itemBase=$(basename $item)
itemExt=".${itemBase##*.}" #Dot must be in here.
if [[ "${itemExt}" == ".${itemBase}" ]]; then itemExt=""; fi #This means the input is a folder, which has no extension.
itemDir=$(dirname "$item")
if [ -z "${list}" ]; then
if [[ $itemBase == $(basename $ARG) ]]; then
list="${itemDir}/\033[1m\033[32m${itemBase%.*}\033[0m${itemExt}"
else
list="${itemDir}/\033[1m${itemBase%.*}\033[0m${itemExt}"
fi
else
list="${list}, ${itemDir}/\033[1m${itemBase%.*}\033[0m${itemExt}"
fi
done
if [ $ARGNUM == 1 ]; then
echo -e "\n\033[1m${ARGNUM} File Left to Process:\033[0m ${list}\n"
else
echo -e "\n\033[1m${ARGNUM} Files Left to Process:\033[0m ${list}\n"
fi
#PREPARATION
#Establish Basic Directory Structure.
OUTDIR=$(readlinkF "$OUTDIR")
if [ $OUTDIR != $PWD ] && [ $isOutGen == false ]; then
mkdir -p $OUTDIR #NO RISKS. WE REMEMBER THE LUT.py. RIP ad-hoc HALD LUT implementation :'( .
isOutGen=true
fi
FILE="${OUTDIR}/${TRUNC_ARG}"
TMP="${FILE}/tmp_${TRUNC_ARG}"
#DNG argument, reused or not. Also, create FILE and TMP.
DEVELOP=true
if [[ ( -d $ARG ) && ( ( `basename ${ARG} | cut -c1-3` == "dng" && -f "${ARG}/../settings.txt" ) || ( `basename ${ARG}` == $TRUNC_ARG && -f "${ARG}/settings.txt" ) ) ]]; then #If we're reusing a dng sequence, copy over before we delete the original.
echo -e "\033[1m${TRUNC_ARG}:\033[0m Moving DNGs from previous run...\n" #Use prespecified DNG sequence.
#User may specify either the dng_ or the trunc_arg folder; must account for both.
if [[ `folderName ${ARG}` == $TRUNC_ARG && -d "${ARG}/dng_${TRUNC_ARG}" ]]; then #Accounts for the trunc_arg folder.
ARG="${ARG}/dng_${TRUNC_ARG}" #Set arg to the dng argument.
elif [[ `folderName ${ARG}` == $TRUNC_ARG && `echo "$(basename ${ARG})" | cut -c 1-3` == "dng" ]]; then #Accounts for the dng_ folder.
TRUNC_ARG=`echo $TRUNC_ARG | cut -c5-${#TRUNC_ARG}`
else
echo -e "\033[0;31m\033[1mCannot reuse - DNG folder does not exist! Skipping argument.\033[0m"
continue
fi
DNG_LOC=${OUTDIR}/tmp_reused
mkdir -p ${OUTDIR}/tmp_reused
find $ARG -iname "*.dng" | xargs -I {} mv {} $DNG_LOC #Copying DNGs to temporary location.
dngSet "$DNG_LOC"
FPS=`cat ${ARG}/../settings.txt | grep "FPS" | cut -d $" " -f2` #Grab FPS from previous run.
FRAMES=`cat ${ARG}/../settings.txt | grep "Frames" | cut -d $" " -f2` #Grab FRAMES from previous run.
KELVIN=`cat ${ARG}/../settings.txt | grep "WBKelvin" | cut -d $" " -f2`
cp "${ARG}/../settings.txt" $DNG_LOC
oldARG="${ARG}"
DIRNAME=$(dirname "$oldARG")
BASE="$(basename "$oldARG")"
EXT=""
FILE="${OUTDIR}/${TRUNC_ARG}"
TMP="${FILE}/tmp_${TRUNC_ARG}" #Remove dng_ from ARG by redefining basic constants. Ready to go!
ARG="${FILE}/dng_${TRUNC_ARG}" #Careful. This won't exist till later.
dngLocClean() {
find $DNG_LOC -iname "*.dng" | xargs -I {} mv {} $oldARG
rm -rf $DNG_LOC
}
mkdirS $FILE dngLocClean
mkdirS $TMP #Make the folders.
find $DNG_LOC -iname "*.dng" | xargs -I {} mv {} $TMP #Moving files to where they need to go.
cp "${DNG_LOC}/settings.txt" $FILE
setBL=false
DEVELOP=false
rm -r $DNG_LOC
elif [ -d $ARG ]; then #If it's a DNG sequence, but not a reused one.
mkdirS $FILE
mkdirS $TMP
echo -e "\033[1m${TRUNC_ARG}:\033[0m Using specified folder of RAW sequences...\n" #Use prespecified DNG sequence.
FPS=24 #Set it to a safe default.
FRAMES=$(find ${ARG} -name "*.dng" | wc -l)
setRange
i=1
for dng in $ARG/*.dng; do
ln -s $dng $(printf "${TMP}/${TRUNC_ARG}_%06d.dng" $i) #Since we're not touching the DNGs, we can link them from wherever to TMP!!! :) Super duper fast.
let i++
if [[ i -gt $FRAME_END ]]; then break; fi
done
dngSet
DEVELOP=false #We're not developing DNG's; we already have them!
else
mkdirS $FILE
mkdirS $TMP
fi
#Darkframe Averaging
if [[ $useDF == true ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Creating darkframe for subtraction...\n"
avgFrame="${TMP}/avg.darkframe" #The path to the averaged darkframe file.
#~ There was a bug - retest this.
darkBase="$(basename "$DARKFRAME")"
darkExt="${darkBase##*.}"
if [ $darkExt != 'darkframe' ]; then
$MLV_DUMP -o "${avgFrame}" -a $DARKFRAME >/dev/null 2>/dev/null
else
cp $DARKFRAME $avgFrame #Copy the preaveraged frame if the extension is .darkframe.
fi
RES_DARK=`echo "$(${MLV_DUMP} -v -m ${avgFrame})" | grep "Res" | sed 's/[[:alpha:] ]*: //'`
DARK_PROC="-s ${avgFrame}"
fi
#Develop sequence if needed.
if [ $DEVELOP == true ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Dumping to DNG Sequence...\n"
if [ ! $DARKFRAME == "" ] && [ ! $CHROMA_SMOOTH == "--no-cs" ]; then #Just to let the user know that certain features are impossible with RAW.
rawStat="*Skipping Darkframe subtraction and Chroma Smoothing for RAW file ${TRUNC_ARG}."
elif [ ! $DARKFRAME == "" ]; then
rawStat="*Skipping Darkframe subtraction for RAW file ${TRUNC_ARG}."
elif [ ! $CHROMA_SMOOTH == "--no-cs" ]; then
rawStat="*Skipping Chroma Smoothing for RAW file ${TRUNC_ARG}."
else
rawStat="\c"
fi
#IF extension is RAW, we want to convert to MLV. All the interesting features are MLV-only, because of mlv_dump's amazingness.
if [ $EXT == "MLV" ] || [ $EXT == "mlv" ]; then
# Read the header.
mlvSet
setRange
# Error checking: Darkframe resolution must match resolution.
if [[ (! -z $RES_DARK) && $RES_DARK != $RES_IN ]]; then
invOption "Darkframe Resolution doesn't match MLV Resolution! Use another darkframe!"
fi
#Dual ISO might want to do the chroma smoothing. In which case, don't do it now!
if [ $DUAL_ISO == true ]; then
smooth="--no-cs"
else
smooth=$CHROMA_SMOOTH
fi
#Create new MLV with adequate number of frames, if needed.
REAL_MLV=$ARG
REAL_FRAMES=$FRAMES
if [ $isFR == false ]; then
REAL_MLV="${TMP}/newer.mlv"
$MLV_DUMP $ARG -o ${REAL_MLV} -f ${FRAME_RANGE} >/dev/null 2>/dev/null
REAL_FRAMES=`${MLV_DUMP} ${REAL_MLV} | awk '/Processed/ { print $2; }'`
fi
fileRanges=(`echo $($SRANGE $REAL_FRAMES $THREADS)`) #Get an array of frame ranges from the amount of frames and threads. I used a python script for this.
#Looks like this: 0-1 2-2 3-4 5-5 6-7 8-8 9-10. Put that in an array.
devDNG() { #Takes n arguments: 1{}, the frame range 2$MLV_DUMP 3$REAL_MLV 4$DARK_PROC 5$no_data 6$smooth 7$TMP 8$FRAME_END 9$TRUNC_ARG 10$FRAME_START
range=$1
firstFrame=false
if [[ $range == "0-0" ]]; then #mlv_dump can't handle 0-0, so we develop 0-1.
range="0-1"
firstFrame=true
fi
tmpOut=${7}/${range} #Each output will number from 0, so give each its own folder.
mkdir -p $tmpOut
start=$(echo "$range" | cut -d'-' -f1)
end=$(echo "$range" | cut -d'-' -f2) #Get start and end frames from the frame range
$2 $3 $4 -o "${tmpOut}/${9}_" -f ${range} $6 --dng --batch | { #mlv_dump command. Uses frame range.
lastCur=0
while IFS= read -r line; do
output=$(echo $line | grep -Po 'V.*A' | cut -d':' -f2 | cut -d$' ' -f1) #Hacked my way to the important bit.
if [[ $output == "" ]]; then continue; fi #If there's no important bit, don't print.
cur=$(echo "$output" | cut -d'/' -f1) #Current frame.
if [[ $cur == $lastCur ]] || [[ $cur -gt $end ]] || [[ $cur -lt $start ]]; then continue; fi #Turns out, it goes through all the frames, even if cutting the frame range. So, clamp it!
lastCur=$cur #It likes to repeat itself.
echo -e "\033[2K\rMLV to DNG: Frame $(echo "${cur} + ${10}" | bc)/${8}\c" #Print out beautiful progress bar, in parallel!
done
} #Progress Bar
if [[ $firstFrame == true ]]; then #If 0-0.
rm $(printf "${tmpOut}/${9}_%06d.dng" 1) 2>/dev/null #Remove frame #1, leaving us only with frame #0.
mv $tmpOut "${7}/0-0" #Move back to 0-0, as if that's how it was developed all along.
fi
}
export -f devDNG #Export to run in subshell.
for range in "${fileRanges[@]}"; do echo $range; done | #For each frame range, assign a thread.
xargs -I {} -P $THREADS -n 1 \
bash -c "devDNG '{}' '$MLV_DUMP' '$REAL_MLV' '$DARK_PROC' 'no_data' '$smooth' '$TMP' '$FRAME_END' '$TRUNC_ARG' '$FRAME_START'"
#Since devDNG must run in a subshell, globals don't follow. Must pass *everything* in.
echo -e "\033[2K\rMLV to DNG: Frame ${FRAME_END}/${FRAME_END}\c" #Ensure it looks right at the end.
echo -e "\n"
count=$FRAME_START
for range in "${fileRanges[@]}"; do #Go through the subfolders sequentially
tmpOut=${TMP}/${range} #Use temporary folder. It will be named the same as the frame range.
for dng in ${tmpOut}/*.dng; do
if [ $count -gt $FRAME_END ]; then echo "ERROR! Count greater than end!"; fi
mv $dng $(printf "${TMP}/${TRUNC_ARG}_%06d.dng" $count) #Move dngs out sequentially, numbering them properly.
let count++
done
rm -r $tmpOut #Remove the now empty subfolder
done
elif [ $EXT == "RAW" ] || [ $EXT == "raw" ]; then
rawSet
setRange
echo -e $rawStat
FPS=`$RAW_DUMP $ARG "${TMP}/${TRUNC_ARG}_" | awk '/FPS/ { print $3; }'` #Run the dump while awking for the FPS.
fi
#~ BLACK_LEVEL=$(exiftool -BlackLevel -s -s -s ${TMP}/${TRUNC_ARG}_$(printf "%06d" $(echo "$FRAME_START" | bc)).dng)
fi
setRange #Just to be sure the frame range was set, in case the input isn't MLV.
BLACK_LEVEL=$(exiftool -BlackLevel -s -s -s ${TMP}/${TRUNC_ARG}_$(printf "%06d" $(echo "$FRAME_START" | bc)).dng) #Use the first DNG to get the correct black level.
prntSet > $FILE/settings.txt
sed -i -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $FILE/settings.txt #Strip escape sequences.
#Create badpixels file.
if [ $isBP == true ] && [ $DEVELOP == true ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Generating badpixels file...\n"
bad_name="badpixels_${TRUNC_ARG}.txt"
gen_bad="${TMP}/${bad_name}"
touch $gen_bad
if [ $EXT == "MLV" ] || [ $EXT == "mlv" ]; then
$MLV_BP -o $gen_bad $ARG
elif [ $EXT == "RAW" ] || [ $EXT == "raw" ]; then
$MLV_BP -o $gen_bad $ARG
fi
if [[ ! -z $BADPIXEL_PATH ]]; then
if [ -f "${gen_bad}" ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Concatenating with specified badpixels file...\n"
mv "${gen_bad}" "${TMP}/bp_gen"
cp $BADPIXEL_PATH "${TMP}/bp_imp"
{ cat "${TMP}/bp_gen" && cat "${TMP}/bp_imp"; } > "${gen_bad}" #Combine specified file with the generated file.
else
cp $BADPIXEL_PATH "${gen_bad}"
fi
fi
BADPIXELS="-P ${gen_bad}"
elif [[ ! -z $BADPIXEL_PATH ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Using specified badpixels file...\n"
bad_name="badpixels_${TRUNC_ARG}.txt"
gen_bad="${TMP}/${bad_name}"
cp $BADPIXEL_PATH "${gen_bad}"
BADPIXELS="-P ${gen_bad}"
fi
#Dual ISO Conversion
if [ $DUAL_ISO == true ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Combining Dual ISO...\n"
#Original DNGs will be moved here.
oldFiles="${TMP}/orig_dng"
mkdirS $oldFiles
inc_iso() { #6 args: 1{} 2$CR_HDR 3$TMP 4$FRAME_END 5$oldFiles 6$CHROMA_SMOOTH. {} is a path. Progress is thread safe. Experiment gone right :).
count=$(echo "$(echo $(echo $1 | rev | cut -d "_" -f 1 | rev | cut -d "." -f 1 | grep "[0-9]") | bc) + 1" | bc) #Get count from filename.
$2 $1 $6 >/dev/null 2>/dev/null #The LQ option, --mean23, is completely unusable in my opinion.
name=$(basename "$1")
mv "${3}/${name%.*}.dng" $5 #Move away original dngs.
mv "${3}/${name%.*}.DNG" "${3}/${name%.*}.dng" #Rename *.DNG to *.dng.
echo -e "\033[2K\rDual ISO Development: Frame ${count}/${4}\c"
}
export -f inc_iso #Must expose function to subprocess.
#~ echo "${CR_HDR} ${TMP}/${TRUNC_ARG}_$(printf "%06d" $FRAME_START).dng"
if [[ $(${CR_HDR} "${TMP}/${TRUNC_ARG}_$(printf "%06d" $FRAME_START).dng") == *"ISO blending didn't work"* ]]; then
invOption "The input wasn't shot Dual ISO!"
fi
find $TMP -maxdepth 1 -name "*.dng" -print0 | sort -z | xargs -0 -I {} -P $THREADS -n 1 \
bash -c "inc_iso '{}' '$CR_HDR' '$TMP' '$FRAME_END' '$oldFiles' '$CHROMA_SMOOTH'"
BLACK_LEVEL=$(exiftool -BlackLevel -s -s -s ${TMP}/${TRUNC_ARG}_$(printf "%06d" $(echo "$FRAME_START" | bc)).dng) #Use the first DNG to get the new correct black level.
echo -e "\n"
fi
if [ $setBL == true ]; then
echo -e "BlackLevel: ${BLACK_LEVEL}" >> $FILE/settings.txt #Black level must now be set.
fi
normToOne() {
wBal=$1
max=0.0
for mult in $wBal; do
if [ $(echo " $mult > $max" | bc) -eq 1 ]; then
max=$mult
fi
done
for mult in $wBal; do
echo -e "$(echo "scale=6; x=${mult} / ${max}; if(x<1) print 0; x" | bc -l) \c" #BC is bae.
done
}
getGreen() {
wBal=$1
i=0
for mult in $wBal; do
if [ $i -eq 1 ]; then
echo -e "${mult}"
fi
let i++
done
}
#Get White Balance correction factor.
if [ $GEN_WHITE == true ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Generating WB...\n"
#Calculate n, the distance between samples.
frameLen=$(echo "$FRAME_END - $FRAME_START + 1" | bc) #Offset by one to avoid division by 0 errors later. min value must be 1.
#A point of improvement, this.
if [[ $WHITE_SPD -gt $frameLen ]]; then
WHITE_SPD=$frameLen
fi
n=`echo "${frameLen} / ${WHITE_SPD}" | bc`
toBal="${TMP}/toBal"
mkdirS $toBal
#Develop every nth file for averaging.
local i=0
local t=0
for file in $TMP/*.dng; do
if [ `echo "(${i}+1) % ${n}" | bc` -eq 0 ]; then
$DCRAW -q 0 $BADPIXELS -r 1 1 1 1 -g $GAMMA -k $BLACK_LEVEL $SATPOINT -o 0 -T "${file}"
name=$(basename "$file")
mv "$TMP/${name%.*}.tiff" $toBal #TIFF MOVEMENT. We use TIFFs here because it's easy for dcraw and Python.
let t++
fi
echo -e "\033[2K\rWB Development: Sample ${t}/$(echo "${frameLen} / $n" | bc) (Frame: $(echo "${i} + 1" | bc)/${FRAME_END})\c"
let i++
done
echo ""
#Calculate + store result into a form dcraw likes.
echo -e "Calculating Auto White Balance..."
BALANCE=`$BAL $toBal`
elif [ $CAMERA_WB == true ]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Retrieving Camera White Balance..."
for file in $TMP/*.dng; do
#dcraw a single file verbosely, to get the camera multiplier with awk.
BALANCE=`$DCRAW -T -w -v -c ${file} 2>&1 | awk '/multipliers/ { print $2, $3, $4 }'`
break
done
else #Something must always be set.
echo -e "\033[1m${TRUNC_ARG}:\033[0m Ignoring White Balance..."
BALANCE="1.000000 1.000000 1.000000"
fi
#Finally, set the white balance after determining it.
if [ $isScale = false ]; then
BALANCE=$(normToOne "$BALANCE")
fi
green=$(getGreen "$BALANCE")
WHITE="-r ${BALANCE} ${green}"
echo -e "Correction Factor (RGBG): ${BALANCE} ${green}\n"
#Move .wav.
SOUND_PATH="${TMP}/${TRUNC_ARG}_.wav"
if [ ! -f $SOUND_PATH ]; then
echo -e "*Not moving .wav, because it doesn't exist.\n"
else
echo -e "*Moving .wav.\n"
cp $SOUND_PATH $FILE
fi
#DEFINE PROCESSING FUNCTIONS
dcrawOpt() { #Find, develop, and splay raw DNG data as ppm, ready to be processed.
find "${TMP}" -maxdepth 1 -iname "*.dng" -print0 | sort -z | tr -d "\n" | xargs -0 \
$DCRAW -c -q $DEMO_MODE $FOUR_COLOR -k $BLACK_LEVEL $SATPOINT $BADPIXELS $WHITE -H $HIGHLIGHT_MODE -g $GAMMA $WAVE_NOISE -o $SPACE $DEPTH
} #Is prepared to pipe all the files in TMP outwards.
dcrawImg() { #Find and splay image sequence data as ppm, ready to be processed by ffmpeg. Not working well.
find "${SEQ}" -maxdepth 1 -iname "*.${IMG_FMT}" -print0 | sort -z | xargs -0 -I {} convert '{}' -set colorspace sRGB -colorspace RGB ppm:-
} #Finds all images, prints to stdout, without any operations, using convert. ppm conversion is inevitably slow, however...
mov_main() {
ffmpeg -f image2pipe -vcodec ppm -r $FPS -i pipe:0 \
-loglevel panic -stats $SOUND -vcodec prores_ks -pix_fmt rgb48be -n -r $FPS -profile:v 4444 -alpha_bits 0 -vendor ap4h $V_FILTERS $SOUND_ACTION "${VID}_hq.mov"
} #-loglevel panic -stats
mov_prox() {
ffmpeg -f image2pipe -vcodec ppm -r $FPS -i pipe:0 \
-loglevel panic -stats $SOUND -c:v libx264 -n -r $FPS -preset fast $V_FILTERS_PROX -crf 23 -c:a mp3 "${VID}_lq.mp4"
} #The option -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" fixes when x264 is unhappy about non-2 divisible dimensions.
mov_main_img() {
ffmpeg -start_number $FRAME_START -loglevel panic -stats -f image2 -i ${SEQ}/${TRUNC_ARG}_%06d.${IMG_FMT} $SOUND -vcodec prores_ks \
-pix_fmt rgb48le -n -r $FPS -profile:v 4444 -alpha_bits 0 -vendor ap4h $V_FILTERS $SOUND_ACTION "${VID}_hq.mov"
}
mov_prox_img() {
ffmpeg -start_number $FRAME_START -loglevel panic -stats -f image2 -i ${SEQ}/${TRUNC_ARG}_%06d.${IMG_FMT} $V_FILTERS_PROX $SOUND -c:v libx264 \
-n -r $FPS -preset veryfast -crf 21 -c:a mp3 -b:a 320k "${VID}_lq.mp4"
}
runSim() {
# Command: cat $PIPE | cmd1 & cmdOrig | tee $PIPE | cmd2
# cat $PIPE | cmd1 - gives output of pipe live. Pipes it into cmd1. Nothing yet; just setup.
# & - runs the next part in the background.
# cmdOrig | tee $PIPE | cmd2 - cmdOrig pipes into the tee, which splits it back into the previous pipe, piping on to cmd2!
# End Result: Output of cmdOrig is piped into cmd1 and cmd2, which execute, both printing to stdout.
cmdOrig=$1
cmd1=$2
cmd2=$3
#~ echo $cmdOrig $cmd1 $cmd2
#~ echo $($cmdOrig)
PIPE="${TMP}/pipe_vid" # $(date +%s%N | cut -b1-13)"
mkfifo $PIPE 2>/dev/null
cat $PIPE | $cmd1 & $cmdOrig | tee $PIPE | $cmd2 #The magic of simultaneous execution ^_^
#~ cat $PIPE | tr 'e' 'a' & echo 'hello' | tee $PIPE | tr 'e' 'o' #The magic of simultaneous execution ^_^
}
img_par() { #Takes 22 arguments: {} 2$DEMO_MODE 3$FOUR_COLOR 4$BADPIXELS 5$WHITE 6$HIGHLIGHT_MODE 7$GAMMA 8$WAVE_NOISE 9$DEPTH 10$SEQ 11$TRUNC_ARG 12$IMG_FMT 13$FRAME_END 14$DEPTH_OUT 15$COMPRESS 16$isJPG 17$PROXY_SCALE 18$PROXY 19$BLACK_LEVEL 20$SPACE 21$SATPOINT 22$DCRAW 23$FFMPEG_FILTERS
count=$(echo $(echo $1 | rev | cut -d "_" -f 1 | rev | cut -d "." -f 1 | grep "[0-9]") | bc) #Instead of count from file, count from name!
DCRAW=${22}
DPXHACK=""
if [[ ${12^^} == "DPX" && ( ${23} == false ) ]]; then DPXHACK="-colorspace sRGB"; else DPXHACK=""; fi
#Trust me, I've tried everything else; but this sRGB transform works. Must be an IM bug. Keep an eye on it!
#The sRGB curve is only applied if going to DPX while DPX is the target image format. Aka. At the end; not in the middle.
if [ ${16} == true ]; then
$DCRAW -c -q $2 $3 $4 $5 -H $6 -k ${19} ${21} -g $7 $8 -o ${20} $9 $1 | \
tee >(convert ${14} - -set colorspace RGB ${DPXHACK} ${15} $(printf "${10}/${11}_%06d.${12}" ${count})) | \
convert - -set colorspace XYZ -quality 80 -colorspace sRGB -resize ${17} $(printf "${18}/${11}_%06d.jpg" ${count})
#JPGs don't get ffmpeg filters applied. They simply can't handle it.
echo -e "\033[2K\rDNG to ${12^^}/JPG: Frame ${count^^}/${13}\c"
else
$DCRAW -c -q $2 $3 $4 $5 -H $6 -k ${19} ${21} -g $7 $8 -o ${20} $9 $1 | \
convert ${14} - -set colorspace RGB ${DPXHACK} ${15} $(printf "${10}/${11}_%06d.${12}" ${count})
echo -e "\033[2K\rDNG to ${12^^}: Frame ${count^^}/${13}\c"
fi
}
#~ See http://www.imagemagick.org/discourse-server/viewtopic.php?t=21161
export -f img_par
#PROCESSING
#IMAGE PROCESSING
if [ $IMAGES == true ] ; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Processing Image Sequence from Frame ${FRAME_START} to ${FRAME_END}...\n"
#Define Image Directories, Create SEQ directory
SEQ="${FILE}/${IMG_FMT}_${TRUNC_ARG}"
PROXY="${FILE}/proxy_${TRUNC_ARG}"
mkdirS $SEQ
if [ $isJPG == true ]; then
mkdirS $PROXY
fi
#Define hardcoded compression based on IMG_FMT
if [ $isCOMPRESS == true ]; then
if [ $IMG_FMT == "exr" ]; then
COMPRESS="-compress piz"
elif [ $IMG_FMT == "tiff" ]; then
COMPRESS="-compress zip"
elif [ $IMG_FMT == "png" ]; then
COMPRESS="-quality 0"
elif [ $IMG_FMT == "dpx" ]; then
COMPRESS="-compress rle"
fi
fi
#Convert all the actual DNGs to IMG_FMT, in parallel.
find "${TMP}" -maxdepth 1 -name '*.dng' -print0 | sort -z | xargs -0 -I {} -P $THREADS -n 1 \
bash -c "img_par '{}' '$DEMO_MODE' '$FOUR_COLOR' '$BADPIXELS' '$WHITE' '$HIGHLIGHT_MODE' '$GAMMA' '$WAVE_NOISE' '$DEPTH' \
'$SEQ' '$TRUNC_ARG' '$IMG_FMT' '$FRAME_END' '$DEPTH_OUT' '$COMPRESS' '$isJPG' '$PROXY_SCALE' '$PROXY' '$BLACK_LEVEL' '$SPACE' '$SATPOINT' '$DCRAW' '$FFMPEG_FILTERS'"
# Removed | cut -d '' -f $FRAME_RANGE , as this happens when creating the DNGs in the first place.
if [ $isJPG == true ]; then #Make it print "Frame $FRAMES / $FRAMES" as the last output :).
echo -e "\033[2K\rDNG to ${IMG_FMT^^}/JPG: Frame ${FRAME_END}/${FRAME_END}\c"
else
echo -e "\033[2K\rDNG to ${IMG_FMT^^}: Frame ${FRAME_END}/${FRAME_END}\c"
fi
echo -e "\n"
tConvert() { #Arguments: 1$inFolder 2$outFolder 3$fromFMT 4$toFMT
inFolder=$1
outFolder=$2
fromFMT=$3
toFMT=$4
iccProf=$5
if [[ ! -z $iccProf ]]; then iccProf="+profile icm -profile $iccProf"; fi
conv_par() { # Arguments: 1${} 2$TRUNC_ARG 3$outFolder 4$fromFMT 5$iccProf 6$toFMT 7$DEPTH_OUT 8$compress 9$FRAME_END 10$IMG_FMT
count=$(echo $(echo $1 | rev | cut -d "_" -f 1 | rev | cut -d "." -f 1 | grep "[0-9]") | bc) #Get count from filename.
echo -e "\033[2K\rMiddle-step: ${4^^} to ${6^^}, Frame ${count^^}/${9}\c"
DPXHACK=""
if [[ ${6^^} == "DPX" && ${10^^} == ${6^^} ]]; then DPXHACK="-colorspace sRGB"; else DPXHACK=""; fi
#Trust me, I've tried everything else; but this sRGB transform works. Must be an IM bug. Keep an eye on it!
#The sRGB curve is only applied if going to DPX while DPX is the target image format. Aka. At the end; not in the middle.
convert ${7} ${1} ${5} $8 -set colorspace RGB ${DPXHACK} "${3}/$(printf "${2}_%06d" ${count}).${6}"
}
export -f conv_par
compress=""
if [[ ${IMG_FMT^^} == ${toFMT^^} ]]; then compress=${COMPRESS}; fi
find $inFolder -iname "*.${fromFMT}" -print0 | sort -z | xargs -0 -I {} -P $THREADS -n 1 \
bash -c "conv_par '{}' '$TRUNC_ARG' '$outFolder' '$fromFMT' '$iccProf' '$toFMT' '$DEPTH_OUT' '$compress' '$FRAME_END' '$IMG_FMT'"
echo ""
}
#FFMPEG Filter Application: Temporal Denoising, 3D LUTs, Deshake, hqdn Denoising, removegrain denoising, unsharp so far.
#See construction of $V_FILTERS in PREPARATION.
if [[ $FFMPEG_FILTERS == true ]]; then
tmpFiltered="${TMP}/filtered"
tmpUnfiltered="${TMP}/unfiltered"
mkdir $tmpFiltered
mkdir $tmpUnfiltered
#Give correct output.
echo -e "\033[1mApplying Filters:\033[0m $(joinArgs ", " "${FILTER_ARR[@]}")...\n"
applyFilters() { #Ideally, this would be all we need. But alas, ffmpeg + exr is broken.
IO=$1
FMT=$2
if [[ -z $FMT ]]; then FMT="${IMG_FMT}"; fi
ffmpeg -start_number $FRAME_START -f image2 -i "${IO}/${TRUNC_ARG}_%06d.${FMT}" -loglevel panic -stats $V_FILTERS \
-pix_fmt rgb48be -start_number $FRAME_START "${tmpFiltered}/${TRUNC_ARG}_%06d.${FMT}"
tConvert "$tmpFiltered" "$IO" "$FMT" "$FMT" # "/home/sofus/subhome/src/convmlv/color/lin_xyz--srgb_srgb.icc" - profile application didn't work...
}
if [[ $IMG_FMT == "exr" ]]; then
echo -e "Note: EXR filtering lags due to middle-step conversion (ffmpeg has no EXR encoder).\n"
img_res=$(identify ${SEQ}/${TRUNC_ARG}_$(printf "%06d" $(echo "$FRAME_START" | bc)).${IMG_FMT} | cut -d$' ' -f3)
tConvert "$SEQ" "$tmpUnfiltered" "$IMG_FMT" "dpx"
ffmpeg -start_number $FRAME_START -f image2 -vcodec dpx -s "${img_res}" -r $FPS -loglevel panic -stats -i "${tmpUnfiltered}/${TRUNC_ARG}_%06d.dpx" \
$V_FILTERS -pix_fmt rgb48be -vcodec dpx -n -r $FPS -start_number $FRAME_START ${tmpFiltered}/${TRUNC_ARG}_%06d.dpx
tConvert "$tmpFiltered" "$SEQ" "dpx" "$IMG_FMT"
else
applyFilters "$SEQ"
fi
echo ""
fi
fi
#MOVIE PROCESSING
VID="${FILE}/${TRUNC_ARG}"
SOUND="-i ${TMP}/${TRUNC_ARG}_.wav"
SOUND_ACTION="-c:a mp3 -b:a 320k"
if [ ! -f $SOUND_PATH ]; then
SOUND=""
SOUND_ACTION=""
fi
if [[ $MOVIE == true && $IMAGES == false && $isH264 == true ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to ProRes/H.264..."
runSim dcrawOpt mov_main mov_prox
echo ""
elif [[ $MOVIE == true && $IMAGES == false && $isH264 == false ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to ProRes..."
dcrawOpt | mov_main
echo ""
elif [[ $MOVIE == false && $IMAGES == false && $isH264 == true ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to H.264..."
dcrawOpt | mov_prox
echo ""
elif [[ $IMAGES == true ]]; then
V_FILTERS="" #Only needed if reading from images.
V_FILTERS_PROX="-vf $FINAL_SCALE"
if [[ $IMG_FMT == "dpx" ]]; then
V_FILTERS="-vf lut3d=${COLOR_LUTS[0]}/srgb--lin.cube"
V_FILTERS_PROX="-vf lut3d=${COLOR_LUTS[0]}/srgb--lin.cube,$FINAL_SCALE" #We apply a sRGB to Linear 1D LUT if reading DPX. Because it's fucking broken.
fi
#Use images if available, as opposed to developing the files again.
if [[ $MOVIE == true && $isH264 == true ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to ProRes/H.264..."
mov_main_img &
mov_prox_img &
wait
echo ""
elif [[ $MOVIE == true && $isH264 == false ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to ProRes..."
mov_main_img
echo ""
elif [[ $MOVIE == false && $isH264 == true ]]; then
echo -e "\033[1m${TRUNC_ARG}:\033[0m Encoding to H.264..."
mov_prox_img
echo ""
fi
fi
#Potentially move DNGs.
if [ $KEEP_DNGS == true ]; then
echo -e "\033[1mMoving DNGs...\033[0m"
DNG="${FILE}/dng_${TRUNC_ARG}"
mkdirS $DNG
if [ $DUAL_ISO == true ]; then
oldFiles="${TMP}/orig_dng"
find $oldFiles -name "*.dng" | xargs -I '{}' mv {} $DNG #Preserve the original, unprocessed DNGs.
else
find $TMP -name "*.dng" | xargs -I '{}' mv {} $DNG
fi
fi
echo -e "\n\033[1mCleaning Up.\033[0m\n\n"
#Delete tmp
rm -rf $TMP
#RESET ARGS & REPARSE OPTIONS - same as in convmlv.sh.
#Big parse/reparse, making sure global, local, command line options all override each other correctly.
set -- $INPUT_ARGS #Reset the argument input for reparsing.
setDefaults #Hard set/reset all the lovely globals.
OPTIND=1 #Reset argument parsing.
parseConf "$GCONFIG" false #Parse global config file.
parseArgs "$@" #First, parse all cli args. We only need the -C flag, but that forces us to just parse everything.
shift $((OPTIND-1)) #Shift past all of the options to the file arguments.
parseConf "$LCONFIG" false #Parse local config file.
set -- $INPUT_ARGS #Reset $@ for cli option reparsing.
OPTIND=1 #To reset argument parsing, we must set OPTIND to 1.
parseArgs "$@" #Reparse cli to overwrite local config options.
shift $((OPTIND-1)) #Shift past all of the options to the file arguments.
OPTIND=1 #Reset argument index.
let ARGNUM--
done
}

757
src/core/parsing.sh 100644
View File

@ -0,0 +1,757 @@
parseConf() {
file=$1 #The File to Parse
argOnly=$2 #If true, will only use file-specific blocks. If false, will ignore file-specific blocks.
CONFIG_NAME="None"
if [[ -z $file ]]; then return; fi
if [[ ! -f $file ]]; then return; fi
local fBlock=false #Whether or not we are in a file-specific block.
local fID="" #The name of the file-specific block we're in.
while IFS="" read -r line || [[ -n "$line" ]]; do
line=$(echo "$line" | sed -e 's/^[ \t]*//') #Strip leading tabs/whitespaces.
if [[ `echo "${line}" | cut -c1-1` == "#" ]]; then continue; fi #Ignore comments
if [[ `echo "${line}" | cut -c1-1` == "/" ]]; then
if [[ $fBlock == true ]]; then invOption "ERROR: Nested file-specific blocks in config file $CONFIG_NAME!"; fi
fBlock=true
fID=`echo "${line}" | cut -d$' ' -f2`
continue
fi #Enter a file-specific block with /, provided the argument name is correct.
if [[ `echo "${line}" | cut -c1-1` == "*" ]]; then fBlock=false; fID=""; fi #Leave a file-specific block.
#~ echo $argOnly $fBlock $fID ${TRUNC_ARG%.*} `echo "${line}" | cut -d$' ' -f1`
if [[ ($argOnly == false && $fBlock == false) || ( ($argOnly == true && $fBlock == true) && $fID == ${TRUNC_ARG%.*} ) ]]; then #Conditions under which to write values.
case `echo "${line}" | cut -d$' ' -f1` in
"CONFIG_NAME") CONFIG_NAME=`echo "${line}" | cut -d$' ' -f2` #Not doing anything with this right now.
;;
"OUTDIR") OUTDIR=`echo "${line}" | cut -d$' ' -f2`
;;
"BIN_PATH") BIN_PATH=`echo "${line}" | cut -d$' ' -f2`; setPaths
;;
"DCRAW") DCRAW=`echo "${line}" | cut -d$' ' -f2`
;;
"MLV_DUMP") MLV_DUMP=`echo "${line}" | cut -d$' ' -f2`
;;
"RAW_DUMP") RAW_DUMP=`echo "${line}" | cut -d$' ' -f2`
;;
"MLV_BP") MLV_BP=`echo "${line}" | cut -d$' ' -f2`
;;
"SRANGE") CR_HDR=`echo "${line}" | cut -d$' ' -f2`
;;
"BAL") PYTHON_SRANGE=`echo "${line}" | cut -d$' ' -f2`; setPaths
;;
"PYTHON") PYTHON=`echo "${line}" | cut -d$' ' -f2`; setPaths
;;
"THREADS") THREADS=`echo "${line}" | cut -d$' ' -f2`
;;
"IMAGE") IMAGES=true
;;
"IMG_FMT")
mode=`echo "${line}" | cut -d$' ' -f2`
case ${mode} in
"0") IMG_FMT="exr"
;;
"1") IMG_FMT="tiff"
;;
"2") IMG_FMT="png"
;;
"3") IMG_FMT="dpx"
;;
*) invOption "Invalid Image Format Choice: ${mode}"
;;
esac
;;
"MOVIE") MOVIE=true
;;
"PROXY")
PROXY=`echo "${line}" | cut -d$' ' -f2`
case ${PROXY} in
"0") isJPG=false; isH264=false
;;
"1") isJPG=false; isH264=true
;;
"2") isJPG=true; isH264=false
;;
"3") isJPG=true; isH264=true
;;
*) invOption "Invalid Proxy Choice: ${PROXY}"
;;
esac
;;
"PROXY_SCALE")
PROXY_SCALE=`echo "${line}" | cut -d$' ' -f2`
proxy_num=`echo "$PROXY_SCALE" | cut -d'%' -f 1`
if [[ ! ( ($proxy_num -le 100 && $proxy_num -ge 5) && $proxy_num =~ ^-?[0-9]+$ ) ]]; then invOption "Invalid Proxy Scale: ${PROXY_SCALE}"; fi
;;
"KEEP_DNGS") KEEP_DNGS=true
;;
"FRAME_RANGE") RANGE_BASE=`echo "${line}" | cut -d$' ' -f2`; isFR=false
;;
"UNCOMP") isCOMPRESS=false
;;
"DEMO_MODE") DEMO_MODE=`echo "${line}" | cut -d$' ' -f2`
;;
"HIGHLIGHT_MODE") HIGHLIGHT_MODE=`echo "${line}" | cut -d$' ' -f2`
;;
"CHROMA_SMOOTH")
mode=`echo "${line}" | cut -d$' ' -f2`
case ${mode} in
"0") CHROMA_SMOOTH="--no-cs"
;;
"1") CHROMA_SMOOTH="--cs2x2"
;;
"2") CHROMA_SMOOTH="--cs3x3"
;;
"3") CHROMA_SMOOTH="--cs5x5"
;;
*) invOption "Invalid Chroma Smoothing Choice: ${mode}"
;;
esac
;;
"WAVE_NOISE") WAVE_NOISE="-n $(echo "${line}" | cut -d$' ' -f2)"
;;
"TEMP_NOISE")
vals="$(echo "${line}" | cut -d$' ' -f2)"
aVal=$(echo "${vals}" | cut -d"-" -f1)
bVal=$(echo "${vals}" | cut -d"-" -f2)
TEMP_NOISE="atadenoise=0a=${aVal}:0b=${bVal}:1a=${aVal}:1b=${bVal}:2a=${aVal}:2b=${bVal}"
tempDesc="Temporal Denoiser"
FFMPEG_FILTERS=true
;;
"HQ_NOISE")
vals="$(echo "${line}" | cut -d$' ' -f2)"
S=`echo "${vals}" | cut -d$':' -f1`
T=`echo "${vals}" | cut -d$':' -f2`
LS=`echo "${S}" | cut -d$'-' -f1`
CS=`echo "${S}" | cut -d$'-' -f2`
LT=`echo "${T}" | cut -d$'-' -f1`
CT=`echo "${T}" | cut -d$'-' -f2`
HQ_NOISE="hqdn3d=luma_spatial=${LS}:chroma_spatial=${CS}:luma_tmp=${LT}:chroma_tmp=${CT}"
hqDesc="3D Denoiser"
FFMPEG_FILTERS=true
;;
"REM_NOISE")
vals="$(echo "${line}" | cut -d$' ' -f2)"
m1=`echo "${vals}" | cut -d$'-' -f1`
m2=`echo "${vals}" | cut -d$'-' -f2`
m3=`echo "${vals}" | cut -d$'-' -f3`
m4=`echo "${vals}" | cut -d$'-' -f4`
REM_NOISE="removegrain=m0=${m1}:m1=${m2}:m2=${m3}:m3=${m4}"
remDesc="RemoveGrain Modal Denoiser"
FFMPEG_FILTERS=true
;;
"GAMMA") #Value checking done in color management.
mode=`echo "${line}" | cut -d$' ' -f2`
case ${mode} in
"0")
COLOR_GAMMA="STANDARD" #Lets CM know that it should correspond to the gamut, or be 2.2.
;;
"1")
COLOR_GAMMA="lin" #Linear
;;
"2")
COLOR_GAMMA="cineon" #Cineon
;;
"3")
COLOR_GAMMA="clog2" #C-Log2. Req: color-ext.
;;
"4")
COLOR_GAMMA="slog3" #S-Log3. Req: color-ext.
;;
#~ "5")
#~ COLOR_GAMMA="logc" #LogC 4.X . Req: color-ext.
#~ ;;
#~ "6")
#~ COLOR_GAMMA="acescc" #ACEScc Log Gamma. Req: color-aces.
#~ ;;
*)
invOption "g: Invalid Gamma Choice: ${mode}"
;;
esac
;;
"GAMUT") #Value checking done in color management.
mode=`echo "${line}" | cut -d$' ' -f2`
case ${mode} in
"0")
COLOR_GAMUT="srgb" #sRGB
;;
"1")
COLOR_GAMUT="argb" #Adobe RGB
;;
"2")
COLOR_GAMUT="rec709" #Rec.709
;;
"3")
COLOR_GAMUT="xyz" #XYZ. Linear Only.
;;
#~ "3")
#~ COLOR_GAMUT="aces" #ACES. Standard is Linear. Req: color-aces (all gammas will work, even without color-ext)/
#~ ;;
#~ "4")
#~ COLOR_GAMUT="xyz" #ACES. Standard is Linear. Req: color-aces (all gammas will work, even without color-ext)/
#~ ;;
"4")
COLOR_GAMUT="rec2020" #Rec.2020. Req: color-ext.
;;
"5")
COLOR_GAMUT="dcip3" #DCI-P3. Req: color-ext.
;;
"6")
COLOR_GAMUT="ssg3c" #Sony S-Gamut3.cine. Req: color-ext.
;;
*)
invOption "G: Invalid Gamut Choice: ${mode}"
;;
esac
;;
"SHALLOW") DEPTH=""; DEPTH_OUT="-depth 8"
;;
"WHITE")
mode=`echo "${line}" | cut -d$' ' -f2`
case ${mode} in
"0") CAMERA_WB=false; GEN_WHITE=true #Will generate white balance.
;;
"1") CAMERA_WB=true; GEN_WHITE=false; #Will use camera white balance.
;;
"2") WHITE="-r 1 1 1 1"; CAMERA_WB=false; GEN_WHITE=false #Will not apply any white balance.
;;
*)
invOption "Invalid White Balance Choice: ${mode}"
;;
esac
;;
"SHARP")
val=`echo "${line}" | cut -d$' ' -f2`
lSize=`echo "${val}" | cut -d$':' -f1`
lStr=`echo "${val}" | cut -d$':' -f2`
cSize=`echo "${val}" | cut -d$':' -f3`
cStr=`echo "${val}" | cut -d$':' -f4`
SHARP="unsharp=${lSize}:${lSize}:${lStr}:${cSize}:${cSize}:${cStr}"
sharpDesc="Sharpen/Blur"
FFMPEG_FILTERS=true
;;
"LUT")
LUT_PATH=`echo "${line}" | cut -d$' ' -f2`
if [ ! -f $LUT_PATH ]; then invOption "Invalid LUT Path: ${LUT_PATH}"; fi
#Check LUT_SIZE
i=0
while read line; do
sLine=$(echo $line | sed -e 's/^[ \t]*//')
if [[ $(echo $sLine | cut -c1-11) == "LUT_3D_SIZE" ]]; then
if [[ $(echo $sLine | cut -c13-) -le 64 && $(echo $sLine | cut -c13-) -ge 2 ]]; then
break
else
size=$(echo $sLine | cut -c13-)
invOption "$(basename $LUT_PATH): Invalid LUT Size of $size x $size x $size - Must be between x2 and x64 (you can resize using pylut - see 'convmlv -h') ! "
fi
elif [[ $i -gt 20 ]]; then
invOption "$(basename $LUT_PATH): Invalid LUT - LUT_3D_SIZE not found in first 20 non-commented lines."
fi
if [[ ! $(echo $sLine | cut -c1-1) == "#" ]]; then ((i++)); fi
done < $LUT_PATH
LUTS+=( "lut3d=${LUT_PATH}" )
lutDesc="3D LUTs"
FFMPEG_FILTERS=true
;;
"SATPOINT") SATPOINT="-S $(echo "${line}" | cut -d$' ' -f2)"
;;
"WHITE_SPD") WHITE_SPD=`echo "${line}" | cut -d$' ' -f2`
;;
"WHITE_CLIP") isScale=true
;;
"DESHAKE")
DESHAKE="deshake"
deshakeDesc="Deshake Filter"
FFMPEG_FILTERS=true
;;
"DUAL_ISO") DUAL_ISO=true
;;
"BADPIXELS") isBP=true
;;
"BADPIXEL_PATH") BADPIXEL_PATH=`echo "${line}" | cut -d$' ' -f2`
;;
"DARKFRAME")
DARKFRAME=`echo "${line}" | cut -d$' ' -f2`;
if [ ! -f $DARKFRAME ]; then invOption "Invalid Darkframe: ${DARKFRAME}"; fi
useDF=true
;;
esac
fi
done < "$1"
}
parseArgs() { #Amazing new argument parsing!!!
longArg() { #Creates VAL
ret="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
}
while getopts "vh C: o: P: T: i t: m p: s: k r: d: f H: c: n: N: Q: O: g: G: w: A: l: S: D u b a: F: R: q K: Y M -:" opt; do
#~ echo $opt ${OPTARG}
case "$opt" in
-) #Long Arguments
case ${OPTARG} in
outdir)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
OUTDIR=$val
;;
version)
PROGRAM="version"
;;
help)
PROGRAM="help"
;;
config)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
LCONFIG=$val
;;
bin-path)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
BIN_PATH=$val
setPaths #Set all the paths with the new BIN_PATH.
;;
dcraw)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
DCRAW="${val}"
;;
mlv-dump)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
MLV_DUMP=$val
;;
raw-dump)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
RAW_DUMP=$val
;;
badpixels)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
MLV_BP=$val
;;
cr-hdr)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
CR_HDR=$val
;;
srange)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
PYTHON_BAL=$val
setPaths #Must regen BAL
;;
balance)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
PYTHON_SRANGE=$val
setPaths #Must regen SRANGE
;;
python)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
PYTHON=$val
setPaths #Set all the paths with the new PYTHON.
;;
threads)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
THREADS=$val
;;
uncompress)
isCOMPRESS=false
;;
shallow)
DEPTH=""
DEPTH_OUT="-depth 8"
;;
white-speed)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
WHITE_SPD=$val
;;
allow-white-clip)
isScale=true
;;
*)
echo "Invalid option: --$OPTARG" >&2
;;
esac
;;
v)
PROGRAM="version"
;;
h)
PROGRAM="help"
;;
C)
LCONFIG=${OPTARG}
;;
o)
OUTDIR=${OPTARG}
;;
P)
BIN_PATH=${OPTARG}
setPaths #Set all the binary paths with the new BIN_PATH.
;;
T)
THREADS=${OPTARG}
;;
i)
IMAGES=true
;;
t)
mode=${OPTARG}
case ${mode} in
"0") IMG_FMT="exr"
;;
"1") IMG_FMT="tiff"
;;
"2") IMG_FMT="png"
;;
"3") IMG_FMT="dpx"
;;
*) invOption "t: Invalid Image Format Choice: ${mode}"
;;
esac
;;
m)
MOVIE=true
;;
p)
PROXY=${OPTARG}
case ${PROXY} in
"0") isJPG=false; isH264=false
;;
"1") isJPG=false; isH264=true
;;
"2") isJPG=true; isH264=false
;;
"3") isJPG=true; isH264=true
;;
*) invOption "p: Invalid Proxy Choice: ${PROXY}"
;;
esac
;;
s)
PROXY_SCALE=${OPTARG}
proxy_num=`echo "$PROXY_SCALE" | cut -d'%' -f 1`
if [[ ! ( ($proxy_num -le 100 && $proxy_num -ge 5) && $proxy_num =~ ^-?[0-9]+$ ) ]]; then invOption "s: Invalid Proxy Scale: ${PROXY_SCALE}"; fi
;;
k)
KEEP_DNGS=true
;;
r)
RANGE_BASE=${OPTARG}
isFR=false
;;
d)
DEMO_MODE=${OPTARG}
;;
f)
FOUR_COLOR="-f"
;;
H)
HIGHLIGHT_MODE=${OPTARG}
;;
c)
mode=${OPTARG}
case ${mode} in
"0") CHROMA_SMOOTH="--no-cs"
;;
"1") CHROMA_SMOOTH="--cs2x2"
;;
"2") CHROMA_SMOOTH="--cs3x3"
;;
"3") CHROMA_SMOOTH="--cs5x5"
;;
*) invOption "c: Invalid Chroma Smoothing Choice: ${mode}"
;;
esac
;;
n)
WAVE_NOISE="-n ${OPTARG}"
;;
N)
vals=${OPTARG}
aVal=$(echo "${vals}" | cut -d"-" -f1)
bVal=$(echo "${vals}" | cut -d"-" -f2)
TEMP_NOISE="atadenoise=0a=${aVal}:0b=${bVal}:1a=${aVal}:1b=${bVal}:2a=${aVal}:2b=${bVal}"
tempDesc="Temporal Denoiser"
FFMPEG_FILTERS=true
;;
Q)
vals=${OPTARG}
S=`echo "${vals}" | cut -d$':' -f1`
T=`echo "${vals}" | cut -d$':' -f2`
LS=`echo "${S}" | cut -d$'-' -f1`
CS=`echo "${S}" | cut -d$'-' -f2`
LT=`echo "${T}" | cut -d$'-' -f1`
CT=`echo "${T}" | cut -d$'-' -f2`
HQ_NOISE="hqdn3d=luma_spatial=${LS}:chroma_spatial=${CS}:luma_tmp=${LT}:chroma_tmp=${CT}"
hqDesc="3D Denoiser"
FFMPEG_FILTERS=true
;;
O)
vals=${OPTARG}
m1=`echo "${vals}" | cut -d$'-' -f1`
m2=`echo "${vals}" | cut -d$'-' -f2`
m3=`echo "${vals}" | cut -d$'-' -f3`
m4=`echo "${vals}" | cut -d$'-' -f4`
REM_NOISE="removegrain=m0=${m1}:m1=${m2}:m2=${m3}:m3=${m4}"
remDesc="RemoveGrain Modal Denoiser"
FFMPEG_FILTERS=true
;;
g)
mode=${OPTARG}
case ${mode} in
"0")
COLOR_GAMMA="STANDARD" #Lets CM know that it should correspond to the gamut, or be 2.2.
;;
"1")
COLOR_GAMMA="lin" #Linear
;;
"2")
COLOR_GAMMA="cineon" #Cineon
;;
"3")
COLOR_GAMMA="clog2" #C-Log2. Req: color-ext.
;;
"4")
COLOR_GAMMA="slog3" #S-Log3. Req: color-ext.
;;
#~ "5")
#~ COLOR_GAMMA="logc" #LogC 4.X . Req: color-ext.
#~ ;;
#~ "6")
#~ COLOR_GAMMA="acescc" #ACEScc Log Gamma. Req: color-aces.
#~ ;;
*)
invOption "g: Invalid Gamma Choice: ${mode}"
;;
esac
;;
G)
mode=${OPTARG}
case ${mode} in
"0")
COLOR_GAMUT="srgb" #sRGB
;;
"1")
COLOR_GAMUT="argb" #Adobe RGB
;;
"2")
COLOR_GAMUT="rec709" #Rec.709
;;
"3")
COLOR_GAMUT="xyz" #XYZ. Linear Only.
;;
#~ "4")
#~ COLOR_GAMUT="aces" #ACES. Standard is Linear. Req: color-aces (all gammas will work, even without color-ext)/
#~ ;;
"4")
COLOR_GAMUT="rec2020" #Rec.2020. Req: color-ext.
;;
"5")
COLOR_GAMUT="dcip3" #DCI-P3. Req: color-ext.
;;
"6")
COLOR_GAMUT="ssg3c" #Sony S-Gamut3.cine. Req: color-ext.
;;
*)
invOption "G: Invalid Gamut Choice: ${mode}"
;;
esac
;;
w)
mode=${OPTARG}
case ${mode} in
"0") CAMERA_WB=false; GEN_WHITE=true #Will generate white balance.
;;
"1") CAMERA_WB=true; GEN_WHITE=false; #Will use camera white balance.
;;
"2") WHITE="-r 1 1 1 1"; CAMERA_WB=false; GEN_WHITE=false #Will not apply any white balance.
;;
*)
invOption "w: Invalid White Balance Choice: ${mode}"
;;
esac
;;
A)
val=${OPTARG}
lSize=`echo "${val}" | cut -d$':' -f1`
lStr=`echo "${val}" | cut -d$':' -f2`
cSize=`echo "${val}" | cut -d$':' -f3`
cStr=`echo "${val}" | cut -d$':' -f4`
SHARP="unsharp=${lSize}:${lSize}:${lStr}:${cSize}:${cSize}:${cStr}"
sharpDesc="Sharpen/Blur"
FFMPEG_FILTERS=true
;;
l)
LUT_PATH=${OPTARG}
if [ ! -f $LUT_PATH ]; then invOption "Invalid LUT Path: ${LUT_PATH}"; fi
#Check LUT_SIZE
i=0
while read line; do
sLine=$(echo $line | sed -e 's/^[ \t]*//')
if [[ $(echo $sLine | cut -c1-11) == "LUT_3D_SIZE" ]]; then
if [[ $(echo $sLine | cut -c13-) -le 64 && $(echo $sLine | cut -c13-) -ge 2 ]]; then
break
else
size=$(echo $sLine | cut -c13-)
invOption "$(basename $LUT_PATH): Invalid LUT Size of $size x $size x $size - Must be between x2 and x64 (you can resize using pylut - see 'convmlv -h') ! "
fi
elif [[ $i -gt 20 ]]; then
invOption "$(basename $LUT_PATH): Invalid LUT - LUT_3D_SIZE not found in first 20 non-commented lines."
fi
if [[ ! $(echo $sLine | cut -c1-1) == "#" ]]; then ((i++)); fi
done < $LUT_PATH
LUTS+=( "lut3d=${LUT_PATH}" )
lutDesc="3D LUTs"
FFMPEG_FILTERS=true
;;
S)
SATPOINT="-S ${OPTARG}"
;;
D)
DESHAKE="deshake"
deshakeDesc="Deshake Filter"
FFMPEG_FILTERS=true
;;
u)
DUAL_ISO=true
;;
b)
isBP=true
;;
a)
BADPIXEL_PATH=${OPTARG}
BADPIXEL_PATH=${OPTARG}
;;
F)
DARKFRAME=`echo "${line}" | cut -d$' ' -f2`;
if [ ! -f $DARKFRAME ]; then invOption "F: Invalid Darkframe: ${DARKFRAME}"; fi
useDF=true
;;
R)
PROGRAM="darkframe"
#~ MK_DARK=true
DARK_OUT=${OPTARG}
;;
q)
PROGRAM="settings"
#~ SETTINGS_OUTPUT=true
;;
K)
mode=${OPTARG}
case ${mode} in
"0") echo $DEB_DEPS
;;
"1") echo $UBU_DEPS
;;
"2") echo $FED_DEPS
;;
"3") echo $BREW_DEPS
;;
*)
invOption "K: Invalid Dist Choice: ${mode}"
;;
esac
exit 0
;;
Y)
echo $PIP_DEPS
exit 0
;;
M)
echo $MAN_DEPS
exit 0
;;
*)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
}
parseAll() {
#Big parse/reparse, making sure global, local, command line options all override each other correctly.
set -- $INPUT_ARGS #Reset the argument input for reparsing.
setDefaults #Hard set/reset all the lovely globals.
OPTIND=1 #Reset argument parsing.
parseConf "$GCONFIG" false #Parse global config file.
parseArgs "$@" #First, parse all cli args. We only need the -C flag, but that forces us to just parse everything.
shift $((OPTIND-1)) #Shift past all of the options to the file arguments.
parseConf "$LCONFIG" false #Parse local config file.
set -- $INPUT_ARGS #Reset $@ for cli option reparsing.
OPTIND=1 #To reset argument parsing, we must set OPTIND to 1.
parseArgs "$@" #Reparse cli to overwrite local config options.
shift $((OPTIND-1)) #Shift past all of the options to the file arguments.
OPTIND=1 #Reset argument index.
}

View File

@ -0,0 +1,42 @@
less -R << EOF
TODO:
PLANNING:
Except for openlut integration, CM fixes, and the last throes of Mac compatibility, I consider convmlv feature-complete. As in, only bug fixes and error checking.
New developments, like special ffmpeg filters, or new techniques from the ML world, may change that. But that\'s nothing compared to the 2400 lines this pushes at the moment!
Any further effort is better focused on compatibility, bug fixes, error checking, more bug fixes, and finally a GUI app described in FUTURE.
TOP PRIORITY
--> Fix Color Management; -o 5 is broken. Use -o 0 or -o 1, supplemented by current paradigm of Rec709 -> Whatever LUTs, instead of XYZ -> Whatever LUTs.
--> MLVFS backend - run the mlvfs command, passing whatever options it supports, then rewrite ARG. Give an option to choose mlv_dump or mlvfs, and an option for a custom path to mlvfs.
*Consider using dcraw for darkframing, through the -K option. Requires a develop from MLV, then a convert to raw PGM, first.
--> Calibration frame program & library - place in $HOME/.local/convmlv, perhaps.
--> New program: Install dependencies.
HIGH PRIORITY
--> Integrate openlut for 1D LUTs. 3D LUTs would only be used for gamut transforms, not gamut/gamma.
--> More error checking.
--> Test Mac compatibility with a *working* (with 10.7) mlv_dump...
--> Documentation: Videos.
MEDIUM PRIORITY
--> Integrate openlut for gamut ops. Matrices would replace standard 3D LUTs altogether, and openlut would handle 3D LUTs.
LOW
--> Stats for .RAW files.
FUTURE
--> A GUI app, running libraw variants, which has a CLI backend, but can also output a convmlv config file.
--> convmlv will always have more features - bash makes certain nasty things like ffmpeg filters available, as opposed to the \"code it yourself\" of true image array processing...
--> But, a GUI is usable by the average non-nerd!! You know, the users of ML.
BUG: Relative OUTDIR makes baxpixel generation fail if ./mlv2badpixels.sh doesn\'t exist. Should be fixed on all platforms.
BIG BUG: Color Management is oversaturated, destructively so.
--> See Nasty Hacks Part 1 - 3. FML :O.
EOF

View File

@ -0,0 +1,288 @@
#!/bin/bash
help() {
less -R << EOF
Usage:
$(echo -e "\033[1m./convmlv.sh\033[0m [FLAGS] [OPTIONS] \033[2mfiles\033[0m")
$(head "INFO:")
A program allowing you to develop ML files into workable formats. Many useful options are exposed.
--> Defaults: Compressed 16-bit Linear EXR. 10-bit Prores4444 MOV.
--> Color Defaults: Linear (1.0) Gamma on sRGB Gamut, using Camera White Balance.
--> Acceptable Inputs: MLV, RAW (requires raw2dng), Folder containing DNGs.
--> Option Input: From command line or config file (specify with -C).
--> Forum Post: http://www.magiclantern.fm/forum/index.php?topic=16799.
--> A note: BE CAREFUL WITH OPTIONS. Wrong values will give very strange errors. Read this page well!!
It's as simple or complex as you need it to be: 'convmlv -m <mlvfile>.mlv' is enough for good-looking output!
$(echo -e "$(head VERSION): ${VERSION}")
$(head "MANUAL DEPENDENCIES:")
Place these in RES_PATH (see OPTIONS, BASIC). Keep in mind you also need dist. and pip packages.
--> See 'Dist Deps' and 'Python Deps'
-- mlv_dump: Required binary. http://www.magiclantern.fm/forum/index.php?topic=7122.0
-- color-core: Required folder of LUTs. See convmlv repository.
-- sRange.py: Required script. See convmlv repository.
-- raw2dng: For DNG extraction from RAW. http://www.magiclantern.fm/forum/index.php?topic=5404.0
-- mlv2badpixels.sh: For bad pixel removal. https://bitbucket.org/daniel_fort/ml-focus-pixels/src
-- cr2hdr: For Dual ISO Development. Two links: http://www.magiclantern.fm/forum/index.php?topic=16799.0
-- balance.py: For Auto White Balance. See convmlv repository.
-- color-ext: Extra LUTs, providing more color resources. See convmlv repository.
$(head "OPTIONS, BASIC:")
-v, --version $(bVal version) - Print out version string.
-h, --help $(bVal help) - Print out this help page.
-C, --config $(bVal config) - Designates config file to use.
-o, --outdir <path> $(cVal OUTDIR) - The path in which files will be placed.
-P, --bin-path <path> $(iVal BIN_PATH) - The path in which all binary dependencies are looked for.
--> Default: ./binaries (the folder binaries in current folder).
--> Source Code: These components will be looked for at <location of convmlv.sh>/src.
--dcraw <path> $(cVal DCRAW) - The path to dcraw.
--mlv-dump <path> $(cVal MLV_DUMP) - The path to mlv_dump.
--raw-dump <path> $(cVal RAW_DUMP) - The path to raw2dng.
--badpixels <path> $(cVal MLV_BP) - The path to mlv2badpixels.sh (by dfort).
--cr-hdr <path> $(cVal CR_HDR) - The path to cr2hdr.
--srange <path> $(cVal SRANGE) - The path to sRange.py.
--balance <path> $(cVal BAL) - The path to balance.py.
--python <path> $(cVal PYTHON) - The path or command used to invoke Python 3. Default is python3 on Linux, python on Mac.
-T, --threads [int] $(cVal THREADS) - Override amount of utilized process threads. Default is MAX - 1.
$(head "OPTIONS, OUTPUT:")
-i $(cVal IMAGE) - Will output image sequence.
-t [0:3] $(cVal IMG_FMT) - Image output format.
--> 0: EXR (default), 1: TIFF, 2: PNG, 3: Cineon (DPX)."
-m $(cVal MOVIE) - Will output a Prores4444 file.
-p [0:3] $(cVal PROXY) - Create proxies alongside main output.
--> 0: No proxies (Default). 1: H.264 proxy. 2: JPG proxy sequence. 3: Both.
--> JPG proxy will always be in sRGB Gamma/sRGB Gamut. H.264 proxy is color managed.
--> JPG proxy *won't* be developed w/o IMAGE. H.264 proxy *will* be developed no matter what, if specified here.
--> Why? JPG is for potential use in editing. H.264 is for a quick visual preview of convmlv's output.
-s [0%:100%] $(cVal PROXY_SCALE) - the size, in %, of the proxy output.
--> Default: 50%.
-k $(cVal KEEP_DNGS) - Specify if you want to keep the DNG files.
--> Run convmlv on the top level folder of former output to reuse saved DNGs from that run!
-r <start>-<end> $(cVal FRAME_RANGE) - Specify to process an integer frame range.
--> You may use the characters 's' and 'e', such that s = start frame, e = end frame.
--> Indexed from 0 to (# of frames - 1). Develops from 1 to ($ of frames)
--> A single number may be writted to develop that single frame.
--> DO NOT try to reuse DNGs while developing a larger frame range.
--uncompress $(cVal UNCOMP) - Turns off lossless image compression. Otherwise:
--> TIFF: ZIP, EXR: PIZ, PNG: lvl 0, DPX: RLE.
$(head "OPTIONS, RAW DEVELOPMENT:")
-d [0:3] $(cVal DEMO_MODE) - Demosaicing algorithm. Higher modes are slower + better.
--> 0: Bilinear. 1: VNG (default). 2: PPG. 3: AHD.
-f $(cVal FOUR_COLOR) - Interpolate as RGBG. Fixes weirdness with VNG/AHD, at the cost of sharpness.
-H [0:9] $(cVal HIGHLIGHT_MODE) - Highlight management options.
--> 0: White, clipped highlights. 1: Unclipped but colored highlights. 2: The defail of 1, but adjusted to grey.
--> 3-9: Highlight reconstruction. Can cause flickering. Start at 5, then adjust to color (down) or to white (up).
-c [0:3] $(cVal CHROMA_SMOOTH) - Apply shadow/highlight chroma smoothing to the footage.
--> 0: None (default). 1: 2x2. 2: 3x3. 3: 5x5.
--> MLV input Only.
-n [int] $(cVal WAVE_NOISE) - Apply wavelet denoising.
--> Default: None. Subtle: 25. Medium: 50. Strong: 125.
-N <A>-<B> $(cVal TEMP_NOISE) - Apply temporal denoising.
--> A: 0 to 0.3. B: 0 to 5. A reacts to abrupt noise (splotches), B reacts to noise over time (fast motion causes artifacts).
--> Subtle: 0.03-0.04. High: 0.15-0.04. High, Predictable Motion: 0.15-0.07
-Q [i-i:i-i] $(cVal HQ_NOISE) - Apply 3D denoising filter.
--> In depth explanation: https://mattgadient.com/2013/06/29/in-depth-look-at-de-noising-in-handbrake-with-imagevideo-examples/ .
--> Spacial/Temporal (S/T). S will soften/blur/smooth, T will remove noise without doing that but may create artifacts.
--> Luma/Chroma (L/C). L is the detail, C is the color. Each one's denoising may be manipulated Spacially or Temporally.
--> Option Value: <LS>-<CS>:<LT>-<CT>
--> Weak: 2-1:2-3. Medium: 3-2:2-3. Strong: 7-7:5-5
--> DONT combine with TEMP_NOISE.
-O [i-i-i-i] $(cVal REM_NOISE) - Yet another spatial denoiser, with 4 choices of 24 modes.
--> See https://ffmpeg.org/ffmpeg-filters.html#removegrain for list of modes.
--> Option Value: <mode1>-<mode2>-<mode3>-<mode4>
--> I truly cannot tell you what values will be helpful to you; there are too many... Look at the link!
--shallow $(cVal SHALLOW) - Output smaller, 8-bit files.
--> Read why this is a bad idea: http://www.cambridgeincolour.com/tutorials/bit-depth.htm
$(head "OPTIONS, COLOR:")
-g [0:4] $(cVal GAMMA) - Output gamma. A curve applied to the output, for easier viewing/grading.
--> 0: Standard (Around 2.2). 1: Linear (Default).
--> Requires color-ext: 2: Cineon. 3: C-Log2 4: S-Log3
--> "Standard" grades to the gamut specification, and to 2.2 if that's not given.
-G [0:6] $(cVal GAMUT) - Output gamut. The range of colors that can exist in the output.
--> 0: sRGB (Default). 1: Adobe RGB. 2: Rec.709. 3: XYZ (Always Linear Gamma).
--> Requires color-ext: 4: Rec2020 5: DCI-P3 6: Sony S-Gamut3.cine
-w [0:2] $(cVal WHITE) - This is a modal white balance setting.
--> 0: Auto WB (requires balance.py). 1: Camera WB (default). 2: No Change.
--> AWB uses the Grey's World algorithm.
-A [i:i:i:i] $(cVal SHARP) - Lets you sharpen, or blur, your footage.
--> BE CAREFUL. Wrong values will give you strange errors.
--> Size/Strength (S/T). S is the size of the sharpen/blur effect, T is the strength of the sharpen/blur effect.
--> Luma/Chroma (L/C). L is the detail, C is the color. Luma sharpening more effective.
--> Option Value: <LS>:<LT>:<CS>:<CT>
--> LS and CS must be ODD, between 3 and 63. Negative LT/CT values blur, while positive ones sharpen.
--> Strong Sharp: 7:3:7:3 Strong Blur: 7,-3:7,-3. Medium Sharp: 5:1:3:0
-l <path> $(cVal LUT) - Specify a LUT to apply after Color Management.
--> Supports cube, 3dl, dat, m3d.
--> Specify -l multiple times, to apply multiple LUTs in sequence.
-S [int] $(cVal SATPOINT) - Specify the 14-bit uint saturation point of your camera. You don't usually need to.
--> Worth setting globally, as it's a per-camera setting. Must be correct for highlight reconstruction/unclipped highlights.
--> Lower from 15000 if -H1 yields purple highlights, until they turn white.
--> You can determine the optimal value using the max pixel value of 'dcraw -D -j -4 -T'.
--white-speed [int] $(cVal WHITE_SPD) - Manually specify samples used to calculate AWB.
--allow-white-clip $(cVal WHITE_CLIP) - Let the White Balance multipliers clip.
$(head "OPTIONS, FEATURES:")
-D $(cVal DESHAKE) - Auto-stabilize the video using ffmpeg's "deshake" module.
--> You may wish to crop/scale the output later, to avoid edge artifacts.
-u $(cVal DUAL_ISO) - Process as dual ISO.
--> Requires cr2hdr.
-b $(cVal BADPIXELS) - Fix focus pixels issue using dfort's script.
--> Requires mlv2badpixels.sh.
-a <path> $(cVal BADPIXEL_PATH) - Use your own .badpixels file. Does NOT require mlv2badpixels.sh
--> How to: http://www.dl-c.com/board/viewtopic.php?f=4&t=686
-F <path> $(cVal DARKFRAME) - This is the path to a "dark frame MLV"; effective for noise reduction.
--> How to: Record 5 sec w/lens cap on & same settings as footage. Pass MLV in here.
--> If the file extension is '.darkframe', the file will be used as a preaveraged dark frame.
-R <path> $(bVal darkframe_output) - Specify to create a .darkframe file from passed in MLV.
--> Usage: 'convmlv -R <path> <input>.MLV'
--> Averages <input>.MLV to create <path>.darkframe.
--> THE .darkframe EXTENSION IS ADDED FOR YOU.
$(head "OPTIONS, INFO:")
-q $(bVal settings) - Output MLV settings.
-K [0:3] $(bVal "Dist Deps") - Output package dependecies, for use with common package managers.
--> 0: Debian, 1: Ubuntu, 2: Fedora, 3: Homebrew (Mac)
--> Deps Install (Debian): sudo apt-get install \$(./convmlv.sh -K 0)
--> Deps Install (Ubuntu): sudo apt-get install \$(./convmlv.sh -K 1)
--> Deps Install (Fedora): sudo yum install \$(./convmlv.sh -K 2)
--> Deps Install (Homebrew Mac): brew install \$(./convmlv.sh -K 3)
-Y $(bVal "Python Deps") - Lists Python dependencies. Works directly with pip.
-->Install (Cross-Platform): sudo python3 -m pip install $ (./convmlv -Y)
-M $(bVal "Manual Deps") - Lists manual dependencies, which must be downloaded by hand.
--> Manually place all in RES_PATH. See http://www.magiclantern.fm/forum/index.php?topic=16799.0 .
$(head "COLOR MANAGEMENT:")
$(bold INTRO) Images aren't simple. They are often stored, processed, and viewed as a result of complex transformations usually called,
in applications, color management. Understanding it is required as a colourist, and encouraged as a DPs and Cinematographers.
--> Intro: http://www.cambridgeincolour.com/tutorials/color-management1.htm
--> Understanding Gamma: http://www.cambridgeincolour.com/tutorials/gamma-correction.htm
--> Color Spaces: http://www.cambridgeincolour.com/tutorials/color-spaces.htm
--> Conversions: http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm
--> Monitor Calibration: http://www.cambridgeincolour.com/tutorials/monitor-calibration.htm
$(bold "PIPELINE") convmlv is a color managed application, designed to retain quality from RAW footage:
-- mlv_dump writes camera-specific color transformation matrices as metadata in developed DNGs.
--> This defines the camera's gamut.
-- dcraw applies these matrices, then transforms the newly developed image to the super-wide XYZ colorspace.
--> All color detail is preserved, and if now in a well-defined colorspace.
--> No gamma has been applied - the image is now Linear XYZ.
-- ffmpeg applies the specified (up to) x64 resolution 3D LUTs, in .cube format.
--> Use -g and -G to specify Gamma/Gamut combinations.
--> The output employs DATA, not LEGAL, values. The resulting image is flatter, but retains all shadow/highlight detail.
--> -l specified LUTs are applied afterwards.
$(bold "3D LUTS") The included LUTs, found in the convmlv repository, are key to convmlv's color management solution:
-- color-core: The required LUTs, including sRGB (default), Adobe RGB, and Rec709 in Standard and Linear gamma.
-- color-ext: Optional LUTs, including Rec2020, DCI-P3, etc. in Standard/Linear gammas, but also in Log formats.
$(bold "Create Your Own LUTs") using LUTCalc, for any grading format output: https://cameramanben.github.io/LUTCalc/ (watch his tutorials).
--> Note that convmlv only accepts up to 64x64x64 LUTs. You can resize LUTs using pylut (https://pypi.python.org/pypi/pylut).
--> The pylut command to resize is 'pylut <yourx65lut>.cube --resize 64'. Alternatively, you can use pylut from Python (2X only).
--> I reccommend Legal --> Data LUTs, as this conserves shadow/highlight detail for grading. Legal --> Legal looks better, but with detail loss.
$(head "CONFIG FILE:")
Config files, another way to specify options, can save you time & lend you convenience in production situations.
$(echo -e "\033[1mGLOBAL\033[0m"): $HOME/convmlv.conf
$(echo -e "\033[1mLOCAL\033[0m"): Specify -C/--config.
$(echo -e "\033[1mSYNTAX:\033[0m")
Most options listed above have an uppercased VARNAME, ex. OUTDIR. You can specify such options in config files, as such:
<VARNAME> <VALUE>
One option per line only. Indentation by tabs or spaces is allowed, but not enforced.
$(echo -e "\033[1mComments\033[0m") Lines starting with # are comments.
You may name a config using:
CONFIG_NAME <name>
$(echo -e "\033[1mFlags\033[0m") If the value is a true/false flag (ex. IMAGE), simply specifying VARNAME is enough. There is no VALUE.
$(echo -e "\033[1mOPTION ORDER OF PRECEDENCE\033[0m") Options override each other as such:
-LOCAL options overwrite GLOBAL options.
-COMMAND LINE options overwrite LOCAL & GLOBAL options.
-FILE SPECIFIC options overwrite ALL ABOVE options.
$(echo -e "\033[1mFile-Specific Block\033[0m"): A LOCAL config file lets you specify options for specific input names:
/ <TRUNCATED INPUTNAME>
...options here will only be
*
You must use the truncated (no .mlv or .raw) input name after the /. Nested blocks will fail.
With a single config file, you can control the development options of multiple inputs as specifically and/or generically
as you want. Batch developing everything can then be done with a single, powerful commmand.
Contact me with any feedback or questions at convmlv@sofusrose.com, PM me (so-rose) on the ML forums, or post on the thread!
EOF
}

View File

@ -0,0 +1,140 @@
invOption() {
str=$1
echo -e "\033[0;31m\033[1m${str}\033[0m"
echo -e "\n\033[1mCleaning Up.\033[0m\n\n"
#Delete tmp
rm -rf $TMP
exit 1
}
checkArg() {
#stderr is for printing; stdout is for return values.
argBase="$(basename "$ARG")"
argExt="${argBase##*.}"
argTrunc="${argBase%.*}"
local cont
#Argument Checks
if [ ! -f $ARG ] && [ ! -d $ARG ]; then
nFound "File" "${ARG}" "Skipping File"
echo "skip" >&1; return
fi
if [[ ! -d $ARG && ! ( $argExt == "MLV" || $argExt == "mlv" || $argExt == "RAW" || $argExt == "raw" ) ]]; then
echo -e "\033[0;31m\033[1mFile ${ARG} has invalid extension!\033[0m\n" >&2
echo "skip" >&1; return
fi
if [[ ( ( ! -f $ARG ) && $(ls -1 ${ARG%/}/*.[Dd][Nn][Gg] 2>/dev/null | wc -l) == 0 ) && ( `folderName ${ARG}` != $argTrunc ) ]]; then
echo -e "\033[0;31m\033[1mFolder ${ARG} contains no DNG files!\033[0m\n" >&2
echo "skip" >&1; return
fi
if [ ! -d $ARG ] && [[ $(echo $(wc -c ${ARG} | xargs | cut -d " " -f1) / 1000 | bc) -lt 1000 ]]; then #Check that the file is not too small.
cont=false
while true; do
#xargs easily trims the cut statement, which has a leading whitespace on Mac.
read -p "${ARG} is unusually small at $(echo "$(echo "$(wc -c ${ARG})" | xargs | cut -d$' ' -f1) / 1000" | bc)KB. Continue, skip, remove, or quit? [c/s/r/q] " csr
case $csr in
[Cc]* ) "\n\033[0;31m\033[1mContinuing.\033[0m\n"; break
;;
[Ss]* ) echo -e "\n\033[0;31m\033[1mSkipping.\033[0m\n"; cont=true; break
;;
[Rr]* ) echo -e "\n\033[0;31m\033[1mRemoving ${ARG}.\033[0m\n"; cont=true; rm $ARG; break
;;
[Qq]* ) echo -e "\n\033[0;31m\033[1mQuitting.\033[0m\n"; isExit=true; break
;;
* ) echo -e "\033[0;31m\033[1mPlease answer continue, skip, or remove.\033[0m\n"
;;
esac
done
if [ $cont == true ]; then
echo "skip" >&1; return
fi
fi
}
checkDeps() {
#Essentials
if [ ! -f $MLV_DUMP ]; then
nFound "Binary" "${MLV_DUMP}" "Execution will halt" "Get it here: http://www.magiclantern.fm/forum/index.php?topic=7122.0."
isExit=true
fi
if [ ! -d ${COLOR_LUTS[0]} ]; then
nFound "Folder" "color-core" "Execution will halt" "Download from convmlv repository."
isExit=true
fi
if [ ! -f $PYTHON_SRANGE ]; then
nFound "Python Script" "${PYTHON_SRANGE}" "Execution will halt" "Download from convmlv repository."
isExit=true
fi
cmdExists() { if type -P "$1" &> /dev/null || [ -x "$1" ]; then echo true; else echo false; fi }
#Basic Options - Dist Deps
if [[ $(cmdExists "$DCRAW") != true ]]; then
nFound "Command" "$DCRAW" "Execution will halt" "dcraw not installed correctly - See Dist Deps in the OPTIONS, INFO section of 'convmlv -h'."
isExit=true
fi
if [[ $(cmdExists "$PYTHON") != true ]]; then
nFound "Command" "$PYTHON" "Execution will halt" "Python was not installed correctly. Install version 3.X, or see PYTHON in the OPTIONS, BASIC section of 'convmlv -h' for custom path."
isExit=true
fi
if [[ $(cmdExists "$PYTHON") == true && $($PYTHON -c 'import sys; print(sys.version_info[0])') != 3 ]]; then
nFound "Python Version" "3.X" "Execution will halt" "Your python version is $($PYTHON -c "import sys; print('.'.join(str(x) for x in sys.version_info[0:3]))") - convmlv requires 3.X. Typically, you must install the 'python3' package; else you can set set PYTHON in the OPTIONS, BASIC section of 'convmlv -h'."
fi
if [[ $(cmdExists "convert") != true ]]; then
nFound "Command" "convert" "Execution will halt" "ImageMagick not installed correctly - See Dist Deps in the OPTIONS, INFO section of 'convmlv -h'."
isExit=true
fi
if [[ $(cmdExists "ffmpeg") != true ]]; then
nFound "Command" "ffmpeg" "Execution will halt" "ffmpeg not installed correctly - See Dist Deps in the OPTIONS, INFO section of 'convmlv -h'."
isExit=true
fi
if [[ $(cmdExists "exiftool") != true ]]; then
nFound "Command" "exiftool" "Execution will halt" "exiftool not installed correctly - See Dist Deps in the OPTIONS, INFO section of 'convmlv -h'."
isExit=true
fi
#Optionals
if [ ! -f $RAW_DUMP ]; then
nFound "Binary" "${RAW_DUMP}" "Execution will continue without .RAW processing capability" "Get it here: http://www.magiclantern.fm/forum/index.php?topic=5404.0."
fi
if [ ! -f $MLV_BP ]; then
nFound "SH Script" "${MLV_BP}" "Execution will continue without badpixel removal capability" "Get it here: https://bitbucket.org/daniel_fort/ml-focus-pixels/src"
fi
if [ ! -f $CR_HDR ]; then
nFound "Binary" "${CR_HDR}" "Execution will continue without Dual ISO processing capability" "Get it here: http://www.magiclantern.fm/forum/index.php?topic=7139.0"
fi
if [ ! -f $PYTHON_BAL ]; then
nFound "Python Script" "${PYTHON_BAL}" "Execution will continue without AWB" "Download from convmlv repository."
fi
if [ ! -d ${COLOR_LUTS[1]} ]; then
nFound "Folder" "color-ext" "Execution will continue without extra gamma/gamut options." "Download from convmlv repository."
fi
if [[ $isExit == true ]]; then
echo -e "\033[0;33m\033[1mPlace all binaries in BIN_PATH - ${BIN_PATH} - or give specific paths with the relevant arguments/config options (see 'convmlv -h'). Also, make sure they're executable (run 'chmod +x file').\033[0m\n"
exit 1
fi
#Option Checking - ideally, we do all of these. For now, I'm bored of it...
#Check wavelet NR - WAVE_NOISE
#Check TEMP_NOISE
#Check HQ_NOISE
#Check REM_NOISE
#Check SHARP
#Check SATPOINT
#Check WHITE_SPD
#Check BADPIXEL_PATH
#Check LUT size.
#badpixel info.
}

View File

@ -0,0 +1,35 @@
bold() {
echo -e "\033[1m${1}\033[0m"
}
cVal() {
#usage: cVal value
#desc: Formats config file values, as bolded grey.
#return: Formatted value.
echo -e "\033[1m\033[37m${1}\033[0m"
}
bVal() {
#usage: bVal value
#desc: Formats running (not related to development) options, as bolded green.
#return: Formatted value.
echo -e "\033[1m\033[32m${1}\033[0m"
}
head() {
#usage: cVal value
#desc: Formats help page header values, as bold.
#return: Formatted value.
echo -e "\033[1m${1}\033[0m"
}
iVal() {
#usage: iVal value
#desc: Formats important config values, as bolded yellow.
#return: Formatted value.
echo -e "\033[1m\033[33m${1}\033[0m"
}

View File

@ -0,0 +1,13 @@
#!/bin/bash
getThreads() {
local threads=4 #4 threads by default
if [[ $OSTYPE == "linux-gnu" ]]; then #Linux-specific constants.
threads=$(cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -1)
elif [[ $OSTYPE == "darwin11" ]]; then #Mac-specific constants
threads=$(sysctl -n hw.ncpu)
fi
echo "$threads"
}

View File

@ -0,0 +1,52 @@
nFound() { #Prints: ${type} ${name} not found! ${exec_instr}.\n\t${down_instr} to stderr.
type=$1
name="$2"
exec_instr=$3
down_instr=$4
if [[ -z $down_instr ]]; then
echo -e "\033[1;31m${type} \033[0;1m${name}\033[1;31m not found! ${exec_instr}.\033[0m\n" >&2
else
echo -e "\033[1;31m${type} \033[0;1m${name}\033[1;31m not found! ${exec_instr}.\033[0m\n------> ${down_instr}\n" >&2
fi
}
mkdirS() {
path=$1
cleanup=$2
cont=false
if [ -d $path ]; then
while true; do
read -p "Overwrite ${path}? [y/n/q] " ynq
case $ynq in
[Yy]* ) echo -e ""; rm -rf $path; mkdir -p $path >/dev/null 2>/dev/null; break
;;
[Nn]* ) echo -e "\n\033[0;31m\033[1mDirectory ${path} won't be created.\033[0m\n"; cont=true; `$cleanup`; break
;;
[Qq]* ) echo -e "\n\033[0;31m\033[1mHalting execution. Directory ${path} won't be created.\033[0m\n"; `$cleanup`; exit 1;
;;
* ) echo -e "\033[0;31m\033[1mPlease answer yes or no.\033[0m\n"
;;
esac
done
else
mkdir -p $path >/dev/null 2>/dev/null
fi
if [ $cont == true ]; then
let ARGNUM--
continue
fi
}
folderName() {
#Like basename, but for folders.
echo "$1" | rev | cut -d$'/' -f1 | rev
}
joinArgs() {
#Joins the arguments of the input array using commas.
local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"
}

View File

View File

@ -0,0 +1,5 @@
mkDarkframe() {
echo -e "\n\033[1m\033[0;32m\033[1mAveraging Darkframe File\033[0m: ${ARG}"
$MLV_DUMP -o $DARK_OUT ${FILE_ARGS_ARRAY[0]} 2>/dev/null 1>/dev/null
echo -e "\n\033[1m\033[1mWrote Darkframe File\033[0m: ${DARK_OUT}\n"
}

View File

@ -0,0 +1,103 @@
prntSet() {
cat << EOF
$(bold CameraName): ${CAM_NAME}
$(bold RecordingDate): ${REC_DATE}
$(bold RecordingTime): ${REC_TIME}
$(bold FPS): ${FPS}
$(bold Resolution): ${RES_IN}
$(bold TotalFrames): ${FRAMES}
$(bold Aperture): ${APERTURE}
$(bold ISO): ${ISO}
$(bold ShutterSpeed): ${SHUTTER}
$(bold WBKelvin): ${KELVIN}
$(bold FocalLength): ${LEN_FOCAL}
EOF
}
mlvSet() {
camDump=$(${MLV_DUMP} -v -m ${ARG}) #Read it in *once*; otherwise it's unbearably slow on external media.
FPS=`echo "$camDump" | grep FPS | awk 'FNR == 1 {print $3}'`
CAM_NAME=`echo "$camDump" | grep 'Camera Name' | cut -d "'" -f 2`
FRAMES=`echo "$camDump" | awk '/Processed/ { print $2; }'` #Use actual processed frames as opposed to what the sometimes incorrect metadata thinks.
RES_IN=`echo "$camDump" | grep "Res" | sed 's/[[:alpha:] ]*: //'`
ISO=`echo "$camDump" | grep 'ISO' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f2`
APERTURE=`echo "$camDump" | grep 'Aperture' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f1`
LEN_FOCAL=`echo "$camDump" | grep 'Focal Len' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f1`
SHUTTER=`echo "$camDump" | grep 'Shutter' | sed 's/[[:alpha:] ]*: //' | grep -oP '\(\K[^)]+' | cut -d$'\n' -f1`
REC_DATE=`echo "$camDump" | grep 'Date' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f1`
REC_TIME=`echo "$camDump" | grep 'Time: [0-2][0-9]\:*' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f1`
KELVIN=`echo "$camDump" | grep 'Kelvin' | sed 's/[[:alpha:] ]*: //' | cut -d$'\n' -f1`
}
rawSet() { #To be implemented maybe - exiftool? Or raw_dump? ...
CAM_NAME="Unknown"
FRAMES="Unknown"
RES_IN="Unknown"
ISO="Unknown"
APERTURE="Unknown"
LEN_FOCAL="Unknown"
SHUTTER="Unknown"
REC_DATE="Unknown"
REC_TIME="Unknown"
KELVIN="Unknown"
}
dngSet() { #Set as many options as the RAW spec will allow. Grey out the rest.
dngLoc=$1
if [[ -z $dngLoc ]]; then dngLoc="${ARG}"; fi
for dng in $dngLoc/*.dng; do
dataDNG="$(pwd)/.datadng.dng"
cp $dng $dataDNG
break
done
FPS=24 #Standard FPS.
#Frames is taken care of.
CAM_NAME=$(exiftool -UniqueCameraModel -s -s -s $dataDNG)
RES_IN=$(exiftool -ImageSize -s -s -s $dataDNG)
ISO=$(exiftool -UniqueCameraModel -s -s -s $dataDNG)
APERTURE=$(exiftool -ApertureValue -s -s -s $dataDNG)
LEN_FOCAL=$(exiftool -FocalLength -s -s -s $dataDNG)
SHUTTER=$(exiftool -ShutterSpeed -s -s -s $dataDNG)
REC_DATE=$(echo "$(exiftool -DateTimeOriginal -s -s -s $dataDNG)" | cut -d$' ' -f1)
REC_TIME=$(echo "$(exiftool -DateTimeOriginal -s -s -s $dataDNG)" | cut -d$' ' -f2)
KELVIN="Unknown"
rm $dataDNG
}
printFileSettings() {
ARG="${FILE_ARGS_ARRAY[0]}"
checkArg
BASE="$(basename "$ARG")"
EXT="${BASE##*.}"
if [ $EXT == "MLV" ] || [ $EXT == "mlv" ]; then
# Read the header for interesting settings :) .
mlvSet
echo -e "\n\033[1m\033[0;32m\033[1mFile\033[0m: ${ARG}\n"
prntSet
elif [ $EXT == "RAW" ] || [ $EXT == "raw" ]; then
rawSet
echo -e "\n\033[1m\033[0;32m\033[1mFile\033[0m\033[0m: ${ARG}\n"
prntSet
elif [ -d $ARG ]; then
dngSet
echo -e "\n\033[1m\033[0;32m\033[1mFile\033[0m\033[0m: ${ARG}\n"
prntSet
else
echo -e "Cannot print settings from ${ARG}; it's not a valid file!"
fi
}