#!/bin/sh

[ -r .conf ] || exit 125

UFRAW='eval ufraw-batch --interpolation=ahd --out-type=tiff --out-depth=16 --overwrite --zip --wavelet-denoising-threshold=150'
DCRAW='dcraw -v -r 1.110000 1.000000 2.895000 1.000000 -S 62976 -H 0 -q 3 -n 150 -m 4 -4 -T'
#DCRAW='dcraw -v -w -H 0 -q 3 -n 300 -4 -T'
NONA='eval nona -v -t ${CPUS} -m TIFF_m -r ldr -p UINT${DEPTH} -z DEFLATE -o tmp-'
FULLA='eval fulla -v -t ${CPUS} -s'
CCM='color_correct -E -c -p.03 -D64 -a-4096:4096+1024 -k24:40/32 -g28:36/32'
ENBL='enblend --compression=DEFLATE -m 896 --fine-mask'
#ENBL='enfuse --compression=DEFLATE -m 896'
#CONV='convert -limit memory 512 -limit map 256'
CONV='convert'
#INPNT='greycstoration -alpha 0.9 -sigma 0.2 -p 5 -a 1 -dt 20 -iter 5 -bits 16 -m mask.png -inpaint'
#INPNT='greycstoration -alpha 0.9 -sigma 0.2 -iter 512 -bits 16 -inpaint'
INPNT='greycstoration -iter 1024 -bits 16 -inpaint'

RGB='-fx s<=0.03928?s/12.92:((s+0.055)/1.055)^2.4'
sRGB='-fx s<=0.00304?s*12.92:s^(1.0/2.4)*1.055-0.055'

PFSMAX=75013120
PFSHOST=192.168.0.55

LANG=C; export LANG

. .conf

[ -n "${DEPTH}" ] || DEPTH="${2}"
[ -n "${DEPTH}" ] || DEPTH=16

[ -z "${KEEPHDR}" ] || KEEPHDR="tee ${DST}.pfs"
[ -n "${KEEPHDR}" ] || KEEPHDR=cat

[ -n "${CPUS}" ] || CPUS=$(sysctl -n kern.smp.cpus)
[ -n "${CPUS}" ] || CPUS=1

prep () {
    for e in ${EXP}
    do
        eval "SEQ=\${SEQ${e}}"
        eval "SRC=\${SRC${e}}"
        eval "SFX=\${SFX${e}}"
        N=0
        for n in ${SRC}
        do
            o=$(printf '%02d%s' ${N} ${SFX})
            N=$((${N}+1))
            if [ "${n}" = SSKIP ]
            then
                if [ ${o} = 03-e02 -o ${o} = 04-e02 ]
                then
                    eval "NSFX=\${SFX$((${e}+1))}"
                    ln -s $(printf '%02d%s.tiff' ${N} ${NSFX}) ${o}.tiff
                fi
            fi
            [ -z "${n}" -o "${n}" = SKIP -o "${n}" = SSKIP ] && continue
            [ -r ${o}.tiff ] && continue
            [ -r ${n}.RAW.bz2 ] && bzcat ${n}.RAW.bz2 >${n}.RAW
            [ -r ${n}.RAW.gz ] && zcat ${n}.RAW.gz >${n}.RAW
            if [ -r ${n}.RAW ]
            then
                if [ -z "${LIN}" ]
                then
                    conf=${n}.ufraw
                    [ -z "${UCONF}" ] || conf=${UCONF}.ufraw
                    [ -r ${conf} ] || exit 125
                    ${UFRAW} --conf=${conf} --output=${n}.tiff ${n}.RAW
                else
                    ${DCRAW} ${n}.RAW
                fi
                fl=$(dcraw -i -v ${n}.RAW|awk '/^Focal length: /{print $3}')
                tca="$( ( cd ../../tools/tca && echo "disp(tca('tca.db','fz50',${fl},1,0))"|octave -q|cat|head -1 ) )"
                #echo "Focal length: ${fl}; TCA correction: ${tca}"
                ${FULLA} ${tca} -o ${n}.tiff ${n}.tiff
                eval "$(identify -format 'w=%w; h=%h' ${n}.tiff)"
                ${CONV} ${n}.tiff \
                    -depth 16 \
                    -crop $((${w}-24))x$((${h}-12))+12+6 +repage \
                    -orient undefined \
                    -unsharp 0x0.3 \
                    -compress zip ${o}.tiff
                rm -f ${n}.tiff
                if [ -n "${LIN}" -a "${1}" = prep -a "${DEPTH}" = 8 ]
                then
                    if [ -n "${3}" ]
                    then
                        case ${e} in
                        0) m='1.5625,50';;
                        1) m='6.25,50';;
                        2) m='25,50';;
                        3) m='100,50';;
                        4) m='400,50';;
                        5) m='1600,50';;
                        6) m='6400,50';;
                        *) m='100,100';;
                        esac
                    fi
                    echo "${N}/${e}: ${m}"
                    [ -z "${m}" ] || m="-modulate ${m}"
                    ${CONV} ${o}.tiff \
                        ${m} ${sRGB} \
                        -compress zip ${o}.tiff
                fi
                [ "${DEPTH}" = 16 ] \
                || ${CONV} ${o}.tiff -depth 8 -compress zip ${o}.tiff
                exiftool -overwrite_original -P -TagsFromFile ${n}.RAW ${o}.tiff
                [ -r ${n}.RAW.bz2 -o -r ${n}.RAW.gz ] && rm -f ${n}.RAW
                [ -r ${n}.JPG ] \
                && exiftool -overwrite_original -P -TagsFromFile ${n}.JPG ${o}.tiff
            elif [ -r ${n}.JPG ]
            then
                # sRGB => RGB
                [ -z "${LIN}" ] || rgb="${RGB}"
                ${CONV} ${n}.JPG \
                    -noise 3 -unsharp 0x0.3 \
                    ${rgb} \
                    -depth ${DEPTH} \
                    -compress zip ${o}.tiff
                exiftool -overwrite_original -P -TagsFromFile ${n}.JPG ${o}.tiff
            else
                exit 126
            fi
            [ -r mask-${o}.png -a \( "${1}" != prep -o "${DEPTH}" != 8 \) ] \
            && ${CONV} ${o}.tiff -matte \
                mask-${o}.png -compose multiply -composite \
                mask-${o}.png -compose copyopacity -composite \
                -compress zip ${o}.tiff
        done
    done
}

auto () {
    autoexp () {
        e=${1}; shift
        [ -r ${DST}-ap${e}.pto ] && continue
        S=''
        for a in ${*}
        do
            s="$(printf '%s%s.tiff' ${a} ${e})"
            [ -r "${s}" ] && S="${S} ${s}"
        done
        printf 'e=%s; S=%s\n' ${e} "${S}"
        panomatic -n 1 \
            --surfscore 50 --minmatches 8 \
            --sieve1width 64 --sieve1height 48 --sieve1size 8 \
            --sieve2width 16 --sieve2height 16 --sieve2size 4 \
            -o ${DST}${e}-pm.pto ${S}
        autooptimiser -a -l -s -o ${DST}${e}-ao.pto ${DST}${e}-pm.pto
    }
    autosect () {
        a=${1}; shift
        [ -r ${DST}-${a}-pm.pto ] && continue
        S=''
        for e in ${*}
        do
            s="$(printf '%s%s.tiff' ${a} ${e})"
            [ -r "${s}" ] && S="${S} ${s}"
        done
        printf 'a=%s; S=%s\n' ${a} "${S}"
        panomatic -n 1 \
            --surfscore 50 --minmatches 8 \
            --sieve1width 64 --sieve1height 48 --sieve1size 8 \
            --sieve2width 32 --sieve2height 24 --sieve2size 4 \
            -o ${DST}-${a}-pm.pto ${S}
        autooptimiser -a -o ${DST}-${a}-ao.pto ${DST}-${a}-pm.pto
    }
    E=''
    for e in ${EXP}
    do
        eval "SRC=\${SRC${e}}"
        eval "SFX=\${SFX${e}}"
        E="${E} ${SFX}"
        A=''
        N=0
        for n in ${SRC}
        do
            [ -z "${n}" -o "${n}" = SKIP ] \
            || A="${A} $(printf '%02d' ${N})"
            N=$((${N}+1))
        done
    done
    printf 'E=%s\nA=%s\n' "${E}" "${A}"; #return 0
    if [ "${E}" = ' ' ]
    then
        autoexp '' ${A}
    else
        for e in ${E}
        do
            autoexp ${e} ${A}
        done
        for a in ${A}
        do
            autosect ${a} ${E}
        done
    fi
}

cluster () {
    clexp () {
        e=${1}
        [ -r ${DST}${e}-ao.pto ] || return
        [ -z "${2}" ] || D="-D${2}"
        [ -z "${3}" ] || d="-d${3}"
        yrp=yrp0-
        [ -z "${4}" ] || yrp="yrp0-$((${4}-1)),$((${4}+1))-"
        perl ../../tools/ptstool -O0xff \
            -s -Vbv0:acde0-:${yrp} \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.pto
        PToptimizer ${DST}${e}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -x48 -y36 ${D} ${d} \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt
        PToptimizer ${DST}${e}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -x24 -y18 ${D} ${d} \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt
        PToptimizer ${DST}${e}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            ${D} ${d} \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s \
            -o ${DST}${e}-ao.txt ${DST}${e}-ao.txt
        PToptimizer ${DST}${e}-ao.txt
        perl ../../tools/ptstool -O0xff \
            -i \
            -o ${DST}${e}.pto ${DST}${e}-ao.txt
    }
    clsect () {
        a=${1}
        [ -r ${DST}-${a}-ao.pto ] || return
        perl ../../tools/ptstool -O0xff \
            -Ibv1-:=0:acde0-:0 \
            -Vyrp1- \
            -s -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.pto
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -x48 -y36 -d12 -D24 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -x48 -y36 -d8 -D16 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -x48 -y36 -D10 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s -Vacde1-:yrp1- \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -x24 -y18 -D7 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s  \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -D5 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s  \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptscluster -O0xff \
            -r0x21 -D3 \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt \
        && perl ../../tools/ptstool -O0xff \
            -s  \
            -o ${DST}-${a}-ao.txt ${DST}-${a}-ao.txt
        PToptimizer ${DST}-${a}-ao.txt
        perl ../../tools/ptstool -O0xff \
            -i \
            -o ${DST}-${a}.pto ${DST}-${a}-ao.txt
    }
    E=''
    for e in ${EXP}
    do
        eval "SRC=\${SRC${e}}"
        eval "SFX=\${SFX${e}}"
        E="${E} ${SFX}"
        A=''
        N=0
        for n in ${SRC}
        do
            [ -z "${n}" -o "${n}" = SKIP ] \
            || A="${A} $(printf '%02d' ${N})"
            N=$((${N}+1))
        done
    done
    printf 'E=%s\nA=%s\n' "${E}" "${A}"; #return 0
    if [ "${E}" = ' ' ]
    then
        clexp '' ${DMAX} ${DMIN} ${ANC}
    else
        for e in ${E}
        do
            clexp ${e} ${DMAX} ${DMIN} ${ANC}
        done
        for a in ${A}
        do
            clsect ${a} ${DMAX} ${DMIN}
        done
    fi
}

mkpano () {
    f=$(awk '/^p /{if(match($0,/w[0-9]+/)){w=substr($0,RSTART+1,RLENGTH-1);match($0,/h[0-9]+/);h=substr($0,RSTART+1,RLENGTH-1);print w"x"h}nextfile}' ${DST}.pto)
    [ -z "${f}" ] || f="-f ${f}"
    c=$(awk '/^p /{if(match($0,/S[0-9]+,[0-9]+,[0-9]+,[0-9]+/)){split(substr($0,RSTART+1,RLENGTH-1),a,/,/);print(a[2]-a[1])"x"(a[4]-a[3])"+"a[1]"+"a[3]}nextfile}' ${DST}.pto)
    [ -z "${c}" ] || f="-f ${c}"
    #[ -z "${c}" ] || c="-crop ${c} +repage"
    for e in ${EXP}
    do
        eval "SFX=\${SFX${e}}"
        [ -r ${DST}${SFX}.tiff ] && continue
        eval "SEQ=\${SEQ${e}}"
        NIN=''
        EIN=''
        for s in ${SEQ}
        do
            NIN="${NIN} -i ${s}"
            EIN=$(printf "${EIN} tmp-%04d.tif" ${s})
        done
        ${NONA} ${NIN} ${DST}.pto \
        && ${ENBL} ${f} -o tmp${SFX}.tiff ${EIN} \
        && rm ${EIN} \
        && ${CONV} tmp${SFX}.tiff \
            +matte +repage \
            -unsharp 0x0.2 \
            -compress zip ${DST}${SFX}.tiff \
        && rm tmp${SFX}.tiff
            #-modulate 100,95 \
    done

    [ -n "${3}" ] \
    || for e in ${EXP}
    do
        eval "SFX=\${SFX${e}}"
        rm [0-9][0-9]${SFX}.tiff
    done

    apply-patch () 
    {
        g=${1}; shift
        se=${1}; shift
        de=${1}; shift
        n=${1}; shift
        [ -n ${n} ] || n=1
        rgb=''; srgb=''
        [ -n ${LIN} ] || { rgb="${RGB}"; srgb="${sRGB}"; }
        ${CONV} ${DST}-e${se}.tiff \
            -crop ${g} +repage \
            ${rgb} "${@}" ${srgb} \
            -compress zip ${DST}-e${de}.${n}.tiff 
        [ -r mask-${DST}-e${de}.${n}.png ] \
        && ${CONV} ${DST}-e${de}.${n}.tiff \
            mask-${DST}-e${de}.${n}.png -compose copyopacity -composite \
            -compress zip ${DST}-e${de}.${n}.tiff
        mv ${DST}-e${de}.tiff ${DST}-e${de}.0.tiff
        ${CONV} ${DST}-e${de}.0.tiff ${DST}-e${de}.${n}.tiff \
            -geometry ${g} \
            -compose src-over -composite \
            -compress zip ${DST}-e${de}.tiff
        rm ${DST}-e${de}.0.tiff ${DST}-e${de}.${n}.tiff
    }
    apply-patch 3072x864+0+512 04 05 1  -modulate  50.000,100
    apply-patch 3072x864+0+512 04 06 1  -modulate  25.000,100
    apply-patch 64x64+1440+1472 05 04 2 -modulate 200.000,100
    apply-patch 64x64+1440+1472 05 03 2 -modulate 400.000,100
    #apply-patch 3072x864+0+512 04 05 1 -evaluate multiply 0.495 -modulate 100,126
    #apply-patch 3072x864+0+512 04 06 1 -evaluate multiply 0.225 -modulate 100,129
    #apply-patch 64x64+1440+1472 05 04 2 -modulate 100,75 -evaluate multiply 2.20
    #apply-patch 64x64+1440+1472 05 03 2 +contrast -modulate 100,65 -evaluate multiply 3.70

    inpaint () {
        g=${1}
        n=${2}
        ${CONV} ${DST}.tiff \
            -crop ${g} \
            -compress zip ${DST}.${n}.tiff 
        mv ${DST}.tiff ${DST}.0.tiff
        greycstoration -inpaint ${DST}.${n}.tiff \
            -iter 1024 -bits 16 \
            -m mask-${DST}.${n}.png \
            -o ${DST}.${n}.tiff
        ${CONV} ${DST}.0.tiff ${DST}.${n}.tiff \
            -geometry ${g} \
            -compose src-over -composite \
            -compress zip ${DST}.tiff
        rm ${DST}.0.tiff ${DST}.${n}.tiff
    }
    #inpaint 416x64+1536+1920 1
}

mkhdr () {
    #pfsinhdrgen ${DST}.hdrgen \
    #| pfshdrcalibrate -v -r gamma -g 8 -b 16 -s ${DST}.0.m
    PFSCAL='pfshdrcalibrate -v -x -r gamma -g 8'
    [ -r ${DST}.m ] \
    && PFSCAL="pfshdrcalibrate -v -x -c none -f ${DST}.m"
    PFSCNT=2
    [ -r ${DST}.hdrgen ] \
    && PFSCNT=$(wc -l ${DST}.hdrgen|sed -e 's/ *\([0-9]*\) *.*/\1/')
    INIMG=${DST}.tiff
    [ -r ${DST}.hdrgen ] \
    && INIMG=$(awk '{print $1;nextfile}' ${DST}.hdrgen)
    PFSSIZE=$(identify -format "%w*%h*${PFSCNT}" ${INIMG}|bc)
    PFSEVAL=eval
    [ ${PFSSIZE} -le ${PFSMAX} ] || PFSEVAL="rsh ${PFSHOST}"
    PFSIN="pfsintiff --linear ${DST}.tiff"
    [ -r ${DST}.hdrgen ] \
    && PFSIN="pfsinhdrgen ${DST}.hdrgen | ${PFSCAL} -b ${DEPTH}"
    [ -r ${DST}.pfs.bz2 ] \
    && PFSIN="bzcat ${DST}.pfs.bz2"
    PFSCHAIN="cd $(pwd) && ${PFSIN}"

    cat >&2 <<EOM
Image size is ${PFSSIZE} pxel(s)
Max allowed for local operation is ${PFSMAX} pxel(s)
Pipeline
  ${PFSCHAIN}
will be executed using '${PFSEVAL}' command
EOM

    ${PFSEVAL} "${PFSCHAIN}" \
    | pfswb -v \
    | pfstmo_mantiuk08 -v -d pd=crt -c 0.75 -e 1.00 \
    | pfsgamma -m 0.95 -g 1.00 \
    | pfsoutimgmagick ${DST}.0.tiff
    [ ${?} -ne 0 -o -n "${3}" ] \
    || for e in ${EXP}
       do
        eval "SFX=\${SFX${e}}"
        [ -z "${SFX}" ] || rm ${DST}${SFX}.tiff
       done
    ${CONV} ${DST}.tiff \
        -sigmoidal-contrast 4x82% \
        -matte -channel A \
        ${DST}.0.tiff -fx '0.4+0.55*(v.luminance^3)' \
        ${DST}.0.tiff +swap \
        -compose src-over -composite \
        -compress zip ${DST}.tiff
    rm ${DST}.0.tiff
    #test -r ${DST}.tiff
}

final () {
    SFX=${1}
    shift
    ${CONV} ${DST}.tiff \
        ${@} \
        -quality 90 ${DST}${SFX}.jpeg
    r=${?}
    return ${r}
}

prep "${@}"
[ "${1}" = prep ] && exit
[ "${1}" = auto ] && { auto "${@}"; exit; }
[ "${1}" = cluster ] && { cluster "${@}"; exit; }
mkpano "${@}" || exit ${?}
[ "${1}" = pano ] && exit
#mkhdr "${@}" || exit ${?}
#[ "${1}" = hdr ] && exit
#HH='-resize x2816'
#[ "${3}" = e ] || HH=''
${CONV} ${DST}.tiff ${HH} -unsharp 0x0.75+0.6+0.05 -compress zip ${DST}.tiff \
&& final -huge \
&& ${CONV} ${DST}.tiff -resize x1536 -unsharp 0x0.75+0.6+0.04 -compress zip ${DST}.tiff \
&& final -big \
&& ${CONV} ${DST}.tiff -resize x768 -unsharp 0x0.65+0.5+0.04 -compress zip ${DST}.tiff \
&& final -middle \
&& ${CONV} ${DST}.tiff -resize x384 -unsharp 0x0.55+0.5+0.04 -compress zip ${DST}.tiff \
&& ${CONV} ${DST}.tiff -resize x256 -unsharp 0x0.45+0.4+0.03 -compress zip ${DST}.tiff \
&& final -small -gamma 1.10 \
&& rm ${DST}.tiff
exit
