Expose options for window type, bits, ext type
Exposes various options for filter precision,
window type, extension type and intermediate
extra precision bits between horz and vert filtering
steps, as options in the various utilities.
Note extension type was previously part of resampling config,
but it has been taken out in this patch and made part of
global options for simplicity.
Change-Id: I0e5d85daccdc18810351e7f33a226c7ea78cc856
diff --git a/tools/lanczos/lanczos_README.txt b/tools/lanczos/lanczos_README.txt
index 6bf5b22..b37dfdb 100644
--- a/tools/lanczos/lanczos_README.txt
+++ b/tools/lanczos/lanczos_README.txt
@@ -38,19 +38,46 @@
--------------------
The usage of lanczos_resample_y4m is:
lanczos_resample_y4m
+ [<Options>]
<y4m_input>
<num_frames>
<horz_resampling_config>
<vert_resampling_config>
<y4m_output>
[<outwidth>x<outheight>]
+
Notes:
+ <Options> are optional switches prefixed by '-' as follows:
+ -bit:<n> - providing bits for filter taps
+ [default: 14]
+ -ieb:<n> - providing intermediate extra bits of
+ prec between horz and vert filtering
+ [default: 2]
+ -ext:<ext_type> - providing the extension type
+ <ext_type> is one of:
+ 'r' or 'rep' (Repeat)
+ 's' or 'sym' (Symmetric)
+ 'f' or 'ref' (Reflect/Mirror-whole)
+ 'g' or 'gra' (Grafient preserving)
+ [default: 'r']
+ -win:<win_type> - providing the windowing function type
+ <win_type> is one of:
+ 'lanczos' (Repeat)
+ 'lanczos_dil' (Symmetric)
+ 'gaussian' (Gaussian)
+ 'gengaussian' (Generalized Gaussian)
+ 'cosine' (Cosine)
+ 'hamming (Hamming)
+ 'blackman (Blackman)
+ 'kaiser (Kaiser)
+ [default: 'lanczos']
+
<y4m_input> is the input video in Y4M format
<y4m_output> is the output video in Y4M format
<num_frames> is number of frames to be processed
<horz_resampling_config> and <vert_resampling_config>
are of the form:
- <p>:<q>:<Lanczos_a>[:<x0>:<ext>] where:
+ <p>:<q>:<Lanczos_a>[:<x0>] where:
<p>/<q> gives the resampling ratio.
<Lanczos_a> is Lanczos parameter.
<x0> is the optional initial offset
@@ -63,17 +90,11 @@
which is a shortcut for x0 = (q-p)/(4p)
The field can be prefixed by 'i' meaning
using the inverse of the number provided,
- <ext> is the optional extension type:
- 'r' or 'rep' (Repeat)
- 's' or 'sym' (Symmetric)
- 'f' or 'ref' (Reflect/Mirror-whole)
- 'g' or 'gra' (Grafient preserving)
- [default: 'r']
If it is desired to provide different config parameters
for luma and chroma, the <Lanczos_a> and <x0> fields
could be optionally converted to a pair of
comma-separated parameters as follows:
- <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>:<ext>]
+ <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>]
where <Lanczos_al> and <lanczos_ac> are
luma and chroma lanczos parameters
<x0l> and <x0c> are
@@ -81,7 +102,7 @@
<outwidth>x<outheight> is output video dimensions
only needed in case of upsampling
Resampling config of 1:1:1:0 horizontally or vertically
- is regarded as a no-op in that direction.
+ is regarded as a no-op in that direction
Example usages:
@@ -120,21 +141,22 @@
lanczos_resample_y4m /tmp/down.y4m 10 3:2:6:i0.125 4:3:6 /tmp/downup.y4m \
1920x1080
-4a. Similar to 3a, except using symmetric border extension for vertical
- resampling instead of default repeat.
+4a. Similar to 3a, except using symmetric border extension instead of default
+ repeat.
- lanczos_resample_y4m Boat_1920x1080_60fps_10bit_420.y4m 10 \
- 2:3:6:0.125 3:4:6:c:s /tmp/down.y4m
+ lanczos_resample_y4m -ext:sym Boat_1920x1080_60fps_10bit_420.y4m 10 \
+ 2:3:6:0.125 3:4:6:c /tmp/down.y4m
4b. Reversing the process in 4a.
- lanczos_resample_y4m /tmp/down.y4m 10 3:2:6:i0.125 4:3:6:c:s \
+ lanczos_resample_y4m -ext:sym /tmp/down.y4m 10 3:2:6:i0.125 4:3:6:c \
/tmp/downup.y4m 1920x1080
5a. Downsample 10 frames from Boat_1920x1080_60fps_10bit_420.y4m by
ratio 3/2 horizontally and vertically with Lanczos parameter
6 for both, centered sampling for luma, co-sited chroma horizontally
- and centered chroma vertically.
+ and centered chroma vertically. Note this is the most common use
+ case encountered in practice.
lanczos_resample_y4m Boat_1920x1080_60fps_10bit_420.y4m 10 \
2:3:6:c,d 2:3:6 /tmp/down.y4m
@@ -144,12 +166,24 @@
lanczos_resample_y4m /tmp/down.y4m 10 3:2:6:ic,id 3:2:6 \
/tmp/downup.y4m 1920x1080
+6a. Similar to 5a except using symmetric border extension, 12-bit
+ filters, 3 bit intermediate extra precision, and hamming windowing.
+ lanczos_resample_y4m -ext:sym -bit:12 -ieb:3 -win:hamming \
+ Boat_1920x1080_60fps_10bit_420.y4m 10 \
+ 2:3:6:c,d 2:3:6 /tmp/down.y4m
+
+6b. Reversing the process in 6a.
+
+ lanczos_resample_y4m -ext:sym -bit:12 -ieb:3 -win:hamming \
+ /tmp/down.y4m 10 3:2:6:ic,id 3:2:6 \
+ /tmp/downup.y4m 1920x1080
lanczos_resample_yuv
--------------------
The usage of lanczos_resample_yuv is similar but with two extra
arguments to specify the input format:
lanczos_resample_yuv
+ [<Options>]
<yuv_input>
<width>x<height>
<pix_format>
@@ -174,24 +208,23 @@
Utility to show the filter parameters used for both luma and chroma.
The usage of lanczos_resample_filter is:
lanczos_resample_filter
+ [<Options>]
<resampling_config>
- [<filter_bits>]
Notes:
<resampling_config> is in the same format as one specified
in lanczos_resample_y4m above for <horz_resampling_config>
or <vert_resampling_config>.
- <filter_bits> is the bits for the filter [default 12].
Example usages:
- lanczos_resample_filter 2:3:6 14
+7a. lanczos_resample_filter -bit:14 2:3:6
(shows 14-bit a = 6 filter for 2/3 resampling, x0 = centered)
- lanczos_resample_filter 1:2:5:0.125 12
+7b. lanczos_resample_filter -bit:12 1:2:5:0.125
(shows 12-bit a = 5 filter for 1/2 resampling, x0 = 0.125)
- lanczos_resample_filter 1:2:5:c,d 12
+7c. lanczos_resample_filter -bit:12 1:2:5:c,d 12
(shows 12-bit a = 5 filter for 1/2 resampling,
x0 = centered for luma, co-sited for chroma)
- lanczos_resample_filter 3:2:6:i0.125 12
+7d. lanczos_resample_filter -bit:12 3:2:6:i0.125 12
(shows 12-bit a = 5 filter for 3/2 resampling, x0 = inverse of 0.125)
@@ -211,17 +244,21 @@
The usage for the script is:
Usage:
- lanczos_downup.sh <input_y4m> <num_frames>
+ lanczos_downup.sh [<Options>]
+ <input_y4m>
+ <num_frames>
<horz_resampling_config>
<vert_resampling_config>
<downup_y4m>
[<down_y4m>]
Notes:
+ <Options> are optional switches similar to what is used by
+ lanczos_resample_y4m utility
<y4m_input> is input y4m video
<num_frames> is number of frames to process
<horz_resampling_config> and <vert_resampling_config> are in format:
- <p>:<q>:<Lanczos_a_str>[:<x0>:<ext>]
+ <p>:<q>:<Lanczos_a_str>[:<x0>]
similar to what is used by lanczos_resample_y4m utility, with the
enhancement that for <Lanczos_a_str> optionally
two '^'-separated strings for 'a' could be provided instead
@@ -239,26 +276,27 @@
file is deleted.
Example usages:
-Similar to use case 1a and 1b above.
+8. Similar to combined use cases 1a and 1b above including both
+down and inverse up steps.
-6a. From build directory run:
+8a. From build directory run:
/path/to/script/lanczos_downup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6 3:4:6 /tmp/downup.y4m
[Here the intermediate resampled files is not stored]
-6b. From build directory run:
+8b. From build directory run:
/path/to/script/lanczos_downup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6 3:4:6 /tmp/downup.y4m \
/tmp/down.y4m
- [Here the intermediate resampled files is stored in /tmp/down.y4m]
+ [Here the intermediate resampled file is stored in /tmp/down.y4m]
-6c. From build directory run:
+8c. From build directory run:
/path/to/script/lanczos_downup.sh Boat_1920x1080_60fps_10bit_420.y4m \
- 10 2:3:4^8 3:4:4^8 /tmp/downup.y4m
- [Here Lanczos parameters 4 and 8 are used for down and upscaling
+ 10 2:3:8^4 3:4:8^4 /tmp/downup.y4m
+ [Here Lanczos parameters 8 and 4 are used for down and upscaling
respectively]
-6d. From build directory run:
+8d. From build directory run:
/path/to/script/lanczos_downup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6,4^6,4:c,d 3:4:6,4^6,4 /tmp/downup.y4m
[Here Lanczos parameters 6 and 4 are used for luma and chroma
@@ -275,7 +313,9 @@
The usage for the script is:
Usage:
- lanczos_downcompup.sh <input_y4m> <num_frames>
+ lanczos_downcompup.sh [<Options>]
+ <input_y4m>
+ <num_frames>
<horz_resampling_config>
<vert_resampling_config>
<cq_level>[:<cpu_used>]
@@ -283,10 +323,12 @@
[[<down_y4m>]:[<downcomp_bit>]:[<downcomp_y4m]]
Notes:
+ <Options> are optional switches similar to what is used by
+ lanczos_resample_y4m utility
<y4m_input> is input y4m video
<num_frames> is number of frames to process
<horz_resampling_config> and <vert_resampling_config> are in format:
- <p>:<q>:<Lanczos_a_str>[:<x0>:<ext>]
+ <p>:<q>:<Lanczos_a_str>[:<x0>]
similar to what is used by lanczos_resample_y4m utility, with the
enhancement that for <Lanczos_a_str> optionally
two '^'-separated strings for 'a' could be provided instead
@@ -313,15 +355,15 @@
intermediate file is deleted.
Example usages:
-7. Similar to use cases 6 above with a compression step in between.
+9. Similar to use cases 8 above with a compression step in between.
-7a. From build directory run:
+9a. From build directory run:
/path/to/script/lanczos_downcompup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6 3:4:6 40:5 /tmp/downup.y4m
[Here no intermediate files are stored.
Compression is at cq_level 40 and cpu_used=5]
-7b. From build directory run:
+9b. From build directory run:
/path/to/script/lanczos_downcompup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6 3:4:6 40:5 /tmp/downup.y4m \
/tmp/down.y4m::/tmp/downrec.y4m
@@ -329,7 +371,7 @@
stoted in /tmp/down.y4m and /tmp/downrec.y4m respectively.
Compression is at cq_level 40 and cpu_used=5].
-7c. From build directory run:
+9c. From build directory run:
/path/to/script/lanczos_downcompup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6 3:4:6 40:5 /tmp/downup.y4m \
/tmp/down.y4m:/tmp/down.bit:/tmp/downrec.y4m
@@ -338,18 +380,30 @@
/tmp/downcomp.bit and /tmp/downrec.y4m respectively.
Compression is at cq_level 40 and cpu_used=5].
-7d. From build directory run:
+9d. From build directory run:
/path/to/script/lanczos_downcompup.sh Boat_1920x1080_60fps_10bit_420.y4m \
- 10 2:3:4^8 3:4:4,8 40:5 /tmp/downup.y4m
- [Here Lanczos parameters 4 and 8 are used for down and upscaling
+ 10 2:3:8^4 3:4:8^4 40:5 /tmp/downup.y4m
+ [Here Lanczos parameters 8 and 4 are used for down and upscaling
respectively.
Compression is at cq_level 40 and cpu_used=5].
-7e. From build directory run:
+9e. From build directory run:
/path/to/script/lanczos_downcompup.sh Boat_1920x1080_60fps_10bit_420.y4m \
10 2:3:6,4^6,4:c,d 3:4:6,4^6,4 40:5 /tmp/downup.y4m
[Here Lanczos parameters 6 and 4 are used for luma and chroma
respectively for both down and upscaling. Further centered
- luma and co-sited chroma are used horizontally, while centered
- luma and chroma sampling are used vertically.
+ luma sampling and co-sited chroma sampling are respectively used
+ in the horizontal direction, while centered sampling is used for
+ both luma and chroma vertically.
+ Compression is at cq_level 40 and cpu_used=5].
+
+9f. From build directory run:
+ /path/to/script/lanczos_downcompup.sh -win:kaiser \
+ Boat_1920x1080_60fps_10bit_420.y4m \
+ 10 2:3:5:c,d 3:4:5 40:5 /tmp/downup.y4m
+ [Here Lanczos parameter 5 is used for luma and chroma both
+ horizontally and vertically, Further, centered luma
+ sampling and co-sited chroma sampling are used respectively
+ in the horizontal direction, while centered sampling is used
+ for both luma and chroma vertically.
Compression is at cq_level 40 and cpu_used=5].
diff --git a/tools/lanczos/lanczos_downcompup.sh b/tools/lanczos/lanczos_downcompup.sh
index d5fd64b..b51006f 100755
--- a/tools/lanczos/lanczos_downcompup.sh
+++ b/tools/lanczos/lanczos_downcompup.sh
@@ -1,7 +1,9 @@
#!/bin/bash
#
# Usage:
-# lanczos_downcompup.sh <input_y4m> <num_frames>
+# lanczos_downcompup.sh [<Options>]
+# <input_y4m>
+# <num_frames>
# <horz_resampling_config>
# <vert_resampling_config>
# <cq_level>[:<cpu_used>]
@@ -9,10 +11,12 @@
# [[<down_y4m>]:[<downcomp_bit>]:[<downcomp_y4m]]
#
# Notes:
+# <Options> are optional switches similar to what is used by
+# lanczos_resample_y4m utility
# <y4m_input> is input y4m video
# <num_frames> is number of frames to process
# <horz_resampling_config> and <vert_resampling_config> are in format:
-# <p>:<q>:<Lanczos_a_str>[:<x0>:<ext>]
+# <p>:<q>:<Lanczos_a_str>[:<x0>]
# similar to what is used by lanczos_resample_y4m utility, with the
# enhancement that for <Lanczos_a_str> optionally
# two '^'-separated strings for 'a' could be provided instead
@@ -41,11 +45,6 @@
set -e
-if [[ $# -lt "6" ]]; then
- echo "Too few parameters $#"
- exit 1;
-fi
-
tmpdir="/tmp"
AOMENC="${tmpdir}/aomenc_$$"
AOMDEC="${tmpdir}/aomdec_$$"
@@ -58,13 +57,24 @@
extra=""
-input_y4m=$1
-nframes=$2
-hdconfig=$3
-vdconfig=$4
-codecparams=$5
-downcompup_y4m=$6
-intfiles=$7
+opts=0
+options=""
+while [[ "${@:$((opts+1)):1}" == -* ]]; do
+ options="$options ${@:$((opts+1)):1}"
+ ((opts=opts+1))
+done
+if [[ $# -lt "((opts+6))" ]]; then
+ echo "Too few parameters $(($#-opts))"
+ exit 1;
+fi
+
+input_y4m=${@:$((opts+1)):1}
+nframes=${@:$((opts+2)):1}
+hdconfig=${@:$((opts+3)):1}
+vdconfig=${@:$((opts+4)):1}
+codecparams=${@:$((opts+5)):1}
+downcompup_y4m=${@:$((opts+6)):1}
+intfiles=${@:$((opts+7)):1}
#Get codec params cq_level and cpu_used
OIFS="$IFS"; IFS=':' codecparams_arr=($codecparams); IFS="$OIFS"
@@ -136,7 +146,7 @@
fi
#Downsample
-$RESAMPLE $input_y4m $nframes $hdconfig $vdconfig $down_y4m
+$RESAMPLE $options $input_y4m $nframes $hdconfig $vdconfig $down_y4m
#Compress
$AOMENC -o $downcomp_bit $down_y4m \
@@ -150,7 +160,7 @@
$AOMDEC --progress -S --codec=av1 -o $downcomp_y4m $downcomp_bit
#Upsample
-$RESAMPLE $downcomp_y4m $nframes $huconfig $vuconfig $downcompup_y4m \
+$RESAMPLE $options $downcomp_y4m $nframes $huconfig $vuconfig $downcompup_y4m \
${width}x${height}
#Compute metrics
diff --git a/tools/lanczos/lanczos_downup.sh b/tools/lanczos/lanczos_downup.sh
index 52e5340..52344e8 100755
--- a/tools/lanczos/lanczos_downup.sh
+++ b/tools/lanczos/lanczos_downup.sh
@@ -1,17 +1,21 @@
#!/bin/bash
#
# Usage:
-# lanczos_downup.sh <input_y4m> <num_frames>
+# lanczos_downup.sh [<Options>]
+# <input_y4m>
+# <num_frames>
# <horz_resampling_config>
# <vert_resampling_config>
# <downup_y4m>
# [<down_y4m>]
#
# Notes:
+# <Options> are optional switches similar to what is used by
+# lanczos_resample_y4m utility
# <y4m_input> is input y4m video
# <num_frames> is number of frames to process
# <horz_resampling_config> and <vert_resampling_config> are in format:
-# <p>:<q>:<Lanczos_a_str>[:<x0>:<ext>]
+# <p>:<q>:<Lanczos_a_str>[:<x0>]
# similar to what is used by lanczos_resample_y4m utility, with the
# enhancement that for <Lanczos_a_str> optionally
# two '^'-separated strings for 'a' could be provided instead
@@ -41,16 +45,22 @@
trap 'echo "Exiting..."; rm -f ${AOMENC} ${AOMDEC} ${RESAMPLE}' EXIT
-if [[ $# -lt "5" ]]; then
- echo "Too few parameters $#"
+opts=0
+options=""
+while [[ "${@:$((opts+1)):1}" == -* ]]; do
+ options="$options ${@:$((opts+1)):1}"
+ ((opts=opts+1))
+done
+if [[ $# -lt "((opts+5))" ]]; then
+ echo "Too few parameters $(($#-opts))"
exit 1;
fi
-
-input_y4m=$1
-nframes=$2
-hdconfig=$3
-vdconfig=$4
-downup_y4m=$5
+input_y4m=${@:$((opts+1)):1}
+nframes=${@:$((opts+2)):1}
+hdconfig=${@:$((opts+3)):1}
+vdconfig=${@:$((opts+4)):1}
+downup_y4m=${@:$((opts+5)):1}
+down_y4m=${@:$((opts+6)):1}
#Get width and height
hdr=$(head -1 $input_y4m)
@@ -60,10 +70,8 @@
height=${theight:1}
#Get intermediate (down) file
-if [[ -z $6 ]]; then
+if [[ -z $down_y4m ]]; then
down_y4m=/tmp/down_$$.y4m
-else
- down_y4m=$6
fi
#Obtain the horizontal and vertical upsampling configs
@@ -103,11 +111,11 @@
vuconfig="${vuconfig}:${vdconfig_arr[4]}"
fi
-$RESAMPLE $input_y4m $nframes $hdconfig $vdconfig $down_y4m &&
-$RESAMPLE $down_y4m $nframes $huconfig $vuconfig $downup_y4m ${width}x${height}
+$RESAMPLE $options $input_y4m $nframes $hdconfig $vdconfig $down_y4m &&
+$RESAMPLE $options $down_y4m $nframes $huconfig $vuconfig $downup_y4m ${width}x${height}
#tiny_ssim_highbd $input_y4m $downup_y4m
-if [[ -z $6 ]]; then
+if [[ -z ${@:$((opts+6)):1} ]]; then
rm $down_y4m
fi
diff --git a/tools/lanczos/lanczos_resample_filter.c b/tools/lanczos/lanczos_resample_filter.c
index 23e9c3b..e4d246f 100644
--- a/tools/lanczos/lanczos_resample_filter.c
+++ b/tools/lanczos/lanczos_resample_filter.c
@@ -22,20 +22,48 @@
#define CFG_MAX_LEN 256
#define CFG_MAX_WORDS 5
+#define DEF_EXTRA_PREC_BITS 2
#define DEF_COEFF_PREC_BITS 14
+#define DEF_EXT_TYPE (EXT_REPEAT)
#define DEF_WIN_TYPE (WIN_LANCZOS)
// Usage:
-// lanczos_resample_filter <resampling_config> [<filter_bits>]
+// lanczos_resample_filter [<Options>] <resampling_config>
static void usage_and_exit(char *prog) {
printf("Usage:\n");
printf(" %s\n", prog);
+ printf(" [<Options>]\n");
printf(" <resampling_config>\n");
- printf(" [<filter_bits>]\n");
+ printf(" \n");
printf(" Notes:\n");
+ printf(" <Options> are optional switches prefixed by '-' as follows:\n");
+ printf(" -bit:<n> - providing bits for filter taps\n");
+ printf(" [default: 14]\n");
+ printf(" -ieb:<n> - providing intermediate extra bits of\n");
+ printf(" prec between horz and vert filtering\n");
+ printf(" [default: 2]\n");
+ printf(" -ext:<ext_type> - providing the extension type\n");
+ printf(" <ext_type> is one of:\n");
+ printf(" 'r' or 'rep' (Repeat)\n");
+ printf(" 's' or 'sym' (Symmetric)\n");
+ printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
+ printf(" 'g' or 'gra' (Grafient preserving)\n");
+ printf(" [default: 'r']\n");
+ printf(" -win:<win_type> - providing the windowing function type\n");
+ printf(" <win_type> is one of:\n");
+ printf(" 'lanczos' (Repeat)\n");
+ printf(" 'lanczos_dil' (Symmetric)\n");
+ printf(" 'gaussian' (Gaussian)\n");
+ printf(" 'gengaussian' (Generalized Gaussian)\n");
+ printf(" 'cosine' (Cosine)\n");
+ printf(" 'hamming (Hamming)\n");
+ printf(" 'blackman (Blackman)\n");
+ printf(" 'kaiser (Kaiser)\n");
+ printf(" [default: 'lanczos']\n");
+ printf(" \n");
printf(" <resampling_config> is of the form:\n");
- printf(" <p>:<q>:<Lanczos_a>[:<x0>:<ext>] where:\n");
+ printf(" <p>:<q>:<Lanczos_a>[:<x0>] where:\n");
printf(" <p>/<q> gives the resampling ratio.\n");
printf(" <Lanczos_a> is Lanczos parameter.\n");
printf(" <x0> is the optional initial offset\n");
@@ -48,22 +76,15 @@
printf(" which is a shortcut for x0 = (q-p)/(4p)\n");
printf(" The field can be prefixed by 'i' meaning\n");
printf(" using the inverse of the number provided,\n");
- printf(" <ext> is the optional extension type:\n");
- printf(" 'r' or 'rep' (Repeat)\n");
- printf(" 's' or 'sym' (Symmetric)\n");
- printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
- printf(" 'g' or 'gra' (Grafient preserving)\n");
- printf(" [default: 'r']\n");
printf(" If it is desired to provide different config parameters\n");
printf(" for luma and chroma, the <Lanczos_a> and <x0> fields\n");
printf(" could be optionally converted to a pair of\n");
printf(" comma-separated parameters as follows:\n");
- printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>:<ext>]\n");
+ printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>]\n");
printf(" where <Lanczos_al> and <lanczos_ac> are\n");
printf(" luma and chroma lanczos parameters\n");
printf(" <x0l> and <x0c> are\n");
printf(" luma and chroma initial offsets\n");
- printf(" <filter_bits> is prec bits for the filter [default 12].\n");
printf(" Resampling config of 1:1:1:0 is regarded as a no-op\n");
exit(1);
}
@@ -83,8 +104,8 @@
return n;
}
-static int parse_rational_config(char *cfg, int *p, int *q, int *a, double *x0,
- EXT_TYPE *ext_type) {
+static int parse_rational_config(char *cfg, int *p, int *q, int *a,
+ double *x0) {
char cfgbuf[CFG_MAX_LEN];
strncpy(cfgbuf, cfg, CFG_MAX_LEN - 1);
@@ -107,7 +128,6 @@
// Set defaults
x0[0] = x0[1] = (double)('c');
- *ext_type = EXT_REPEAT;
if (ncfgwords > 3) {
char *x0params[2];
@@ -124,27 +144,62 @@
}
if (nx0params == 1) x0[1] = x0[0];
}
- if (ncfgwords > 4) {
- if (!strcmp(cfgwords[4], "S") || !strcmp(cfgwords[4], "s") ||
- !strcmp(cfgwords[4], "sym"))
- *ext_type = EXT_SYMMETRIC;
- else if (!strcmp(cfgwords[4], "F") || !strcmp(cfgwords[4], "f") ||
- !strcmp(cfgwords[4], "ref"))
- *ext_type = EXT_REFLECT;
- else if (!strcmp(cfgwords[4], "R") || !strcmp(cfgwords[4], "r") ||
- !strcmp(cfgwords[4], "rep"))
- *ext_type = EXT_REPEAT;
- else if (!strcmp(cfgwords[4], "G") || !strcmp(cfgwords[4], "g") ||
- !strcmp(cfgwords[4], "gra"))
- *ext_type = EXT_GRADIENT;
- else
- return 0;
- }
return 1;
}
+static int get_options(char *argv[], int *bit, int *ebit, EXT_TYPE *ext_type,
+ WIN_TYPE *win_type) {
+ int n = 1;
+ while (argv[n][0] == '-') {
+ if (!strncmp(argv[n], "-bit:", 5)) {
+ *bit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ieb:", 5)) {
+ *ebit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ext:", 5)) {
+ *ext_type = EXT_REPEAT;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "S") || !strcmp(word, "s") || !strcmp(word, "sym"))
+ *ext_type = EXT_SYMMETRIC;
+ else if (!strcmp(word, "F") || !strcmp(word, "f") || !strcmp(word, "ref"))
+ *ext_type = EXT_REFLECT;
+ else if (!strcmp(word, "R") || !strcmp(word, "r") || !strcmp(word, "rep"))
+ *ext_type = EXT_REPEAT;
+ else if (!strcmp(word, "G") || !strcmp(word, "g") || !strcmp(word, "gra"))
+ *ext_type = EXT_GRADIENT;
+ else
+ fprintf(stderr, "Unknown extension type, using default\n");
+ } else if (!strncmp(argv[n], "-win:", 5)) {
+ *win_type = WIN_LANCZOS;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "lanczos"))
+ *win_type = WIN_LANCZOS;
+ else if (!strcmp(word, "lanczos_dil"))
+ *win_type = WIN_LANCZOS_DIL;
+ else if (!strcmp(word, "gaussian"))
+ *win_type = WIN_GAUSSIAN;
+ else if (!strcmp(word, "gengaussian"))
+ *win_type = WIN_GENGAUSSIAN;
+ else if (!strcmp(word, "cosine"))
+ *win_type = WIN_COSINE;
+ else if (!strcmp(word, "hamming"))
+ *win_type = WIN_HAMMING;
+ else if (!strcmp(word, "blackman"))
+ *win_type = WIN_BLACKMAN;
+ else if (!strcmp(word, "kaiser"))
+ *win_type = WIN_KAISER;
+ else
+ fprintf(stderr, "Unknown window type, using default\n");
+ }
+ n++;
+ }
+ return n - 1;
+}
+
int main(int argc, char *argv[]) {
+ int extra_bits = DEF_EXTRA_PREC_BITS;
int bits = DEF_COEFF_PREC_BITS;
+ EXT_TYPE ext = DEF_EXT_TYPE;
+ WIN_TYPE win = DEF_WIN_TYPE;
RationalResampleFilter rf[2];
if (argc < 2) {
printf("Not enough arguments\n");
@@ -153,17 +208,19 @@
if (!strcmp(argv[1], "-help") || !strcmp(argv[1], "-h") ||
!strcmp(argv[1], "--help") || !strcmp(argv[1], "--h"))
usage_and_exit(argv[0]);
+ const int opts = get_options(argv, &bits, &extra_bits, &ext, &win);
+ if (argc < 2 + opts) {
+ printf("Not enough arguments\n");
+ usage_and_exit(argv[0]);
+ }
int p, q, a[2];
double x0[2];
- EXT_TYPE ext;
- if (!parse_rational_config(argv[1], &p, &q, a, x0, &ext))
+ if (!parse_rational_config(argv[opts + 1], &p, &q, a, x0))
usage_and_exit(argv[0]);
- if (argc > 2) bits = atoi(argv[2]);
for (int k = 0; k < 2; ++k) {
- if (!get_resample_filter(p, q, a[k], x0[k], ext, DEF_WIN_TYPE, 1, bits,
- &rf[k])) {
+ if (!get_resample_filter(p, q, a[k], x0[k], ext, win, 1, bits, &rf[k])) {
fprintf(stderr, "Cannot generate filter, exiting!\n");
exit(1);
}
diff --git a/tools/lanczos/lanczos_resample_y4m.c b/tools/lanczos/lanczos_resample_y4m.c
index d8b1a7a..852d932 100644
--- a/tools/lanczos/lanczos_resample_y4m.c
+++ b/tools/lanczos/lanczos_resample_y4m.c
@@ -24,13 +24,14 @@
#define CFG_MAX_LEN 256
#define CFG_MAX_WORDS 5
-#define COEFF_PREC_BITS 14
-#define INT_EXTRA_PREC_BITS 2
-
+#define DEF_EXTRA_PREC_BITS 2
+#define DEF_COEFF_PREC_BITS 14
+#define DEF_EXT_TYPE (EXT_REPEAT)
#define DEF_WIN_TYPE (WIN_LANCZOS)
// Usage:
// lanczos_resample_y4m
+// [<Options>]
// <y4m_input>
// <num_frames>
// <horz_resampling_config>
@@ -41,19 +42,46 @@
static void usage_and_exit(char *prog) {
printf("Usage:\n");
printf(" %s\n", prog);
+ printf(" [<Options>]\n");
printf(" <y4m_input>\n");
printf(" <num_frames>\n");
printf(" <horz_resampling_config>\n");
printf(" <vert_resampling_config>\n");
printf(" <y4m_output>\n");
printf(" [<outwidth>x<outheight>]\n");
+ printf(" \n");
printf(" Notes:\n");
+ printf(" <Options> are optional switches prefixed by '-' as follows:\n");
+ printf(" -bit:<n> - providing bits for filter taps\n");
+ printf(" [default: 14]\n");
+ printf(" -ieb:<n> - providing intermediate extra bits of\n");
+ printf(" prec between horz and vert filtering\n");
+ printf(" [default: 2]\n");
+ printf(" -ext:<ext_type> - providing the extension type\n");
+ printf(" <ext_type> is one of:\n");
+ printf(" 'r' or 'rep' (Repeat)\n");
+ printf(" 's' or 'sym' (Symmetric)\n");
+ printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
+ printf(" 'g' or 'gra' (Grafient preserving)\n");
+ printf(" [default: 'r']\n");
+ printf(" -win:<win_type> - providing the windowing function type\n");
+ printf(" <win_type> is one of:\n");
+ printf(" 'lanczos' (Repeat)\n");
+ printf(" 'lanczos_dil' (Symmetric)\n");
+ printf(" 'gaussian' (Gaussian)\n");
+ printf(" 'gengaussian' (Generalized Gaussian)\n");
+ printf(" 'cosine' (Cosine)\n");
+ printf(" 'hamming (Hamming)\n");
+ printf(" 'blackman (Blackman)\n");
+ printf(" 'kaiser (Kaiser)\n");
+ printf(" [default: 'lanczos']\n");
+ printf(" \n");
printf(" <y4m_input> is the input video in Y4M format\n");
printf(" <y4m_output> is the output video in Y4M format\n");
printf(" <num_frames> is number of frames to be processed\n");
printf(" <horz_resampling_config> and <vert_resampling_config>\n");
printf(" are of the form:\n");
- printf(" <p>:<q>:<Lanczos_a>[:<x0>:<ext>] where:\n");
+ printf(" <p>:<q>:<Lanczos_a>[:<x0>] where:\n");
printf(" <p>/<q> gives the resampling ratio.\n");
printf(" <Lanczos_a> is Lanczos parameter.\n");
printf(" <x0> is the optional initial offset\n");
@@ -66,17 +94,11 @@
printf(" which is a shortcut for x0 = (q-p)/(4p)\n");
printf(" The field can be prefixed by 'i' meaning\n");
printf(" using the inverse of the number provided,\n");
- printf(" <ext> is the optional extension type:\n");
- printf(" 'r' or 'rep' (Repeat)\n");
- printf(" 's' or 'sym' (Symmetric)\n");
- printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
- printf(" 'g' or 'gra' (Grafient preserving)\n");
- printf(" [default: 'r']\n");
printf(" If it is desired to provide different config parameters\n");
printf(" for luma and chroma, the <Lanczos_a> and <x0> fields\n");
printf(" could be optionally converted to a pair of\n");
printf(" comma-separated parameters as follows:\n");
- printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>:<ext>]\n");
+ printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>]\n");
printf(" where <Lanczos_al> and <lanczos_ac> are\n");
printf(" luma and chroma lanczos parameters\n");
printf(" <x0l> and <x0c> are\n");
@@ -122,8 +144,8 @@
}
}
-static int parse_rational_config(char *cfg, int *p, int *q, int *a, double *x0,
- EXT_TYPE *ext_type) {
+static int parse_rational_config(char *cfg, int *p, int *q, int *a,
+ double *x0) {
char cfgbuf[CFG_MAX_LEN];
strncpy(cfgbuf, cfg, CFG_MAX_LEN - 1);
@@ -146,7 +168,6 @@
// Set defaults
x0[0] = x0[1] = (double)('c');
- *ext_type = EXT_REPEAT;
if (ncfgwords > 3) {
char *x0params[2];
@@ -163,25 +184,57 @@
}
if (nx0params == 1) x0[1] = x0[0];
}
- if (ncfgwords > 4) {
- if (!strcmp(cfgwords[4], "S") || !strcmp(cfgwords[4], "s") ||
- !strcmp(cfgwords[4], "sym"))
- *ext_type = EXT_SYMMETRIC;
- else if (!strcmp(cfgwords[4], "F") || !strcmp(cfgwords[4], "f") ||
- !strcmp(cfgwords[4], "ref"))
- *ext_type = EXT_REFLECT;
- else if (!strcmp(cfgwords[4], "R") || !strcmp(cfgwords[4], "r") ||
- !strcmp(cfgwords[4], "rep"))
- *ext_type = EXT_REPEAT;
- else if (!strcmp(cfgwords[4], "G") || !strcmp(cfgwords[4], "g") ||
- !strcmp(cfgwords[4], "gra"))
- *ext_type = EXT_GRADIENT;
- else
- return 0;
- }
return 1;
}
+static int get_options(char *argv[], int *bit, int *ebit, EXT_TYPE *ext_type,
+ WIN_TYPE *win_type) {
+ int n = 1;
+ while (argv[n][0] == '-') {
+ if (!strncmp(argv[n], "-bit:", 5)) {
+ *bit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ieb:", 5)) {
+ *ebit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ext:", 5)) {
+ *ext_type = EXT_REPEAT;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "S") || !strcmp(word, "s") || !strcmp(word, "sym"))
+ *ext_type = EXT_SYMMETRIC;
+ else if (!strcmp(word, "F") || !strcmp(word, "f") || !strcmp(word, "ref"))
+ *ext_type = EXT_REFLECT;
+ else if (!strcmp(word, "R") || !strcmp(word, "r") || !strcmp(word, "rep"))
+ *ext_type = EXT_REPEAT;
+ else if (!strcmp(word, "G") || !strcmp(word, "g") || !strcmp(word, "gra"))
+ *ext_type = EXT_GRADIENT;
+ else
+ fprintf(stderr, "Unknown extension type, using default\n");
+ } else if (!strncmp(argv[n], "-win:", 5)) {
+ *win_type = WIN_LANCZOS;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "lanczos"))
+ *win_type = WIN_LANCZOS;
+ else if (!strcmp(word, "lanczos_dil"))
+ *win_type = WIN_LANCZOS_DIL;
+ else if (!strcmp(word, "gaussian"))
+ *win_type = WIN_GAUSSIAN;
+ else if (!strcmp(word, "gengaussian"))
+ *win_type = WIN_GENGAUSSIAN;
+ else if (!strcmp(word, "cosine"))
+ *win_type = WIN_COSINE;
+ else if (!strcmp(word, "hamming"))
+ *win_type = WIN_HAMMING;
+ else if (!strcmp(word, "blackman"))
+ *win_type = WIN_BLACKMAN;
+ else if (!strcmp(word, "kaiser"))
+ *win_type = WIN_KAISER;
+ else
+ fprintf(stderr, "Unknown window type, using default\n");
+ }
+ n++;
+ }
+ return n - 1;
+}
+
static void get_resampled_hdr(char *dest, int len, char **words, int nwords,
int width, int height) {
snprintf(dest, len, "YUV4MPEG2 W%d H%d", width, height);
@@ -217,8 +270,14 @@
}
int main(int argc, char *argv[]) {
+ int extra_bits = DEF_EXTRA_PREC_BITS;
+ int bits = DEF_COEFF_PREC_BITS;
+ EXT_TYPE ext = DEF_EXT_TYPE;
+ WIN_TYPE win = DEF_WIN_TYPE;
+
RationalResampleFilter horz_rf[2], vert_rf[2];
int ywidth, yheight;
+
if (argc < 6) {
printf("Not enough arguments\n");
usage_and_exit(argv[0]);
@@ -226,8 +285,13 @@
if (!strcmp(argv[1], "-help") || !strcmp(argv[1], "-h") ||
!strcmp(argv[1], "--help") || !strcmp(argv[1], "--h"))
usage_and_exit(argv[0]);
- char *y4m_input = argv[1];
- char *y4m_output = argv[5];
+ const int opts = get_options(argv, &bits, &extra_bits, &ext, &win);
+ if (argc < 6 + opts) {
+ printf("Not enough arguments\n");
+ usage_and_exit(argv[0]);
+ }
+ char *y4m_input = argv[opts + 1];
+ char *y4m_output = argv[opts + 5];
char hdr[Y4M_HDR_MAX_LEN];
int nhdrwords;
@@ -248,19 +312,18 @@
usage_and_exit(argv[0]);
}
const int bytes_per_pel = (bitdepth + 7) / 8;
- int num_frames = atoi(argv[2]);
+ int num_frames = atoi(argv[opts + 2]);
int horz_p, horz_q, vert_p, vert_q;
int horz_a[2], vert_a[2];
double horz_x0[2], vert_x0[2];
- EXT_TYPE horz_ext, vert_ext;
- if (!parse_rational_config(argv[3], &horz_p, &horz_q, horz_a, horz_x0,
- &horz_ext)) {
+ if (!parse_rational_config(argv[opts + 3], &horz_p, &horz_q, horz_a,
+ horz_x0)) {
printf("Could not parse horz resampling config\n");
usage_and_exit(argv[0]);
}
- if (!parse_rational_config(argv[4], &vert_p, &vert_q, vert_a, vert_x0,
- &vert_ext)) {
+ if (!parse_rational_config(argv[opts + 4], &vert_p, &vert_q, vert_a,
+ vert_x0)) {
printf("Could not parse vert resampling config\n");
usage_and_exit(argv[0]);
}
@@ -272,12 +335,13 @@
int rywidth = 0, ryheight = 0;
if (horz_p > horz_q || vert_p > vert_q) {
- if (argc < 7) {
+ if (argc < 7 + opts) {
printf("Upsampled output dimensions must be provided\n");
usage_and_exit(argv[0]);
}
// Read output dim if one of the dimensions use upscaling
- if (!parse_dim(argv[6], &rywidth, &ryheight)) usage_and_exit(argv[0]);
+ if (!parse_dim(argv[opts + 6], &rywidth, &ryheight))
+ usage_and_exit(argv[0]);
}
if (horz_p <= horz_q)
rywidth = get_resampled_output_length(ywidth, horz_p, horz_q, subx);
@@ -299,18 +363,15 @@
const int rysize = rywidth * ryheight;
const int ruvsize = ruvwidth * ruvheight;
- const int bits = COEFF_PREC_BITS;
- const int int_extra_bits = INT_EXTRA_PREC_BITS;
-
for (int k = 0; k < 2; ++k) {
- if (!get_resample_filter(horz_p, horz_q, horz_a[k], horz_x0[k], horz_ext,
- DEF_WIN_TYPE, subx, bits, &horz_rf[k])) {
+ if (!get_resample_filter(horz_p, horz_q, horz_a[k], horz_x0[k], ext, win,
+ subx, bits, &horz_rf[k])) {
fprintf(stderr, "Cannot generate filter, exiting!\n");
exit(1);
}
// show_resample_filter(&horz_rf[k]);
- if (!get_resample_filter(vert_p, vert_q, vert_a[k], vert_x0[k], vert_ext,
- DEF_WIN_TYPE, suby, bits, &vert_rf[k])) {
+ if (!get_resample_filter(vert_p, vert_q, vert_a[k], vert_x0[k], ext, win,
+ suby, bits, &vert_rf[k])) {
fprintf(stderr, "Cannot generate filter, exiting!\n");
exit(1);
}
@@ -338,28 +399,28 @@
uint8_t *s = inbuf;
uint8_t *r = outbuf;
resample_2d_8b(s, ywidth, yheight, ywidth, &horz_rf[0], &vert_rf[0],
- int_extra_bits, &clip, r, rywidth, ryheight, rywidth);
+ extra_bits, &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d_8b(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d_8b(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
} else {
int16_t *s = (int16_t *)inbuf;
int16_t *r = (int16_t *)outbuf;
resample_2d(s, ywidth, yheight, ywidth, &horz_rf[0], &vert_rf[0],
- int_extra_bits, &clip, r, rywidth, ryheight, rywidth);
+ extra_bits, &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
}
fwrite(frametag, 6, 1, fout);
fwrite(outbuf, (rysize + 2 * ruvsize) * bytes_per_pel, 1, fout);
diff --git a/tools/lanczos/lanczos_resample_yuv.c b/tools/lanczos/lanczos_resample_yuv.c
index 92fb702..ea1e17c 100644
--- a/tools/lanczos/lanczos_resample_yuv.c
+++ b/tools/lanczos/lanczos_resample_yuv.c
@@ -22,13 +22,14 @@
#define CFG_MAX_LEN 256
#define CFG_MAX_WORDS 5
-#define COEFF_PREC_BITS 14
-#define INT_EXTRA_PREC_BITS 2
-
+#define DEF_EXTRA_PREC_BITS 2
+#define DEF_COEFF_PREC_BITS 14
+#define DEF_EXT_TYPE (EXT_REPEAT)
#define DEF_WIN_TYPE (WIN_LANCZOS)
// Usage:
// lanczos_resample_yuv
+// [<Options>]
// <yuv_input>
// <width>x<height>
// <pix_format>
@@ -41,6 +42,7 @@
void usage_and_exit(char *prog) {
printf("Usage:\n");
printf(" %s\n", prog);
+ printf(" [<Options>]\n");
printf(" <yuv_input>\n");
printf(" <width>x<height>\n");
printf(" <pix_format>\n");
@@ -49,7 +51,33 @@
printf(" <vert_resampling_config>\n");
printf(" <yuv_output>\n");
printf(" [<outwidth>x<outheight>]\n");
+ printf(" \n");
printf(" Notes:\n");
+ printf(" <Options> are optional switches prefixed by '-' as follows:\n");
+ printf(" -bit:<n> - providing bits for filter taps\n");
+ printf(" [default: 14]\n");
+ printf(" -ieb:<n> - providing intermediate extra bits of\n");
+ printf(" prec between horz and vert filtering\n");
+ printf(" [default: 2]\n");
+ printf(" -ext:<ext_type> - providing the extension type\n");
+ printf(" <ext_type> is one of:\n");
+ printf(" 'r' or 'rep' (Repeat)\n");
+ printf(" 's' or 'sym' (Symmetric)\n");
+ printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
+ printf(" 'g' or 'gra' (Grafient preserving)\n");
+ printf(" [default: 'r']\n");
+ printf(" -win:<win_type> - providing the windowing function type\n");
+ printf(" <win_type> is one of:\n");
+ printf(" 'lanczos' (Repeat)\n");
+ printf(" 'lanczos_dil' (Symmetric)\n");
+ printf(" 'gaussian' (Gaussian)\n");
+ printf(" 'gengaussian' (Generalized Gaussian)\n");
+ printf(" 'cosine' (Cosine)\n");
+ printf(" 'hamming (Hamming)\n");
+ printf(" 'blackman (Blackman)\n");
+ printf(" 'kaiser (Kaiser)\n");
+ printf(" [default: 'lanczos']\n");
+ printf(" \n");
printf(" <yuv_input> is the input video in raw YUV format\n");
printf(" <yuv_output> is the output video in raw YUV format\n");
printf(" <width>x<height> is input video dimensions.\n");
@@ -59,7 +87,7 @@
printf(" <num_frames> is number of frames to be processed\n");
printf(" <horz_resampling_config> and <vert_resampling_config>\n");
printf(" are of the form:\n");
- printf(" <p>:<q>:<Lanczos_a>[:<x0>:<ext>] where:\n");
+ printf(" <p>:<q>:<Lanczos_a>[:<x0>] where:\n");
printf(" <p>/<q> gives the resampling ratio.\n");
printf(" <Lanczos_a> is Lanczos parameter.\n");
printf(" <x0> is the optional initial offset\n");
@@ -72,17 +100,11 @@
printf(" which is a shortcut for x0 = (q-p)/(4p)\n");
printf(" The field can be prefixed by 'i' meaning\n");
printf(" using the inverse of the number provided,\n");
- printf(" <ext> is the optional extension type:\n");
- printf(" 'r' or 'rep' (Repeat)\n");
- printf(" 's' or 'sym' (Symmetric)\n");
- printf(" 'f' or 'ref' (Reflect/Mirror-whole)\n");
- printf(" 'g' or 'gra' (Grafient preserving)\n");
- printf(" [default: 'r']\n");
printf(" If it is desired to provide different config parameters\n");
printf(" for luma and chroma, the <Lanczos_a> and <x0> fields\n");
printf(" could be optionally converted to a pair of\n");
printf(" comma-separated parameters as follows:\n");
- printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>:<ext>]\n");
+ printf(" <p>:<q>:<Lanczos_al>,<lanczos_ac>[:<x0l>,<x0c>]\n");
printf(" where <Lanczos_al> and <lanczos_ac> are\n");
printf(" luma and chroma lanczos parameters\n");
printf(" <x0l> and <x0c> are\n");
@@ -162,8 +184,8 @@
return n;
}
-static int parse_rational_config(char *cfg, int *p, int *q, int *a, double *x0,
- EXT_TYPE *ext_type) {
+static int parse_rational_config(char *cfg, int *p, int *q, int *a,
+ double *x0) {
char cfgbuf[CFG_MAX_LEN];
strncpy(cfgbuf, cfg, CFG_MAX_LEN - 1);
@@ -186,7 +208,6 @@
// Set defaults
x0[0] = x0[1] = (double)('c');
- *ext_type = EXT_REPEAT;
if (ncfgwords > 3) {
char *x0params[2];
@@ -203,26 +224,63 @@
}
if (nx0params == 1) x0[1] = x0[0];
}
- if (ncfgwords > 4) {
- if (!strcmp(cfgwords[4], "S") || !strcmp(cfgwords[4], "s") ||
- !strcmp(cfgwords[4], "sym"))
- *ext_type = EXT_SYMMETRIC;
- else if (!strcmp(cfgwords[4], "F") || !strcmp(cfgwords[4], "f") ||
- !strcmp(cfgwords[4], "ref"))
- *ext_type = EXT_REFLECT;
- else if (!strcmp(cfgwords[4], "R") || !strcmp(cfgwords[4], "r") ||
- !strcmp(cfgwords[4], "rep"))
- *ext_type = EXT_REPEAT;
- else if (!strcmp(cfgwords[4], "G") || !strcmp(cfgwords[4], "g") ||
- !strcmp(cfgwords[4], "gra"))
- *ext_type = EXT_GRADIENT;
- else
- return 0;
- }
return 1;
}
+static int get_options(char *argv[], int *bit, int *ebit, EXT_TYPE *ext_type,
+ WIN_TYPE *win_type) {
+ int n = 1;
+ while (argv[n][0] == '-') {
+ if (!strncmp(argv[n], "-bit:", 5)) {
+ *bit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ieb:", 5)) {
+ *ebit = atoi(argv[n] + 5);
+ } else if (!strncmp(argv[n], "-ext:", 5)) {
+ *ext_type = EXT_REPEAT;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "S") || !strcmp(word, "s") || !strcmp(word, "sym"))
+ *ext_type = EXT_SYMMETRIC;
+ else if (!strcmp(word, "F") || !strcmp(word, "f") || !strcmp(word, "ref"))
+ *ext_type = EXT_REFLECT;
+ else if (!strcmp(word, "R") || !strcmp(word, "r") || !strcmp(word, "rep"))
+ *ext_type = EXT_REPEAT;
+ else if (!strcmp(word, "G") || !strcmp(word, "g") || !strcmp(word, "gra"))
+ *ext_type = EXT_GRADIENT;
+ else
+ fprintf(stderr, "Unknown extension type, using default\n");
+ } else if (!strncmp(argv[n], "-win:", 5)) {
+ *win_type = WIN_LANCZOS;
+ const char *word = argv[n] + 5;
+ if (!strcmp(word, "lanczos"))
+ *win_type = WIN_LANCZOS;
+ else if (!strcmp(word, "lanczos_dil"))
+ *win_type = WIN_LANCZOS_DIL;
+ else if (!strcmp(word, "gaussian"))
+ *win_type = WIN_GAUSSIAN;
+ else if (!strcmp(word, "gengaussian"))
+ *win_type = WIN_GENGAUSSIAN;
+ else if (!strcmp(word, "cosine"))
+ *win_type = WIN_COSINE;
+ else if (!strcmp(word, "hamming"))
+ *win_type = WIN_HAMMING;
+ else if (!strcmp(word, "blackman"))
+ *win_type = WIN_BLACKMAN;
+ else if (!strcmp(word, "kaiser"))
+ *win_type = WIN_KAISER;
+ else
+ fprintf(stderr, "Unknown window type, using default\n");
+ }
+ n++;
+ }
+ return n - 1;
+}
+
int main(int argc, char *argv[]) {
+ int extra_bits = DEF_EXTRA_PREC_BITS;
+ int bits = DEF_COEFF_PREC_BITS;
+ EXT_TYPE ext = DEF_EXT_TYPE;
+ WIN_TYPE win = DEF_WIN_TYPE;
+
RationalResampleFilter horz_rf[2], vert_rf[2];
int ywidth, yheight;
if (argc < 8) {
@@ -232,33 +290,38 @@
if (!strcmp(argv[1], "-help") || !strcmp(argv[1], "-h") ||
!strcmp(argv[1], "--help") || !strcmp(argv[1], "--h"))
usage_and_exit(argv[0]);
- if (!parse_dim(argv[2], &ywidth, &yheight)) usage_and_exit(argv[0]);
+ const int opts = get_options(argv, &bits, &extra_bits, &ext, &win);
+ if (argc < 8 + opts) {
+ printf("Not enough arguments\n");
+ usage_and_exit(argv[0]);
+ }
+
+ if (!parse_dim(argv[opts + 2], &ywidth, &yheight)) usage_and_exit(argv[0]);
int subx, suby;
int bitdepth;
- if (!parse_pix_format(argv[3], &bitdepth, &subx, &suby))
+ if (!parse_pix_format(argv[opts + 3], &bitdepth, &subx, &suby))
usage_and_exit(argv[0]);
const int bytes_per_pel = (bitdepth + 7) / 8;
- int num_frames = atoi(argv[4]);
+ int num_frames = atoi(argv[opts + 4]);
int horz_p, horz_q, vert_p, vert_q;
int horz_a[2], vert_a[2];
double horz_x0[2], vert_x0[2];
- EXT_TYPE horz_ext = EXT_REPEAT, vert_ext = EXT_REPEAT;
- if (!parse_rational_config(argv[5], &horz_p, &horz_q, horz_a, horz_x0,
- &horz_ext)) {
+ if (!parse_rational_config(argv[opts + 5], &horz_p, &horz_q, horz_a,
+ horz_x0)) {
printf("Could not parse horz resampling config\n");
usage_and_exit(argv[0]);
}
- if (!parse_rational_config(argv[6], &vert_p, &vert_q, vert_a, vert_x0,
- &vert_ext)) {
+ if (!parse_rational_config(argv[opts + 6], &vert_p, &vert_q, vert_a,
+ vert_x0)) {
printf("Could not parse vert resampling config\n");
usage_and_exit(argv[0]);
}
- char *yuv_input = argv[1];
- char *yuv_output = argv[7];
+ char *yuv_input = argv[opts + 1];
+ char *yuv_output = argv[opts + 7];
const int uvwidth = subx ? (ywidth + 1) >> 1 : ywidth;
const int uvheight = suby ? (yheight + 1) >> 1 : yheight;
@@ -267,12 +330,13 @@
int rywidth = 0, ryheight = 0;
if (horz_p > horz_q || vert_p > vert_q) {
- if (argc < 9) {
+ if (argc < 9 + opts) {
printf("Upsampled output dimensions must be provided\n");
usage_and_exit(argv[0]);
}
// Read output dim if one of the dimensions use upscaling
- if (!parse_dim(argv[8], &rywidth, &ryheight)) usage_and_exit(argv[0]);
+ if (!parse_dim(argv[opts + 8], &rywidth, &ryheight))
+ usage_and_exit(argv[0]);
}
if (horz_p <= horz_q)
rywidth = get_resampled_output_length(ywidth, horz_p, horz_q, subx);
@@ -287,18 +351,15 @@
const int rysize = rywidth * ryheight;
const int ruvsize = ruvwidth * ruvheight;
- const int bits = COEFF_PREC_BITS;
- const int int_extra_bits = INT_EXTRA_PREC_BITS;
-
for (int k = 0; k < 2; ++k) {
- if (!get_resample_filter(horz_p, horz_q, horz_a[k], horz_x0[k], horz_ext,
- DEF_WIN_TYPE, subx, bits, &horz_rf[k])) {
+ if (!get_resample_filter(horz_p, horz_q, horz_a[k], horz_x0[k], ext, win,
+ subx, bits, &horz_rf[k])) {
fprintf(stderr, "Cannot generate filter, exiting!\n");
exit(1);
}
// show_resample_filter(&horz_rf[k]);
- if (!get_resample_filter(vert_p, vert_q, vert_a[k], vert_x0[k], vert_ext,
- DEF_WIN_TYPE, suby, bits, &vert_rf[k])) {
+ if (!get_resample_filter(vert_p, vert_q, vert_a[k], vert_x0[k], ext, win,
+ suby, bits, &vert_rf[k])) {
fprintf(stderr, "Cannot generate filter, exiting!\n");
exit(1);
}
@@ -321,28 +382,28 @@
uint8_t *s = inbuf;
uint8_t *r = outbuf;
resample_2d_8b(s, ywidth, yheight, ywidth, &horz_rf[0], &vert_rf[0],
- int_extra_bits, &clip, r, rywidth, ryheight, rywidth);
+ extra_bits, &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d_8b(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d_8b(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
} else {
int16_t *s = (int16_t *)inbuf;
int16_t *r = (int16_t *)outbuf;
resample_2d(s, ywidth, yheight, ywidth, &horz_rf[0], &vert_rf[0],
- int_extra_bits, &clip, r, rywidth, ryheight, rywidth);
+ extra_bits, &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf[1], &vert_rf[1],
- int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
+ extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
}
fwrite(outbuf, (rysize + 2 * ruvsize) * bytes_per_pel, 1, fout);
}