47,14 → 47,26 |
# <http://wiki.multimedia.cx/index.php?title=VC-1> |
# |
|
declare -r VERSION="1.1.0" |
declare -r VERSION="1.0.99" # ("1.1.0 RC") |
# {{{ # CHANGELOG |
# History (The full changelog can be found at <http://p.outlyer.net/vcs/files/CHANGELOG>). |
# |
# 1.1.0: (2009-?-?) |
# 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 |
# * 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 |
# }}} # CHANGELOG |
|
set -e |
66,6 → 78,7 |
# * [[x1]] Find out why the order of ffmpeg arguments breaks some files. |
# * [[x2]] Find out if egrep is safe to use or grep -E is more commonplace. |
# * Better DVD support (e.g. real detection of aspect ratio) |
# * Use ffmpeg's detected length if shorter than mplayer's |
# |
|
# }}} # TODO |
116,6 → 129,8 |
|
# This is the horizontal padding added to each capture. Changing it might break |
# extended set's alignement so keep this in mind if you tinker with it |
# When shadows are enabled, 5 is substracted from this value in csheet_montage |
# so keep this in mind! |
declare -ri HPAD=8 |
# }}} # End of constants |
|
147,6 → 162,7 |
declare bg_sign=SlateGray # Background for signature |
declare bg_title=White # Background for the title (see -T) |
declare bg_contact=White # Background of the thumbnails |
declare bg_tstamps='#000000aa' # Background for the timestamps box |
declare fg_heading=black # Font colour for meta info box |
declare fg_sign=black # Font colour for signature |
declare fg_tstamps=white # Font colour for timestamps |
250,6 → 266,7 |
# go there |
# This holds the output of mplayer -identify on the current video |
declare MPLAYER_CACHE= |
declare FFMPEG_CACHE= |
# This holds the parsed values of MPLAYER_CACHE, see also the Indexes in VID |
# (defined in the constants block) |
declare -a VID= |
266,21 → 283,21 |
# This number of seconds is *not* captured from the end of the video |
declare -i end_offset=$DEFAULT_END_OFFSET |
|
# Experimental in 1.0.7b: transformations/filters |
# Operations are decomposed into independent optional steps, this will allow |
# to add some intermediate steps (e.g. polaroid mode) |
# Transformations/filters |
# Operations are decomposed into independent optional steps, this allows |
# to add some intermediate steps (e.g. polaroid/photo mode's frames) |
# Filters in this context are functions. |
# There're two kinds of filters and a delegate: |
# * individual filters are run over each vidcap |
# * global filters are run over all vidcaps at once |
# * global filters are run over all vidcaps at once (currently deprecated) |
# * The contact sheet creator delegates on some function to create the actual |
# contact sheet |
# |
# Individual filters take the form: |
# filt_name( vidcapfile, timestamp in seconds.milliseconds, width, height ) |
# filt_name( vidcapfile, timestamp in seconds.milliseconds, width, height, [context, [index]] ) |
# They're executed in order by filter_vidcap() |
declare -a FILTERS_IND=( 'filt_resize' 'filt_apply_stamp' ) |
# Global filters take the form |
declare -a FILTERS_IND=( 'filt_resize' 'filt_apply_stamp' 'filt_softshadow' ) |
# Deprecated: Global filters take the form |
# filtall_name( vidcapfile1, vidcapfile2, ... ) |
# They're executed in order by filter_all_vidcaps |
declare -a FILTERS_CS |
298,8 → 315,9 |
# When set to 1 the signature won't contain the "Preview created by..." line |
declare -i anonymous_mode=0 |
|
# See csheet_montage for more details |
# See coherence_check for more details |
declare -i DISABLE_SHADOWS=0 |
declare -i DISABLE_TIMESTAMPS=0 |
|
# }}} # Variables |
|
338,6 → 356,7 |
'DEFAULT_END_OFFSET' |
'MIN_LENGTH_FOR_END_OFFSET' |
'DEBUG' |
'DISABLE_.*' |
) |
|
# This is only used to exit when -DD is used |
803,6 → 822,18 |
echo "[TRACE]: $@" >&2 |
} |
|
# |
# Tests if the filter chain contains the provided filter |
# has_filter($1 = filtername) |
has_filter() { |
local filter= ref=$1 |
for filter in ${FILTERS_IND[@]} ; do |
[ "$filter" == "$ref" ] || continue |
return 0 |
done |
return 1 |
} |
|
# }}} # Convenience functions |
|
# {{{ # Core functionality |
1072,7 → 1103,7 |
} |
|
# Applies all individual vidcap filters |
# filter_vidcap($1 = filename, $2 = timestamp, $3 = width, $4 = height) |
# filter_vidcap($1 = filename, $2 = timestamp, $3 = width, $4 = height, $5 = context, $6 = index[1..]) |
filter_vidcap() { |
trace $FUNCNAME $@ |
# For performance purposes each filter simply prints a set of options |
1080,7 → 1111,7 |
# filters. |
local cmdopts= |
for filter in ${FILTERS_IND[@]}; do |
cmdopts="$cmdopts $( $filter "$1" "$2" "$3" "$4" ) " |
cmdopts="$cmdopts $( $filter "$1" "$2" "$3" "$4" "$5" "$6" ) -flatten " |
done |
local t=$(new_temp_file .png) |
eval "convert '$1' $cmdopts '$t'" |
1103,30 → 1134,85 |
} |
|
# Draw a timestamp in the file |
# filt_apply_stamp($1 = filename, $2 = timestamp, $3 = width, $4 = height) |
# filt_apply_stamp($1 = filename, $2 = timestamp, $3 = width, $4 = height, $5 = context, $6 = index) |
filt_apply_stamp() { |
trace $FUNCNAME $@ |
local filename=$1 timestamp=$2 width=$3 height=$4 |
local filename=$1 timestamp=$2 width=$3 height=$4 context=$5 index=$6 |
|
echo -n " \( -box '#000000aa' -fill '$fg_tstamps' -pointsize '$pts_tstamps' " |
local pts=$pts_tstamps |
if [ $height -lt 200 ]; then |
pts=$(( $pts_tstamps / 3 )) |
elif [ $height -lt 400 ]; then |
pts=$(( $pts_tstamps * 2 / 3 )) |
fi |
# If the size is too small they won't be readable at all |
if [ $pts -le 8 ]; then |
pts=8 |
if [ $index -eq 1 ] && [ $context -ne $CTX_EXT ]; then |
warn "Beware, using very small timestamps to accomodate smaller captures,\ |
you might prefer using -dt to disable them" |
fi |
fi |
# The last -gravity None is used to "forget" the previous gravity (otherwise it would |
# affect stuff like the polaroid frames) |
echo -n " \( -box '$bg_tstamps' -fill '$fg_tstamps' -pointsize '$pts' " |
echo -n " -gravity '$grav_timestamp' -stroke none -strokewidth 3 -annotate +5+5 " |
echo " ' $(pretty_stamp $stamp) ' \) -flatten " |
echo " ' $(pretty_stamp $stamp) ' \) -flatten -gravity None " |
} |
|
# Apply a Polaroid-like effect |
# 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_photoframe() { |
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 |
echo -n "-bordercolor white -border 6 -bordercolor grey60 -border 1 " |
# 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 |
# Tweaking the size gives a nice effect too |
# w=$(( $w - ( $RANDOM % ( $w / 3 ) ) )) |
# 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 " |
} |
|
filt_softshadow() { |
# Before this was a filter, there was the global (montage) softshadow (50x2+10+10) and the |
# photoframe inline softshadow 60x4+4+4 |
echo -n "\( -background black +clone -shadow 50x2+4+4 -background none \) +swap -flatten -trim +repage " |
} |
|
|
# Apply a polaroid-like border effect |
# Based on filt_photoframe(), with a bigger lower border |
# filt_polaroid($1 = filename, $2 = timestamp, $3 = width, $4 = height) |
filt_polaroid() { |
trace $FUNCNAME $@ |
# local file="$1" ts=$2 w=$3 h=$4 |
local border=$(( ($3*$4) / 3600 )) # Read filt_photoframe for details |
[ $border -lt 7 ] || border=6 |
echo -n "-bordercolor white -mattecolor white -frame ${border}x${border} " |
# FIXME: This is rather ugly (double-flipping) there's sure a better way |
echo -n "\( -flip -splice 0x$(( $border*5 )) \) " |
echo "-flip -bordercolor grey60 -border 1 +repage" |
} |
|
# Applies a random rotation |
# Taken from <http://www.imagemagick.org/Usage/thumbnails/#polaroid> |
# filt_randrot($1 = filename, $2 = timestamp, $3 = width, $4 = height) |
1195,18 → 1281,23 |
shift 4 |
# Padding is no longer dependant upong context since alignment of the |
# captures was far trickier then |
local hpad=$HPAD vpad=4 |
local hpad= vpad= splice= |
|
# Using transparent seems to make -shadow futile |
# The shadows already add a good amount of padding |
if has_filter filt_softshadow ; then |
hpad=$(( $HPAD-5 )) |
vpad=0 |
splice=5x10 |
else |
hpad=$HPAD |
vpad=4 |
splice=0x8 |
fi |
|
montage -background Transparent "$@" -geometry +$hpad+$vpad -tile "$cols"x "$output" |
# With the shadows moved to a filter, there's not enough spacing to header |
convert "$output" -background Transparent -splice $splice "$output" |
|
# This should actually be moved to a filter but with the current |
# architecture I'm unable to come up with the correct convert options |
if [ $DISABLE_SHADOWS -eq 0 ]; then |
# This produces soft-shadows, which look much better than the montage ones |
convert \( -shadow 50x2+10+10 "$output" \) "$output" -composite "$output" |
fi |
|
# FIXME: Error handling |
echo $output |
} |
1269,9 → 1360,7 |
accoffset=0 |
cmdopts= # This command is pretty time-consuming, let's make it in a row |
|
# Base canvas |
inf "Creating polaroid base canvas $row/$numrows..." |
convert -size ${canvasw}x${canvash} xc:transparent "$rowfile" |
# 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 |
1280,23 → 1369,19 |
w=$(imw "$1") |
|
# Stick the vicap in the canvas |
#convert -geometry +${accoffset}+0 "$rowfile" "$1" -composite "$rowfile" |
cmdopts="$cmdopts -geometry +${accoffset}+0 '$1' -composite " |
cmdopts="$cmdopts '$1' -geometry +${accoffset}+0 -composite " |
|
offset=$(( $minoffset + ( $RANDOM % $maxoffset ) )) |
let 'accoffset=accoffset + w - offset' |
shift |
done |
inf "Composing polaroid row $row/$numrows..." |
eval convert "'$rowfile'" "$cmdopts" -trim +repage "'$rowfile'" >&2 |
inf "Composing overlapped row $row/$numrows..." |
eval convert -size ${canvasw}x${canvash} xc:transparent -geometry +0+0 "$cmdopts" -trim +repage "'$rowfile'" >&2 |
done |
|
inf "Merging polaroid rows..." |
inf "Merging overlapped rows..." |
output=$(new_temp_file .png) |
# Standard composition |
#convert -background Transparent "${rowfiles[@]}" -append polaroid.png |
# Overlapped composition |
convert -size ${canvasw}x$(( $canvash * $cols )) xc:transparent "$output" |
|
cmdopts= |
accoffset=0 |
local h |
1307,13 → 1392,16 |
maxoffset=$(( $h / 4 )) |
offset=$(( $minoffset + ( $RANDOM % $maxoffset ) )) |
# The row is also offset horizontally |
cmdopts="$cmdopts -geometry +$(( $RANDOM % $maxoffset ))+$accoffset '$row' -composite " |
cmdopts="$cmdopts '$row' -geometry +$(( $RANDOM % $maxoffset ))+$accoffset -composite " |
let 'accoffset=accoffset + h - offset' |
done |
# After the trim the top corners are too near the heading, we add some space |
# with -splce |
eval convert -background transparent "$output" $cmdopts -trim +repage \ |
-bordercolor Transparent -splice 0x10 "$output" >&2 |
# After the trim the image will be touching the outer borders and the heading and footer, |
# older versions (prior to 1.0.99) used -splice 0x10 to correct the heading spacing, 1.0.99 |
# onwards uses -frame to add spacing in all borders + splice to add a bit more space on the |
# upper border. Note splice uses the background colour while frame uses the matte colour |
eval convert -size ${canvasw}x$(( $canvash * $cols )) xc:transparent -geometry +0+0 \ |
$cmdopts -trim +repage -bordercolor Transparent -background Transparent -mattecolor Transparent \ |
-frame 5x5 -splice 0x5 "$output" >&2 |
|
# FIXME: Error handling |
echo $output |
1338,6 → 1426,8 |
if [ $DVD_MODE -eq 0 ]; then |
MPLAYER_CACHE=$(mplayer -benchmark -ao null -vo null -identify -frames 0 \ |
-quiet "$f" 2>/dev/null | grep ^ID) |
# Used as fallback. Introduced in 1.0.99 so expect it to fail :P |
FFMPEG_CACHE=$(ffmpeg -i "$f" -dframes 0 -vframes 0 /dev/null 2>&1 | grep Stream) |
else |
MPLAYER_CACHE=$(mplayer -benchmark -ao null -vo null -identify -frames 0 \ |
-quiet -dvd-device $DVD_FILE dvd://$DVD_TITLE \ |
1370,18 → 1460,108 |
VID[$FPS]="${VID[$FPS]:0:$(( ${#VID[$FPS]} - 1 ))}" |
fi |
|
# Fallback for values known to fail often |
if [ "$FFMPEG_CACHE" ]; then |
# FPS=1000.00 happens often for WMV |
if [ "${VID[$FPS]}" == "1000.00" ]; then |
local fps2=$(grep Stream <<<"$FFMPEG_CACHE" | grep Video | head -1 | \ |
egrep -o ', [0-9]+\.[0-9]+ ' | egrep -o '[0-9]+.*[0-9]') |
if is_float "$fps2" ; then |
VID[$FPS]=$fps2 |
fi |
unset fps2 |
fi |
# Number of channels 0 happens for WMA in non-x86 |
# Mplayer seems to default to 2 for >2, so ffmpeg might be a better default option |
# if [ "${VID[$CHANS]}" ] && ( ! is_number "${VID[$CHANS]}" || [ ${VID[$CHANS]} -eq 0 ] ) ; then |
local ch2=$(grep Stream <<<"$FFMPEG_CACHE" | grep Audio | head -1 | cut -d, -f3 | sed 's/^ //') |
if [ "$ch2" ]; then |
case $ch2 in |
mono) VID[$CHANS]=1 ;; |
stereo) VID[$CHANS]=2 ;; |
5.1) VID[$CHANS]=6 ;; |
*) ;; |
esac |
fi |
# fi |
fi |
|
|
# Check sanity of the most important values |
is_number "${VID[$W]}" && is_number "${VID[$H]}" && is_float "${VID[$LEN]}" |
} |
|
# Checks if the provided arguments make sense and are allowed to be used |
# together |
coherence_check() { |
# If -m is used then -S must be used |
if [ $manual_mode -eq 1 ] && [ -z $initial_stamps ]; then |
error "You must provide timestamps (-S) when using manual mode (-m)" |
return $EX_USAGE |
fi |
|
# Currently it's not allowed to use dvd mode with more than one input |
# "file" (in this mode, input files are actually dvd titles of the file |
# provided in -V) |
if [ $DVD_MODE -eq 1 ] && [ $multiple_input_files -eq 1 ]; then |
if [ $DVD_MODE -eq 1 ] ; then |
if [ $multiple_input_files -eq 1 ]; then |
error "Only an input file is allowed in DVD mode" |
return $EX_UNAVAILABLE |
fi |
|
# DVD Mode only works with mplayer, the decoder is changed when |
# the DVD mode option is found, so if it's ffmpeg at this point, |
# it's by user request (i.e. -F after -V) |
if [ $decoder -ne $DEC_MPLAYER ]; then |
warn "DVD mode requires the use of mplayer, falling back to it" |
decoder=$DEC_MPLAYER |
fi |
fi |
|
local filter= |
if [ $DISABLE_TIMESTAMPS -eq 0 ] && |
local filts=( ) |
has_filter filt_polaroid && has_filter filt_apply_stamp ; then |
|
for filter in ${FILTERS_IND[@]} ; do |
if [ "$filter" == "filt_polaroid" ]; then |
filts+=( $filter ) |
filts+=( filt_apply_stamp ) |
elif [ "$filter" == "filt_apply_stamp" ]; then |
continue; |
else |
filts+=( $filter ) |
fi |
done |
FILTERS_IND=( ${filts[*]} ) |
unset filts |
fi |
# The shoftshadow and randrot filters must be in the correct place |
# or they will affect the image incorrectly. |
# Additionally the default filters can be disabled from the command |
# line (with --disable), they're removed from the filter chain here |
local filts=( ) end_filts=( ) |
for filter in ${FILTERS_IND[@]} ; do |
case "$filter" in |
filt_softshadow) |
# Note the newer soft shadows code (1.0.99 onwards) behaves slightly |
# differently. On previous versions disabling shadows only affected |
# the montage shadow (but e.g. the polaroid mode preserved them), |
# this is no longer true |
if [ $DISABLE_SHADOWS -ne 1 ]; then |
end_filts[100]="filt_softshadow" |
fi |
;; |
filt_apply_stamp) |
if [ $DISABLE_TIMESTAMPS -ne 1 ]; then |
filts+=( "$filter" ) |
fi |
;; |
filt_randrot) end_filts[200]="filt_randrot" ;; |
*) filts+=( "$filter" ) ;; |
esac |
done |
FILTERS_IND=( ${filts[*]} ${end_filts[*]} ) |
} |
|
# Main function. |
1411,7 → 1591,7 |
fi |
DVD_TITLE=$1 |
if [ $DVD_TITLE -eq 0 ]; then |
local dt="$(lsdvd /dev/dvd | grep 'Longest track:' | \ |
local dt="$(lsdvd "$DVD_FILE" | grep 'Longest track:' | \ |
cut -d' ' -f3- | sed 's/^0*//')" |
if ! is_number "$dt" ; then |
error "Failed to autodetect longest DVD title" |
1421,13 → 1601,6 |
unset dt |
inf "Using DVD Title #$DVD_TITLE" |
fi |
# DVD Mode only works with mplayer, the decoder is changed when |
# the DVD mode option is found, so if it's ffmpeg, it's by user |
# request |
if [ $decoder -ne $DEC_MPLAYER ]; then |
warn "DVD mode requires the use of mplayer" |
decoder=$DEC_MPLAYER |
fi |
else |
if [ ! -f "$f" ]; then |
error "File \"$f\" doesn't exist" |
1482,7 → 1655,7 |
|
# If the temporal vidcap already exists, abort |
if [ -f $VIDCAPFILE ]; then |
error "File 0000000$f.png exists and would be overwritten, move it out before running." |
error "File $VIDCAPFILE exists and would be overwritten, move it out before running." |
return $EX_CANTCREAT |
fi |
# mplayer will re-write also 00000001.png-00000004.png |
1508,7 → 1681,7 |
inf "Generating highlight #${n}/${#HLTIMECODES[*]} ($pretty)..." |
|
capture "$f" $stamp || return $? |
filter_vidcap "$VIDCAPFILE" $pretty $vidcap_width $vidcap_height || { |
filter_vidcap "$VIDCAPFILE" $pretty $vidcap_width $vidcap_height $CTX_HL $n || { |
local r=$? |
error "Failed to apply transformations to the capture." |
return $r |
1542,7 → 1715,7 |
inf "Generating capture #${n}/${#TIMECODES[*]} ($pretty)..." |
|
capture "$f" $stamp || return $? |
filter_vidcap "$VIDCAPFILE" $pretty $vidcap_width $vidcap_height || return $? |
filter_vidcap "$VIDCAPFILE" $pretty $vidcap_width $vidcap_height $CTX_STD $n || return $? |
|
# identified by capture number, padded to 6 characters |
capfile=$(new_temp_file "-cap-$(pad 6 $n).png") |
1584,7 → 1757,7 |
pretty=$(pretty_stamp $stamp) |
inf "Generating capture from extended set: ${n}/${#TIMECODES[*]} ($pretty)..." |
capture "$f" $stamp || return $? |
filter_vidcap "$VIDCAPFILE" $pretty $w $h || return $? |
filter_vidcap "$VIDCAPFILE" $pretty $w $h $CTX_EXT $n || return $? |
|
capfile=$(new_temp_file "-excap-$(pad 6 $n).png") |
mv "$VIDCAPFILE" "$capfile" |
1702,9 → 1875,29 |
fi |
|
|
local csw=$(imw "$output") exw= hlw= |
local width=$csw |
if [ "$HLTIMECODES" ] || [ "$extended_factor" != "0" ]; then |
inf "Merging contact sheets..." |
if [ "$HLTIMECODES" ]; then |
local hlw=$(imw "$hlfile") |
if [ $hlw -gt $width ]; then width=$hlw ; fi |
fi |
if [ "$extended_factor" != "0" ]; then |
local exw=$(imw $extoutput) |
if [ $exw -gt $width ]; then width=$exw ; fi |
fi |
fi |
if [ $csw -lt $width ]; then |
local csh=$(imh "$output") |
# Expand the standard set to the maximum width of the sets by padding both sides |
# For some reason the more obvious (to me) convert command-lines lose |
# the transparency |
convert \( -size $(( ($width - $csw) / 2 ))x$csh xc:transparent \) "$output" \ |
\( -size $(( ($width - $csw) / 2 ))x$csh xc:transparent \) +append "$output" |
unset csh |
fi |
|
# If there were highlights then mix them in |
if [ "$HLTIMECODES" ]; then |
# For some reason adding the background also adds padding with: |
1711,15 → 1904,28 |
# convert \( -background LightGoldenRod "$hlfile" -flatten \) \ |
# \( "$output" \) -append "$output" |
# replacing it with a "-composite" operation apparently works |
local geometry=$(identify -format '%wx%h' "$hlfile") |
convert \( -size "$geometry" xc:LightGoldenRod "$hlfile" -composite \) \ |
\( -size "$(cut -d'x' -f1<<<$geometry)"x1 xc:black \) \ |
# Expand the highlights to the correct size by padding |
local hlh=$(imh "$hlfile") |
if [ $hlw -lt $width ]; then |
convert \( -size $(( ($width - $hlw) / 2 ))x$hlh xc:transparent \) "$hlfile" \ |
\( -size $(( ($width - $hlw) / 2 ))x$hlh xc:transparent \) +append "$hlfile" |
fi |
convert \( -size ${width}x${hlh} xc:LightGoldenRod "$hlfile" -composite \) \ |
\( -size ${width}x1 xc:black \) \ |
"$output" -append "$output" |
unset hlh |
fi |
# Extended captures |
if [ "$extended_factor" != 0 ]; then |
convert "$output" "$extoutput" -append "$output" |
# Already set local exw=$(imw "$extoutput") |
local exh=$(imh "$extoutput") |
if [ $exw -lt $width ]; then |
# Expand the extended set to be the correct size |
convert \( -size $(( ($width - $exw) / 2 ))x$exh xc:transparent \) "$extoutput" \ |
\( -size $(( ($width - $exw) / 2 ))x$exh xc:transparent \) +append "$extoutput" |
fi |
convert "$output" -background Transparent "$extoutput" -append "$output" |
fi |
# Add the background |
convert -background "$bg_contact" "$output" -flatten "$output" |
|
1799,7 → 2005,7 |
filesize_label="Disc size" |
filesize_value="$(get_blockdev_size "$DVD_FILE")" |
else |
filename_value="$filename_value (DVD Label: $dvd_label)" |
filename_value="$(basename "$DVD_FILE") $filename_value (DVD Label: $dvd_label)" |
filesize_value="$(get_pretty_file_size "$f")" |
fi |
else |
2059,9 → 2265,14 |
Randomly rotate each image. |
"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. |
"photos": Use '-kc' or '--funky photos' |
Combination of rotate, photoframe and overlap. |
Same as -kp -kr -ko. |
"polaroid": Use '-kp' or '--funky polaroid' |
Combination of rotate, photoframe and overlap. |
Same as -kr -ko -kf. |
Combination of rotate, polaroidframe and overlap. |
Same as -kL -kr -ko. |
"film": Use '-ki' or '--funky film' |
Imitates filmstrip look. |
"random": Use '-kx' or '--funky random' |
2221,7 → 2432,8 |
;; |
-j|--jpeg) |
if [ "$2" ]; then # Arg is optional, 2 is for JPEG 2000 |
if [ "$2" != "2" ]; then |
# 2000 is also accepted |
if [ "$2" != "2" ] && [ "$2" != "2000" ]; then |
error "Use -j for jpeg output or -j2 for JPEG 2000 output. Got '-j$2'." |
exit $EX_USAGE |
fi |
2319,12 → 2531,23 |
shift |
;; |
-k|--funky) # Funky modes |
case $(tolower "$2") in |
p|polaroid) # Same as overlap + rotate + photoframe |
case "$2" in # Note older versions (<1.0.99) were case-insensitive |
p|polaroid) # Same as overlap + rotate + polaroid |
inf "Changed to polaroid funky mode." |
FILTERS_IND+=( 'filt_polaroid' 'filt_randrot' ) |
CSHEET_DELEGATE='csheet_overlap' |
# XXX: The newer version has a lot less flexibility with these many |
# hardcoded values... |
grav_timestamp=South |
fg_tstamps=Black |
bg_tstamps=Transparent |
pts_tstamps=$(( $pts_tstamps * 3 / 2 )) |
;; |
c|photos) # Same as overlap + rotate + photoframe, this is the older polaroid |
inf "Changed to polaroid funky mode." |
FILTERS_IND+=( 'filt_photoframe' 'filt_randrot' ) |
CSHEET_DELEGATE='csheet_overlap' |
# The timestamp must change location to be visible |
# The timestamp must change location to be visible most of the time |
grav_timestamp=NorthWest |
;; |
o|overlap) # Random overlap mode |
2337,6 → 2560,13 |
f|photoframe) # White photo frame |
FILTERS_IND+=( 'filt_photoframe' ) |
;; |
L|polaroidframe) # White polaroid frame |
FILTERS_IND+=( 'filt_polaroid ') |
grav_timestamp=South |
fg_tstamps=Black |
bg_tstamps=Transparent |
pts_tstamps=$(( $pts_tstamps * 3 / 2 )) |
;; |
i|film) |
inf "Enabled film mode." |
FILTERS_IND+=( 'filt_film' ) |
2356,16 → 2586,16 |
case $(tolower "$2") in |
# timestamp (no final s) is undocumented but will stay |
t|timestamps|timestamp) |
if [ $DISABLE_TIMESTAMPS -eq 0 ]; then |
inf "Timestamps disabled." |
# TODO: Can array splicing be done in a saner way? |
declare -a tmp=${FILTERS_IND[@]} |
unset FILTERS_IND |
FILTERS_IND=${tmp[@]/filt_apply_stamp/} |
unset tmp |
# They'll be removed from the filter chain in coherence_check |
DISABLE_TIMESTAMPS=1 |
fi |
;; |
s|shadows|shadow) |
if [ $DISABLE_SHADOWS -eq 0 ]; then |
inf "Shadows disabled." |
# They will be removed from the filter chain in coherence_check |
DISABLE_SHADOWS=1 |
fi |
;; |
2427,18 → 2657,14 |
|
# }}} # 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 |
|
# Test requirements |
test_programs || exit $EX_UNAVAILABLE |
|
# If -m is used then -S must be used |
if [ $manual_mode -eq 1 ] && [ -z $initial_stamps ]; then |
error "You must provide timestamps (-S) when using manual mode (-m)" |
exit $EX_USAGE |
fi |
|
# The coherence check ensures the processed options are |
# not incoherent/incompatible with the input files or each other |
coherence_check |
set +e # Don't fail automatically |
for arg do process "$arg" ; done |
|