#!/usr/bin/env zsh # Copyright (C) 2022-2024 Sergey Matveev VERSION=0.7.0 setopt ERR_EXIT pagesize=${PAGESIZE:-100} ordering=${ORDERING:-Om} style=$STYLE exifTagsOmit=( ExifToolVersion Directory FileAccessDate FileAttributes FileInodeChangeDate FilePermissions ) [[ -z $style ]] || style="" mkdir -p alt .info preview setopt EXTENDED_GLOB imgs=() for img (*.jxl(N)) { [[ -r .info/$img.img ]] || imgs=($imgs $img) } [[ ${#imgs} == 0 ]] || { echo Infos... >&2 parallel "jxlinfo {} > .info/{}.img" ::: $imgs } imgs=() src=(*.jxl) for img ($src) { [[ -r .info/$img.exif ]] || imgs=($imgs $img) } src=() [[ ${#imgs} == 0 ]] || { echo Exif info... >&2 parallel "exiftool -escapeHTML -htmlFormat -groupHeadings --${=${(j/ --/)exifTagsOmit}} {} > .info/{}.exif" ::: $imgs } imgs=((*.jxl)($ordering)) pages=$(( ${#imgs} / $pagesize )) [[ $(( $pages * $pagesize )) -ge ${#imgs} ]] || pages=$(( $pages + 1 )) local tmp=`mktemp` trap "rm -f $tmp" HUP PIPE INT QUIT TERM EXIT pams=() djxl2pam="( djxl --quiet {} - --output_format ppm || djxl --quiet {} - --output_format pgm )" if [[ -n "$NOALT" ]] ; then for img ($imgs) { [[ -r preview/$img.webp ]] || pams=($pams $img) } else jpgs=() pngs=() for img ($imgs) { [[ -r .info/$img.img ]] if ! [[ ( -r alt/$img.jpg ) || ( -r alt/$img.png ) ]] ; then grep -q "JPEG bitstream reconstruction" .info/$img.img && jpgs=($jpgs $img) || pngs=($pngs $img) fi [[ -r preview/$img.webp ]] || pams=($pams $img) } [[ ${#jpgs} == 0 ]] || { echo JPEG reconstruction... >&2 parallel "djxl --quiet {} alt/{}.jpg && touch -r {} alt/{}.jpg" ::: $jpgs } jpgs=() [[ ${#pngs} == 0 ]] || { echo PNG generation... >&2 parallel "$djxl2pam | pamtopng > {}.png" ::: $pngs parallel "pngcrush -warn -rem alla -rem allb -z 2 {}.png alt/{}.png && rm {}.png" ::: $pngs parallel "advpng --quiet --recompress -4 alt/{}.png && touch -r {} alt/{}.png" ::: $pngs } pngs=() fi mkpreview="pnmscale -w 100" mkpreview="$mkpreview | cwebp -quiet -pass 10 -alpha_filter best -m 6 -o preview/{}.webp -- -" mkpreview="$mkpreview && touch -r {} preview/{}.webp" [[ ${#pams} == 0 ]] || { echo Generating previews... >&2 parallel "$djxl2pam | $mkpreview" ::: $pams } pams=() for (( i=1 ; i <= ${#imgs} ; i++ )) { local img=${imgs[$i]} echo $i $img local dst=$i.img.html local p=$(( ( $i / $pagesize ) + 1 )) cat > $tmp < ${style} Image ${i}/${#imgs}: $img EOF [[ $i -eq 1 ]] || echo "" >> $tmp [[ $i -eq ${#imgs} ]] || echo "" >> $tmp cat >> $tmp < EOF [[ $i -eq 1 ]] || echo "<<<" >> $tmp echo "^^^" >> $tmp [[ $i -eq ${#imgs} ]] || echo ">>>" >> $tmp echo "
\"$img\"" >> $tmp [[ ! -r ${img}.txt ]] || { echo "
" >> $tmp
        cat ${img}.txt >> $tmp
        echo "
" >> $tmp } [[ ! -r ${img}.html ]] || { cat ${img}.html >> $tmp } echo "
" >> $tmp [[ -r .info/$img.img ]] echo "
" >> $tmp
    cat .info/$img.img >> $tmp
    echo "
" >> $tmp [[ -n "$NOALT" ]] || { if [[ $img:e = jxl ]] ; then echo "Alternative formats:" >> $tmp [[ -r alt/$img.jpg ]] && { echo "JPEG" >> $tmp } || { echo "PNG" >> $tmp } fi echo "
" >> $tmp } [[ -r .info/$img.exif ]] cat .info/$img.exif >> $tmp echo "" >> $tmp cmp -s $tmp $dst || { cat $tmp > $dst touch -r $img $dst } } for (( p=1 ; p <= $pages ; p++ )) { local dst=$p.page.html cat > $tmp < ${style} Page ${p}/$pages EOF [[ $p -eq 1 ]] || echo "" >> $tmp [[ $p -eq $pages ]] || echo "" >> $tmp cat >> $tmp < EOF [[ $p -ne 1 ]] || { [[ ! -r .txt ]] || { echo "
" >> $tmp
            cat .txt >> $tmp
            echo "
" >> $tmp } [[ ! -r .html ]] || { cat .html >> $tmp } } [[ $p -eq 1 ]] || echo "<<<" >> $tmp [[ $p -eq $pages ]] || echo ">>>" >> $tmp echo "| home" >> $tmp echo "| end" >> $tmp echo "
" >> $tmp for (( i=1 ; i <= $pagesize ; i++ )) { img=$(( ( $p - 1 ) * $pagesize + $i )) [[ $img -le ${#imgs} ]] || break echo "" >> $tmp alt="preview ${img}" title="" [[ ! -r ${imgs[$img]}.txt ]] || { alt=`cat ${imgs[$img]}.txt` title="title=\"$alt\"" } echo "\"$alt\"" >> $tmp } echo "" >> $tmp cmp -s $tmp $dst || { cat $tmp > $dst echo page $p } }