Support new background layer name
[fgen.git] / fgen.sh
diff --git a/fgen.sh b/fgen.sh
index 019e662..ea04217 100755 (executable)
--- a/fgen.sh
+++ b/fgen.sh
@@ -3,17 +3,21 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2023 Hugo Villeneuve <hugo@hugovil.com>
 
+# Abort on all errors
+set -e
+
 PROG_NAME=$(basename $0)
 
 # Set default values
-main_layer="Layer 558"
+bg_layer_name="background"
 
 # Pour conversion vidéo:
-fps=3
+fps=8
 
 debug=0
-
+trames=1
 SED=sed
+FFMPEG_OPTS="-hide_banner -loglevel error -y"
 
 # -limit memory 5000mb -limit disk 5gb
 IM_OPS=""
@@ -33,7 +37,7 @@ function log_dbg() {
 # Arg1: layer
 function get_size()
 {
-    cat ${layers} | grep "${1}" | ${SED} "s/.*geometry:\([0-9]\+x[0-9]\+\).*/\1/g"
+    cat ${layers} | grep -m 1 "${1}" | ${SED} "s/.*geometry:\([0-9]\+x[0-9]\+\).*/\1/g"
 }
 
 # Arg1: layer
@@ -59,13 +63,12 @@ function get_label()
 # Arg1: line
 function get_frame_id()
 {
-    frame=$(echo "${1}" | grep -e "label:[0-9]" | ${SED} "s/label:\([0-9]\+\),.*/\1/g")
+    frame=$(echo "${1}" | grep -e "label:[0-9]\+," | ${SED} "s/label:\([0-9]\+\),.*/\1/g")
 
     if [ x"${frame}" = x"" ]; then
-        return 1
+        echo ""
     else
         echo "${frame}"
-        return 0
     fi
 }
 
@@ -88,14 +91,22 @@ print_usage()
     echo
     echo "Options:"
     echo "  -d   affiche les informations de debug"
+    echo "  -f   ne regénère pas les trames, mais uniquement la séquence vidéo"
+    echo "  -r   nombre de trames par seconde (FPS)"
     echo "  -h   affiche ce message d'aide"
 }
 
-while getopts "dh" flag ;do
+while getopts "dhfr:" flag ;do
     case ${flag} in
         d)
             debug="1"
             ;;
+        f)
+            trames=0
+            ;;
+        r)
+            fps="${OPTARG}"
+            ;;
        h)
            print_usage
             exit 0
@@ -135,7 +146,6 @@ layers=${dest}/layers.txt
 
 if [ ! -d ${dest} ]; then
     mkdir ${dest}
-    #    rm -rf ${dest}
 fi
 
 for tool in convert composite identify; do
@@ -145,56 +155,76 @@ for tool in convert composite identify; do
     fi
 done
 
-identify ${IM_OPS} -verbose -format "label:%l,geometry:%g\n" ${src} > ${layers}
-
-# Ignore empty labels:
-${SED} -i -e /label:,.*/d ${layers}
-
-# Extract global frame size:
-size=$(get_size "${main_layer}")
-
-log_dbg "CANVAS SIZE=${size}"
+if [ ${trames} -eq 1 ]; then
+    identify ${IM_OPS} -verbose -format "label:%l,geometry:%g\n" ${src} > ${layers}
 
-rm -f ${dest}/frame*.png
+    # Ignore empty labels:
+    ${SED} -i -e /label:,.*/d ${layers}
 
-# Create background frame:
-convert -size ${size} xc:none ${dest}/background.png
+    # Extract global frame size:
+    size=$(get_size "${bg_layer_name}")
 
-# Remove first line (Layer 558):
-${SED} -i -e '1d' ${layers}
+    log_dbg "Background size: ${size}"
 
-# Will start at frame 2 at first loop iteration
-f=1
-
-files=""
-
-while read l; do
-    f=$((${f} + 1))
-
-    label=$(get_label "${l}")
-    p=$(get_pos "${l}")
-    nf=$(get_frame_id "${l}")
-
-    log_dbg "Couche ${f}"
-    log_dbg "  nom: ${label}"
-    log_dbg "  pos: ${p}"
-
-    if is_skip_label "${label}"; then
-        log_dbg "  skip..."
-        continue
-    fi
-
-    files="${files} -page ${p} ${src}[${f}]"
-
-    if [ x"${nf}" != x"" ]; then
-        log_dbg "New frame ID: ${nf}"
-        convert -page +0+0 ${dest}/background.png ${files} -background none -layers merge ${dest}/f${nf}.png
-        files=""
+    if [ x"${size}" = x"" ]; then
+        echo "Error: background layer not found"
+        exit 1
     fi
 
-done <${layers}
+    # Remove background line:
+    ${SED} -i -e /label:${bg_layer_name},.*/d ${layers}
+
+    # Create background frame:
+    convert -size ${size} xc:none ${dest}/background.png
+
+    # Will start at frame 2 at first loop iteration
+    f=1
+
+    nf=""
+    oldnf=""
+    files=""
+
+    while read l; do
+        f=$((${f} + 1))
+
+        label=$(get_label "${l}")
+        p=$(get_pos "${l}")
+        nf=$(get_frame_id "${l}")
+
+        log_dbg "Couche ${f}"
+        log_dbg "  nom: ${label}"
+        log_dbg "  pos: ${p}"
+
+        if is_skip_label "${label}"; then
+            log_dbg "  skip..."
+            continue
+        fi
+
+        files="${files} -page ${p} ${src}[${f}]"
+
+        if [ x"${nf}" != x"" ]; then
+            # Only check expected frame if oldnf is set...
+            if [ x"${oldnf}" != x"" ]; then
+                expected_nf=$((${oldnf} + 1))
+
+                if [ ${expected_nf} -ne ${nf} ]; then
+                    echo "Error: invalid frame sequence: ${nf}"
+                    echo "  previous: ${oldnf}"
+                    echo "  expected: ${expected_nf}"
+                    files=""
+                    continue
+                fi
+            fi
+
+            log_dbg "New frame ID: ${nf}"
+            convert -colorspace sRGB -page +0+0 ${dest}/background.png ${files} -background none -layers merge ${dest}/f${nf}.png
+            files=""
+            oldnf="${nf}"
+        fi
+    done <${layers}
+fi
 
 if which ffmpeg 1> /dev/null 2>&1; then
     # Conversion vidéo:
-    ffmpeg -y -r ${fps} -start_number 1 -i ${dest}/f%d.png ${dest}/sequence.mp4
+    ffmpeg ${FFMPEG_OPTS} -r ${fps} -start_number 1 -i ${dest}/f%d.png ${dest}/sequence.mp4
 fi