1,4 → 1,4 |
#!/bin/bash |
#!/usr/bin/env bash |
# |
# $Rev$ $Date$ |
# |
45,35 → 45,47 |
# <http://lists.mplayerhq.hu/pipermail/mencoder-users/2006-August/003843.html> |
# [VC1] VC-1 and derived codecs information |
# <http://wiki.multimedia.cx/index.php?title=VC-1> |
# [FJ] GNU seq’s cousin on FreeBSD is... jot |
# <http://www.nevdull.com/2007/09/24/gnu-seqs-cousin-on-freebsd-is-jot/> |
# [FNL] Re: Replacing spaces with newlines using awk: msg#00064 |
# <http://osdir.com/ml/editors.sed.user/2004-07/msg00064.html> |
# [FD1] File Descriptors in Bourne shell (sh,ksh,bash). |
# <http://mixedvolume.blogspot.com/2004/12/file-descriptors-in-bourne-shell.html> |
# [FD2] Redirection [[Bash Hackers Wiki] |
# <http://bash-hackers.org/wiki/doku.php/syntax/redirection> |
# |
|
declare -r VERSION="1.0.99" # ("1.1.0 RC") |
declare -r VERSION="1.0.100a" # ("1.1.0 RC2") |
# {{{ # CHANGELOG |
# History (The full changelog can be found at <http://p.outlyer.net/vcs/files/CHANGELOG>). |
# |
# 1.0.99: (2009-3-11) |
# * FEATURE: Experimental support for DVDs (-V) |
# * FEATURE: Added JPEG 2000 output format (-j2) |
# * FEATURE/COSMETIC: Polaroid mode now produces a polaroid-like frame, the |
# older version is now renamed as simply 'photos' |
# New "funky" modes: newer polaroid, photos (older polaroid), |
# polaroidframe. |
# * Overrideable variables: DISABLE_SHADOWS and DISABLE_TIMESTAMPS (set to |
# 1 to disable) |
# * BUGFIX/COSMETIC: Re-added the missed space before filename |
# * BUGFIX/COSMETIC: Reworked alignment and padding |
# * Timestamps size is adjusted with smaller captures |
# * BUGFIX: Fixed polaroid/rotate bug where all images overlapped on the |
# same position (reported by Aleksandar Urošević, formerly |
# unreproducible) |
# * Better detection of video/audio features by falling back to ffmpeg when |
# appropriate |
# 1.0.100a: (Focus on FreeBSD support -and hopefully better POSIX compatibility-) |
# * FEATURE: FreeBSD (7.1-RELEASE) support |
# * COMPATIBILITY: |
# - Call bash through env |
# - Ensure we're using the correct getopt version |
# - Try to use POSIX sed options when appropriate |
# - Replaced incompatible sed constructs |
# - Use mktemp's common GNU/BSD(/POSIX?) syntax |
# - Use jot instead of seq if required and available |
# * BUGFIX: Don't fail if tput is unable to change colours |
# * BUGFIX: Check for requirements before anything else |
# * INTERNAL: Cache tput output |
# * FEATURE: Added -R / --randomsource. Mainly useful for debugging, |
# also to repeat a set of results and compare outputs on different |
# systems |
# * Corrected info message in photos mode |
# |
# }}} # CHANGELOG |
|
set -e |
|
# This might change the way some commands are used. |
# Right now it's unused |
#declare -i IS_GNU=1 |
#grep -qi gnu <<<"$OSTYPE" || IS_GNU=0 |
|
# {{{ # TODO |
|
# TODO / FIXME: |
# * [[R1#22]] states that not all bc versions understand '<', more info required |
# * [[x1]] Find out why the order of ffmpeg arguments breaks some files. |
81,7 → 93,6 |
# * Better DVD support (e.g. real detection of aspect ratio) |
# * Use ffmpeg's detected length if shorter than mplayer's |
# |
|
# }}} # TODO |
|
# {{{ # Constants |
133,10 → 144,20 |
# When shadows are enabled, 5 is substracted from this value in csheet_montage |
# so keep this in mind! |
declare -ri HPAD=8 |
|
# These are used as constants but will be set from the available system |
# programs |
# ERESED # see choose_eresed |
# SEQ # see choose_seqw |
|
# }}} # End of constants |
|
# {{{ # Override-able variables |
|
# GETOPT must be correctly set or the script will fail. |
# It can be set in the configuration files if it isn't in the path or |
# the first getopt in the path isn't the right version. |
# A check will be made and a warning with details shown if required. |
declare GETOPT=getopt |
# Set to 1 to print function calls |
declare -i DEBUG=0 |
declare -i DEFAULT_INTERVAL=300 |
272,6 → 293,10 |
# (defined in the constants block) |
declare -a VID= |
|
# These variables will hold the output of tput, used |
# to colourise feedback |
declare prefix_err= prefix_inf= prefix_warn= suffix_fback= |
|
# Workarounds: |
# Argument order in FFmpeg is important -ss before or after -i will make |
# the capture work or not depending on the file. See -Wo. |
320,6 → 345,12 |
declare -i DISABLE_SHADOWS=0 |
declare -i DISABLE_TIMESTAMPS=0 |
|
# Sets which function is used to obtain random numbers valid values are |
# bashrand and filerand. |
# Setting it manually will break it, calling with -R changes this to filerand. |
# See rand() for an explanation |
declare RANDFUNCTION=bashrand |
|
# }}} # Variables |
|
# {{{ # Configuration handling |
358,6 → 389,8 |
'MIN_LENGTH_FOR_END_OFFSET' |
'DEBUG' |
'DISABLE_.*' |
# Note GETOPT doesn't make sense to be overridden from the command-line |
'GETOPT' |
) |
|
# This is only used to exit when -DD is used |
395,7 → 428,7 |
local compregex=$( sed 's/ /|/g' <<<${ALLOWED_OVERRIDES[*]} ) |
|
# Don't allow ';', FIXME: dunno how secure that really is... |
# FIXME: ...it doesn't really works anyway |
# FIXME: ...it doesn't really work anyway |
if ! egrep -q '^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*=[^;]*' <<<"$o" ; then |
return |
fi |
403,8 → 436,8 |
return |
fi |
|
local varname=$(sed -r 's/^[[:space:]]*([a-zA-Z0-9_]*)=.*/\1/'<<<"$o") |
local varval=$(sed -r 's/[^=]*=(.*)/\1/'<<<"$o") |
local varname=$($ERESED 's/^[[:space:]]*([a-zA-Z0-9_]*)=.*/\1/'<<<"$o") |
local varval=$($ERESED 's/[^=]*=(.*)/\1/'<<<"$o") |
# FIXME: Security! |
local curvarval= |
eval curvarval='$'"$varname" |
497,6 → 530,75 |
[ '1' == "$(bc -q <<<"$1 $op $3")" ] |
} |
|
# converts spaces to newlines in a x-platform way [[FNL]] |
# stonl($1 = string) |
stonl() { |
# Not pretty, but seems to be standard ('\n' works in GNU |
# but not in e.g. FreeBSD) |
sed 's/ /\ |
/g' <<<"$1" |
} |
|
# bash version of ord() [[ORD]] |
# prints the ASCII value of a character |
ord() { |
printf '%d' "'$1" |
} |
|
# Wrapper around $RANDOM, not called directly, wrapped again in rand(). |
# See rand() for an explanation. |
bashrand() { |
echo $RANDOM |
} |
|
# Prepares for "filerand()" calls |
# File descriptor 7 is used to keep a file open, from which data is read |
# and then transformed into a number. |
# init_filerand($1 = filename) |
init_filerand() { # [[FD1]], [[FD2]] |
test -r "$1" |
exec 7<"$1" |
# closed in exithdlr |
} |
|
# Produce a (not-really-)random number from a file, not called directly wrapped |
# in rand() |
# Note that once the file end is reached, the random values will always |
# be the same (hash_string result for an empty string) |
filerand() { |
local b= |
# "read 5 bytes from file descriptor 7 and put them in $b" |
read -n5 -u7 b |
hash_string "$b" |
} |
|
# Produce a random number |
# $RANDFUNCTION defines wich one to use (bashrand or filerand). |
# Since functions using random values are most often run in subshells |
# setting $RANDOM to a given seed has not the desired effect. |
# filerand() is used to that effect; it keeps a file open from which bytes |
# are read and not-so-random values generated; since file descriptors are |
# inherited, subshells will "advance" the random sequence. |
# Argument -R enables the filerand() function |
rand() { |
$RANDFUNCTION |
} |
|
# produces a numeric value from a string |
hash_string() { |
local HASH_LIMIT=65536 |
local v="$1" |
local -i hv=15031 |
local c= |
if [ "$v" ]; then # seqw 0 0 would be catastrophic if SEQ==jot |
for i in $(seqw 0 $(( ${#v}-1 ))); do |
c=$( ord ${v:$i:1} ) |
hv=$(( ( ( $hv << 1 ) + $c ) % $HASH_LIMIT )) |
done |
fi |
echo $hv |
} |
|
# Applies the Pythagorean Theorem |
# pyth_th($1 = cathetus1, $2 = cathetus2) |
pyth_th() { |
532,13 → 634,13 |
# New parsing code: replaces units by a product |
# and feeds the resulting string to bc |
t=$s |
t=$(sed -r 's/([0-9]+)h/ ( \1 * 3600 ) + /g' <<<$t) |
t=$(sed -r 's/([0-9]+)m/ ( \1 * 60 ) + /g' <<<$t) |
t=$($ERESED 's/([0-9]+)h/ ( \1 * 3600 ) + /g' <<<$t) |
t=$($ERESED 's/([0-9]+)m/ ( \1 * 60 ) + /g' <<<$t) |
t=$(sed 's/s/ + /g' <<<$t) |
t=$(sed -r 's/([0-9])\./\1 + ./g' <<<"$t") # seconds followed by ms, with no "S" |
t=$(sed -r 's/\.\.+/./g'<<<$t) |
t=$(sed -r 's/\.([0-9]+)/0.\1 + /g' <<<$t) |
t=$(sed -r 's/\+ ?$//g' <<<$t) |
t=$($ERESED 's/([0-9])\./\1 + ./g' <<<"$t") # seconds followed by ms, with no "S" |
t=$($ERESED 's/\.\.+/./g'<<<$t) |
t=$($ERESED 's/\.([0-9]+)/0.\1 + /g' <<<$t) |
t=$($ERESED 's/\+ ?$//g' <<<$t) |
|
r=$(bc -lq <<<$t 2>/dev/null) # bc parsing fails with correct return code |
if [ -z "$r" ]; then |
618,7 → 720,7 |
fi |
|
# Trim (most) decimals |
sed -r 's/\.([0-9][0-9]).*/.\1/'<<<$R |
$ERESED 's/\.([0-9][0-9]).*/.\1/'<<<$R |
} |
|
# Prints a given size in human friendly form |
666,9 → 768,9 |
local to="$2" |
|
# Output extension |
local ext=$(sed -r 's/.*\.(.*)/\1/' <<<$to) |
local ext=$($ERESED 's/.*\.(.*)/\1/' <<<$to) |
# Input extension |
local iext=$(sed -r 's/.*\.(.*)/\1/' <<<$to) |
local iext=$($ERESED 's/.*\.(.*)/\1/' <<<$to) |
# Input filename without extension |
local b=${to%.$iext} |
|
715,21 → 817,35 |
# way to do it portably. |
# Alternatives: |
# * fdisk -s (no need for privileged access, read-only) |
# Prints the number of blocks. In Linux they're always 1024 AFAICT, |
# but I'm not sure about other unices (the -in disk- block size for |
# DVDs is 2048). |
# Prints the number of blocks (only in GNU's version?, FreeBSD's |
# doesn't, so probably POSIX in general doesn't either). |
# In Linux blocks are always 1024 AFAICT, but I'm not sure about |
# other unices (the -in disk- block size for DVDs is 2048). |
# * hal |
# hal-find-by-property --key block.device --string <(REAL)DEVICE> |
# hal-get-property --udi <DEVICEID> --key volume.disc.capacity |
# Gets byte size but HAL is far from standard (only Linux |
# and FreeBSD have it AFAIK) |
# and FreeBSD have it AFAIK. DBUS, on which it relies, wasn't |
# enabled byb default on my FreeBSD install). |
# FreeBSD has no block devices either. |
# * sysfs |
# cat /sys/block/<(KERNEL)DEVICE>/size |
# Size is given in sectors (512 blocks). Linux only. *BSD has |
# sysctl of which I've no clue. |
local dev="$1" |
local numblocks=$(/sbin/fdisk -s "$dev") |
# Only GNU systems with block devices are compatible with the current code |
if [ ! -b "$1" ] || grep -q gnu <<<"$OSTYPE" ; then |
echo "?" |
return |
fi |
|
local numblocks=$(/sbin/fdisk -s "$dev" 2>"$stderr") |
# FIXME: When fdisk is replaced by a better alternative this should go away |
if is_number "$numblocks" ; then |
get_pretty_size $(( 1024 * $numblocks )) |
else |
echo "?" |
fi |
} |
|
# Tests the presence of all required programs |
736,13 → 852,12 |
# test_programs() |
test_programs() { |
local retval=0 last=0 |
for prog in getopt mplayer convert montage identify bc \ |
ffmpeg mktemp sed grep egrep cut; do |
type -pf "$prog" >/dev/null |
if [ $? -ne 0 ] ; then |
for prog in mplayer convert montage identify bc \ |
ffmpeg mktemp sed grep egrep cut $SEQ ; do |
if ! type -pf "$prog" ; then |
error "Required program $prog not found!" |
let 'retval++' |
fi |
fi >/dev/null |
done |
# TODO: [x2] |
|
749,6 → 864,60 |
return $retval |
} |
|
# Test wether $GETOP is a compatible version; try to choose an alternate if |
# possible |
choose_getopt() { |
if ! type -pf $GETOPT ; then |
# getopt not in path |
error "Required program getopt not found!" |
return $EX_UNAVAILABLE |
fi >/dev/null |
local goe= gor=0 |
# Try getopt. If there's more than one in the path, try all of them |
for goe in $(type -paf $GETOPT) ; do |
"$goe" -T || gor=$? |
if [ $gor -eq 4 ]; then |
# Correct getopt found |
GETOPT="$goe" |
break; |
fi |
done >/dev/null |
if [ $gor -ne 4 ]; then |
error "No compatible version of getopt in path, can't continue." |
error " For details on how to correct this problems, see <http://p.outlyer.net/vcs#getopt>" |
return $EX_UNAVAILABLE |
fi |
return 0 |
} |
|
# Set the correct argument to pass to sed |
# The argument to enable extended regular expressions is different in GNU (-r) |
# and POSIX (-E), try to detect it |
choose_eresed() { |
if [ "a" == "$(sed -r 's/A/a/' 2>/dev/null<<<'A')" ]; then |
ERESED='sed -r' |
elif [ "a" == "$(sed -E 's/A/a/' 2>/dev/null<<<'A')" ]; then |
ERESED='sed -E' |
else |
error "The version of sed in the system is not supported. |
Please, contact the author" |
return $EX_SOFTWARE |
fi |
} |
|
# Choose seq or jot, fail if none is present |
# The actual program is wrapped in seqw() |
choose_seqw() { |
if type -pf seq ; then |
SEQ='seq' |
elif type -pf jot ; then |
SEQ='jot' |
else |
error "Either seq or jot are required" |
return $EX_UNAVAILABLE |
fi >/dev/null |
} |
|
# Remove any temporal files |
# Does nothing if none has been created so far |
# cleanup() |
763,6 → 932,10 |
# interrupted) |
# exithdlr() |
exithdlr() { |
# I don't think that's really required anyway |
if [ "$RANDFUNCTION" == "filerand" ]; then |
7<&- # Close FD 7 |
fi |
cleanup |
} |
|
774,13 → 947,11 |
# error($1 = text) |
error() { |
if [ $verbosity -ge $V_ERROR ]; then |
if [ $plain_messages -eq 0 ]; then |
tput bold ; tput setaf 1; |
fi |
[ $plain_messages -eq 0 ] && echo -n $prefix_err |
# sgr0 is always used, this way if |
# a) something prints inbetween messages it isn't affected |
# b) if plain_messages is overridden colour stops after the override |
echo "$1" ; tput sgr0 |
echo "$1$suffix_fback" |
fi >&2 |
# It is important to redirect both tput and echo to stderr. Otherwise |
# n=$(something) wouldn't be coloured |
790,10 → 961,8 |
# warning($1 = text) |
warn() { |
if [ $verbosity -ge $V_WARN ]; then |
if [ $plain_messages -eq 0 ]; then |
tput bold ; tput setaf 3; |
fi |
echo "$1" ; tput sgr0 |
[ $plain_messages -eq 0 ] && echo -n $prefix_warn |
echo "$1$suffix_fback" |
fi >&2 |
} |
# |
801,10 → 970,8 |
# inf($1 = text) |
inf() { |
if [ $verbosity -ge $V_INFO ]; then |
if [ $plain_messages -eq 0 ]; then |
tput bold ; tput setaf 2; |
fi |
echo "$1" ; tput sgr0 |
[ $plain_messages -eq 0 ] && echo -n $prefix_inf |
echo "$1$suffix_fback" |
fi >&2 |
} |
# |
835,6 → 1002,42 |
return 1 |
} |
|
# |
# Initialises the variables affecting coloured feedback |
init_feedback() { |
# If tput isn't found simply ignore tput commands |
# (no colour support) |
if ! type -pf tput >/dev/null ; then |
# XXX: Are nested functions supported by older versions? |
tput() { cat >/dev/null <<<"$1"; } |
elif ! tput bold || # If tput can't tinker with the color, no need to continue |
! tput setaf 0 >/dev/null || |
! tput sgr0 ; |
then |
prefix_err= prefix_inf= prefix_warn= |
suffix_fback= |
else # tput doesn't fail to change colors |
prefix_err=$(tput bold; tput setaf 1) |
prefix_warn=$(tput bold; tput setaf 3) |
prefix_inf=$(tput bold; tput setaf 2) |
suffix_fback=$(tput sgr0) |
fi |
} |
|
# |
# seq wrapper/replacement |
# seq($1 = from, $2 = to) |
seqw() { |
if [ "$SEQ" == "seq" ]; then |
seq $1 $2 |
elif [ "$SEQ" == "jot" ]; then |
jot $(( 1 + $2 - $1 )) $1 |
else |
error "'$SEQ' is not supported, please change the value of \$SEQ" |
return $EX_SOFTWARE |
fi |
} |
|
# }}} # Convenience functions |
|
# {{{ # Core functionality |
845,10 → 1048,13 |
trace $FUNCNAME $@ |
# Try to use /dev/shm if available, this provided a very small |
# benefit on my system but me of help for huge files. Or maybe won't. |
# Passing a full path template is more x-platform than using |
# -t / -p |
if [ -d /dev/shm ] && [ -w /dev/shm ]; then |
VCSTEMPDIR=$(mktemp -d -p /dev/shm vcs.XXXXXX) |
VCSTEMPDIR=$(mktemp -d /dev/shm/vcs.XXXXXX) |
else |
VCSTEMPDIR=$(mktemp -d -t vcs.XXXXXX) |
[ "$TMPDIR" ] || TMPDIR="/tmp" |
VCSTEMPDIR=$(env TMPDIR="$TMPDIR" mktemp -d "$TMPDIR/vcs.XXXXXX") |
fi |
if [ ! -d "$VCSTEMPDIR" ]; then |
error "Error creating temporary directory" |
861,7 → 1067,7 |
# new_temp_file($1 = suffix) |
new_temp_file() { |
trace $FUNCNAME $@ |
local r=$(mktemp -p "$VCSTEMPDIR" "vcs-XXXXXX") |
local r=$(env TMPDIR="$VCSTEMPDIR" mktemp "$VCSTEMPDIR/vcs-XXXXXX") |
if [ ! -f "$r" ]; then |
error "Failed to create temporary file" |
return $EX_CANTCREAT |
886,13 → 1092,13 |
# There're 5 rows of extra info printed |
local ncolours=$(( $(convert -list color | wc -l) - 5 )) |
randcolour() { |
lineno=$(( 5 + ( $RANDOM % $ncolours ) )) |
lineno=$(( 5 + ( $(rand) % $ncolours ) )) |
convert -list color | sed -n "${lineno}p" | cut -d' ' -f1 # [[R1#19]] |
} |
else # Pseudo-random mode, WIP! |
randccomp() { |
# colours are in the 0..65535 range, while RANDOM in 0..32767 |
echo $(( $RANDOM + $RANDOM + ($RANDOM % 1) )) |
echo $(( $(rand) + $(rand) + ($(rand) % 1) )) |
} |
randcolour() { |
echo "rgb($(randccomp),$(randccomp),$(randccomp))" |
901,7 → 1107,7 |
|
local nfonts=$(( $(convert -list type | wc -l) - 5 )) |
randfont() { |
lineno=$(( 5 + ( $RANDOM % $nfonts ))) |
lineno=$(( 5 + ( $(rand) % $nfonts ))) |
convert -list type | sed -n "${lineno}p" | cut -d' ' -f1 # [[R1#19]] |
} |
|
1164,22 → 1370,6 |
# Apply a framed photo-like effect |
# Taken from <http://www.imagemagick.org/Usage/thumbnails/#polaroid> |
# filt_photoframe($1 = filename, $2 = timestamp, $3 = width, $4 = height) |
filt_photoframe0() { |
trace $FUNCNAME $@ |
# local file="$1" ts=$2 w=$3 h=$4 |
# Tweaking the size gives a nice effect too |
# w=$(( $w - ( $RANDOM % ( $w / 3 ) ) )) |
# TODO: Split softshadow in a filter |
# The border is relative to the input size (since 1.0.99), with a maximum of 6 |
# Should probably be bigger for really big frames |
# Note that only images below 21600px (e.g. 160x120) go below a 6px border |
local border=$(( ($3*$4) / 3600 )) |
[ $border -lt 7 ] || border=6 |
echo -n "-bordercolor white -border $border -bordercolor grey60 -border 1 " |
echo -n "-background black \( +clone -shadow 60x4+4+4 \) +swap " |
echo "-background none -flatten -trim +repage" |
} |
|
filt_photoframe() { |
trace $FUNCNAME $@ |
# local file="$1" ts=$2 w=$3 h=$4 |
1220,7 → 1410,7 |
filt_randrot() { |
trace $FUNCNAME $@ |
# Rotation angle [-18..18] |
local angle=$(( ($RANDOM % 37) - 18 )) |
local angle=$(( ($(rand) % 37) - 18 )) |
echo "-background none -rotate $angle " |
} |
|
1354,7 → 1544,7 |
local accoffset # The absolute (horizontal) offset used on the next iteration |
local cmdopts # Holds the arguments passed to convert to compose the sheet |
local w # Width of the current snap |
for row in $(seq 1 $numrows) ; do |
for row in $(seqw 1 $numrows) ; do |
col=0 |
rowfile=$(new_temp_file .png) |
rowfiles+=( "$rowfile" ) |
1364,7 → 1554,7 |
# Base canvas # Integrated in the row creation since 1.0.99 |
|
# Step through vidcaps (col=[0..cols-1]) |
for col in $(seq 0 $(( $cols - 1 ))); do |
for col in $(seqw 0 $(( $cols - 1 ))); do |
# More cols than files in the last iteration (e.g. -n10 -c4) |
if [ -z "$1" ]; then break; fi |
w=$(imw "$1") |
1372,7 → 1562,7 |
# Stick the vicap in the canvas |
cmdopts="$cmdopts '$1' -geometry +${accoffset}+0 -composite " |
|
offset=$(( $minoffset + ( $RANDOM % $maxoffset ) )) |
offset=$(( $minoffset + ( $(rand) % $maxoffset ) )) |
let 'accoffset=accoffset + w - offset' |
shift |
done |
1391,9 → 1581,9 |
h=$(imh "$row") |
minoffset=$(( $h / 8 )) |
maxoffset=$(( $h / 4 )) |
offset=$(( $minoffset + ( $RANDOM % $maxoffset ) )) |
offset=$(( $minoffset + ( $(rand) % $maxoffset ) )) |
# The row is also offset horizontally |
cmdopts="$cmdopts '$row' -geometry +$(( $RANDOM % $maxoffset ))+$accoffset -composite " |
cmdopts="$cmdopts '$row' -geometry +$(( $(rand) % $maxoffset ))+$accoffset -composite " |
let 'accoffset=accoffset + h - offset' |
done |
# After the trim the image will be touching the outer borders and the heading and footer, |
1412,9 → 1602,9 |
# clean_timestamps($1 = space separated timestamps) |
clean_timestamps() { |
trace $FUNCNAME $@ |
# Note AFAIK sort only sorts lines, that's why y replace spaces by newlines |
# Note AFAIK sort only sorts lines, that's why I replace spaces by newlines |
local s=$1 |
sed 's/ /\n/g'<<<"$s" | sort -n | uniq |
stonl "$s" | sort -n | uniq |
} |
|
# Fills the $MPLAYER_CACHE and $VID variables with the video data |
1487,7 → 1677,6 |
# fi |
fi |
|
|
# Check sanity of the most important values |
is_number "${VID[$W]}" && is_number "${VID[$H]}" && is_float "${VID[$LEN]}" |
} |
1580,6 → 1769,13 |
local dvdn="$f" |
if [ -b "$dvdn" ]; then |
dvdn="DVD" |
elif [ -c "$dvdn" ]; then |
if grep -q bsd <<<"$OSTYPE"; then |
inf "Warning: DVD support is even more experimental in *BSD" |
else |
warn "DVD device is a character device" |
fi |
dvdn="DVD" |
elif [ ! -f "$dvdn" ]; then |
error "File \"$dvdn\" doesn't exist" |
return $EX_NOINPUT |
1625,7 → 1821,7 |
aspect_ratio=$(bc -lq <<< "${VID[$W]} / ${VID[$H]}") |
elif [ "-1" == "$aspect_ratio" ]; then |
aspect_ratio=$(guess_aspect ${VID[$W]} ${VID[$H]}) |
inf "Aspect ratio set to $(sed -r 's/(\.[0-9]{2}).*/\1/g'<<<$aspect_ratio)" |
inf "Aspect ratio set to $($ERESED 's/(\.[0-9]{2}).*/\1/g'<<<$aspect_ratio)" |
fi |
local vidcap_width=$(compute_width $vidcap_height) |
|
1997,7 → 2193,7 |
local filesize_value= |
if [ $DVD_MODE -eq 1 ]; then |
local is_dev=0 |
test -b "$DVD_FILE" && is_dev=1 |
( test -b "$DVD_FILE" || test -c "$DVD_FILE" ) && is_dev=1 |
local dvd_label=$(lsdvd "$DVD_FILE" | grep -o 'Disc Title: .*' | cut -d' ' -f3-) |
# lsdvd is guaranteed to be installed if DVD mode is enabled |
if [ $is_dev -eq 1 ]; then # This is a real DVD, not an iso |
2067,7 → 2263,7 |
# Tests integrity of some operations. |
# Used to test internal changes for consistency. |
# It helps me to identify incorrect optimizations. |
# unit_test() |
# unit_test(). Running with -D triggers this. |
unit_test() { |
local t op val ret comm retval=0 |
|
2074,6 → 2270,9 |
# Textual tests, compare output to expected output |
# Tests are in the form "operation arguments correct_result #Description" |
local TESTS=( |
# TODO: UNIX vs GNU |
#"stonl ..." |
|
"rmultiply 1,1 1 #Identity" |
"rmultiply 16/9,1 2 #Rounding" # 1.77 rounded 2 |
"rmultiply 4/3 1 #Rounding" # 1.33 rounded 1 |
2111,7 → 2310,7 |
# many of the inputs |
comm=$(sed 's!.* #!!g' <<<$t) |
# Expected value |
val=$(sed -r "s!.* (.*) #$comm\$!\1!g"<<<$t) |
val=$($ERESED "s!.* (.*) #$comm\$!\1!g"<<<$t) |
op=$(sed "s! $val #$comm\$!!g" <<<$t) |
if [ -z "$comm" ]; then |
comm=unnamed |
2152,7 → 2351,7 |
for t in "${TESTS[@]}"; do |
comm=$(sed 's!.* #!!g' <<<$t) |
# Expected value |
val=$(sed -r "s!.* (.*) #$comm\$!\1!g"<<<$t) |
val=$($ERESED "s!.* (.*) #$comm\$!\1!g"<<<$t) |
op=$(sed "s! $val #$comm\$!!g" <<<$t) |
if [ -z "$comm" ]; then |
comm=unnamed |
2267,7 → 2466,8 |
"photoframe": Use '-kf' or '--funky photoframe' |
Adds a photo-like white frame to each image. |
"polaroidframe": Use '-kL' or '--funky polaroidframe' |
Adds a polaroid picture-like white frame to each image. |
Adds a polaroid picture-like white frame to each |
image. |
"photos": Use '-kc' or '--funky photos' |
Combination of rotate, photoframe and overlap. |
Same as -kp -kr -ko. |
2278,6 → 2478,12 |
Imitates filmstrip look. |
"random": Use '-kx' or '--funky random' |
Randomizes colours and fonts. |
-R <file> |
--randomsource <file> Use the provided file as a source for random "values": |
they won't be random anymore, so two runs with the same |
source and same arguments will produce the same output |
in modes which use using randomisation (e.g. the |
"photos" and "polaroid" modes). |
|
Options used for debugging purposes or to tweak the internal workings: |
-M|--mplayer Force the usage of mplayer. |
2310,19 → 2516,27 |
|
#### Execution starts here #### |
|
# If tput isn't found simply ignore tput commands |
# (no colour support) |
# Important to do it before any message can be thrown |
if ! type -pf tput >/dev/null ; then |
tput() { cat >/dev/null <<<"$1"; } |
warn "tput wasn't found. Coloured feedback disabled." |
fi |
# Important to do this before any message can be thrown |
init_feedback |
|
# Adjust sed for POSIX/GNU compatibility |
choose_eresed |
# Adjust seq for POSIX/GNU compatibility |
choose_seqw |
# Ensure $GETOPT is Linux-style getopt |
choose_getopt |
|
# Execute exithdlr on exit |
trap exithdlr EXIT |
|
show_vcs_info |
|
# Test requirements. Important, must check before looking at the |
# command line (since getopt is used for the task) |
test_programs || exit $EX_UNAVAILABLE |
|
# The command-line overrides any configuration. And the configuration |
# is able to change the program in charge of parsing options ($GETOPT) |
load_config |
|
# {{{ # Command line parsing |
2332,13 → 2546,12 |
ARGS="$@" |
|
# [[R0]] |
TEMP=$(getopt -s bash -o i:n:u:T:f:t:S:j::hFMH:c:ma:l:De::U::qAO:I::k:W:E:d:V: \ |
TEMP=$("$GETOPT" -s bash -o i:n:u:T:f:t:S:j::hFMH:c:ma:l:De::U::qAO:I::k:W:E:d:V:R: \ |
--long "interval:,numcaps:,username:,title:,from:,to:,stamp:,jpeg::,help,"\ |
"shoehorn:,mplayer,ffmpeg,height:,columns:,manual,aspect:,highlight:,"\ |
"extended::,fullname,anonymous,quiet,autoaspect,override:,mincho,funky:,"\ |
"end_offset:,disable:,dvd:" \ |
"end_offset:,disable:,dvd:,randomsource:,undocumented:" \ |
-n $0 -- "$@") |
|
eval set -- "$TEMP" |
|
while true ; do |
2520,7 → 2733,14 |
error "Wrong override format, it should be variable=value. Got '$2'." |
exit $EX_USAGE |
fi |
if grep -q 'GETOPT=' <<<"$2" ; then |
# If we're here, getopt has already been found and works, so it makes no |
# sense to override it; on the other hand, if it hasn't been correctly |
# set/detected we won't reach here |
warn "GETOPT can't be overridden from the command line." |
else |
override "$2" "command line" |
fi |
shift |
;; |
-W) # Workaround mode, see wa_ss_* declarations at the start for details |
2545,7 → 2765,7 |
pts_tstamps=$(( $pts_tstamps * 3 / 2 )) |
;; |
c|photos) # Same as overlap + rotate + photoframe, this is the older polaroid |
inf "Changed to polaroid funky mode." |
inf "Changed to photos funky mode." |
FILTERS_IND+=( 'filt_photoframe' 'filt_randrot' ) |
CSHEET_DELEGATE='csheet_overlap' |
# The timestamp must change location to be visible most of the time |
2583,9 → 2803,19 |
esac |
shift |
;; |
-R|--randomsource) |
if [ ! -r "$2" ]; then |
error "Random source file '$2' can't be read" |
exit $EX_USAGE |
fi |
init_filerand "$2" |
inf "Using '$2' as source of semi-random values" |
RANDFUNCTION=filerand |
shift |
;; |
-d|--disable) # Disable default features |
case $(tolower "$2") in |
# timestamp (no final s) is undocumented but will stay |
# timestamp (with no final s) is undocumented but will stay |
t|timestamps|timestamp) |
if [ $DISABLE_TIMESTAMPS -eq 0 ]; then |
inf "Timestamps disabled." |
2628,6 → 2858,18 |
verbosity=$V_NONE |
fi |
;; |
--undocumented) |
# This is a container for, of course, undocumented functions |
# These are used for testing/debugging purposes. Might (and will) |
# change between versions, break easily and do no safety checks. |
# In short, don't look at them unless told to do so :P |
case "$2" in |
# AWK was used for a little while in a WiP version |
#set_awk=*) AWK="$(cut -d'=' -f2<<<"$2")" ; warn "[U] AWK=$AWK" ;; |
*) false ;; |
esac |
shift |
;; |
-D) # Repeat to just test consistency |
if [ $DEBUGGED -gt 0 ]; then exit ; fi |
DEBUG=1 |
2655,17 → 2897,15 |
elif [ "$2" ]; then |
multiple_input_files=1 |
fi |
|
# }}} # Command line parsing |
|
# The coherence check ensures the processed options are |
# not incoherent/incompatible with the input files or with |
# other given options |
coherence_check |
coherence_check || { |
exit $? |
} |
|
# Test requirements |
test_programs || exit $EX_UNAVAILABLE |
|
set +e # Don't fail automatically |
for arg do process "$arg" ; done |
|