Support horz only and vert only resampling better
Change-Id: Ib7e68794facf042a52edc58915b830da700e43fe
diff --git a/tools/lanczos/lanczos_README.txt b/tools/lanczos/lanczos_README.txt
index 8a44b1f..d55b3ba 100644
--- a/tools/lanczos/lanczos_README.txt
+++ b/tools/lanczos/lanczos_README.txt
@@ -45,6 +45,8 @@
or 'c' meaning centered
<outwidth>x<outheight> is output video dimensions
only needed in case of upsampling
+ Resampling config string of 1:1:1:0 horizontally or vertically
+ is regarded as a no-op in that direction.
Example usages:
@@ -111,6 +113,8 @@
or 'c' meaning centered
<outwidth>x<outheight> is output video dimensions
only needed in case of upsampling
+ Resampling config string of 1:1:1:0 horizontally or vertically
+ is regarded as a no-op in that direction.
diff --git a/tools/lanczos/lanczos_resample.c b/tools/lanczos/lanczos_resample.c
index 3165e34..d550a14 100644
--- a/tools/lanczos/lanczos_resample.c
+++ b/tools/lanczos/lanczos_resample.c
@@ -187,6 +187,7 @@
rf->p = p / g;
rf->q = q / g;
if (x0 == (double)('c')) x0 = get_centered_x0(rf->p, rf->q);
+ rf->filter_bits = bits;
for (int i = 0; i < rf->p; ++i) {
offset[i] = (double)rf->q / (double)rf->p * i + x0;
intpel[i] = (int)floor(offset[i]);
@@ -272,19 +273,21 @@
free(xext_);
}
-static void fill_col_to_arr(int16_t *img, int stride, int len, int16_t *arr) {
+static void fill_col_to_arr(const int16_t *img, int stride, int len,
+ int16_t *arr) {
int i;
- int16_t *iptr = img;
+ const int16_t *iptr = img;
int16_t *aptr = arr;
for (i = 0; i < len; ++i, iptr += stride) {
*aptr++ = *iptr;
}
}
-static void fill_arr_to_col(int16_t *img, int stride, int len, int16_t *arr) {
+static void fill_arr_to_col(int16_t *img, int stride, int len,
+ const int16_t *arr) {
int i;
int16_t *iptr = img;
- int16_t *aptr = arr;
+ const int16_t *aptr = arr;
for (i = 0; i < len; ++i, iptr += stride) {
*iptr = *aptr++;
}
@@ -292,18 +295,30 @@
void resample_2d(const int16_t *x, int inwidth, int inheight, int instride,
RationalResampleFilter *rfh, RationalResampleFilter *rfv,
- int downshifth, int downshiftv, ClipProfile *clip, int16_t *y,
+ int int_extra_bits, ClipProfile *clip, int16_t *y,
int outwidth, int outheight, int outstride) {
+ if (rfv == NULL || is_resampler_noop(rfv)) {
+ resample_horz(x, inwidth, inheight, instride, rfh, clip, y, outwidth,
+ outstride);
+ return;
+ }
+ if (rfh == NULL || is_resampler_noop(rfh)) {
+ resample_vert(x, inwidth, inheight, instride, rfv, clip, y, outheight,
+ outstride);
+ return;
+ }
int16_t *tmpbuf = (int16_t *)malloc(sizeof(int16_t) * outwidth * inheight);
const int arrsize =
outheight + ((inheight + rfv->length > inwidth + rfh->length)
? (inheight + rfv->length)
: (inwidth + rfh->length));
- int16_t *tmparr_ = (int16_t *)malloc(sizeof(int16_t) * arrsize);
+ int16_t *tmparr_ = (int16_t *)calloc(arrsize, sizeof(int16_t));
int16_t *tmparrh = tmparr_ + outheight + rfh->length / 2;
int16_t *tmparrv = tmparr_ + outheight + rfv->length / 2;
int16_t *tmparro = tmparr_;
int tmpstride = outwidth;
+ const int downshifth = rfh->filter_bits - int_extra_bits;
+ const int downshiftv = rfh->filter_bits + int_extra_bits;
for (int i = 0; i < inheight; ++i) {
resample_1d_xc(x + instride * i, inwidth, rfh, downshifth, NULL,
tmpbuf + i * tmpstride, outwidth, tmparrh);
@@ -318,19 +333,35 @@
free(tmparr_);
}
-void resample_hor(const int16_t *x, int inwidth, int inheight, int instride,
- RationalResampleFilter *rfh, int downshifth,
- ClipProfile *clip, int16_t *y, int outwidth, int outstride) {
- int16_t *tmparr_ =
- (int16_t *)malloc(sizeof(int16_t) * (inwidth + rfh->length));
+void resample_horz(const int16_t *x, int inwidth, int inheight, int instride,
+ RationalResampleFilter *rfh, ClipProfile *clip, int16_t *y,
+ int outwidth, int outstride) {
+ const int arrsize = inwidth + rfh->length;
+ int16_t *tmparr_ = (int16_t *)calloc(arrsize, sizeof(int16_t));
int16_t *tmparrh = tmparr_ + rfh->length / 2;
for (int i = 0; i < inheight; ++i) {
- resample_1d_xc(x + instride * i, inwidth, rfh, downshifth, clip,
+ resample_1d_xc(x + instride * i, inwidth, rfh, rfh->filter_bits, clip,
y + i * outstride, outwidth, tmparrh);
}
free(tmparr_);
}
+void resample_vert(const int16_t *x, int inwidth, int inheight, int instride,
+ RationalResampleFilter *rfv, ClipProfile *clip, int16_t *y,
+ int outheight, int outstride) {
+ const int arrsize = outheight + inheight + rfv->length;
+ int16_t *tmparr_ = (int16_t *)calloc(arrsize, sizeof(int16_t));
+ int16_t *tmparrv = tmparr_ + outheight + rfv->length / 2;
+ int16_t *tmparro = tmparr_;
+ for (int i = 0; i < inwidth; ++i) {
+ fill_col_to_arr(x + i, instride, inheight, tmparrv);
+ resample_1d_xt(tmparrv, inheight, rfv, rfv->filter_bits, clip, tmparro,
+ outheight);
+ fill_arr_to_col(y + i, outstride, outheight, tmparro);
+ }
+ free(tmparr_);
+}
+
int get_resampled_output_length(int inlen, int p, int q, int force_even) {
if (!force_even) {
// round
diff --git a/tools/lanczos/lanczos_resample.h b/tools/lanczos/lanczos_resample.h
index 3c54023..51fff05 100644
--- a/tools/lanczos/lanczos_resample.h
+++ b/tools/lanczos/lanczos_resample.h
@@ -25,6 +25,7 @@
int length;
int start;
int steps[MAX_RATIONAL_FACTOR];
+ int filter_bits;
int16_t filter[MAX_RATIONAL_FACTOR][MAX_FILTER_LEN];
double phases[MAX_RATIONAL_FACTOR];
} RationalResampleFilter;
@@ -69,12 +70,15 @@
void resample_2d(const int16_t *x, int inwidth, int inheight, int instride,
RationalResampleFilter *rfh, RationalResampleFilter *rfv,
- int downshifth, int downshiftv, ClipProfile *clip, int16_t *y,
+ int int_extra_bits, ClipProfile *clip, int16_t *y,
int outwidth, int outheight, int outstride);
-void resample_hor(const int16_t *x, int inwidth, int inheight, int instride,
- RationalResampleFilter *rfh, int downshifth,
- ClipProfile *clip, int16_t *y, int outwidth, int outstride);
+void resample_horz(const int16_t *x, int inwidth, int inheight, int instride,
+ RationalResampleFilter *rfh, ClipProfile *clip, int16_t *y,
+ int outwidth, int outstride);
+void resample_vert(const int16_t *x, int inwidth, int inheight, int instride,
+ RationalResampleFilter *rfv, ClipProfile *clip, int16_t *y,
+ int outheight, int outstride);
void show_resample_filter(RationalResampleFilter *rf);
diff --git a/tools/lanczos/lanczos_resample_y4m.c b/tools/lanczos/lanczos_resample_y4m.c
index 52129c0..d3c859b 100644
--- a/tools/lanczos/lanczos_resample_y4m.c
+++ b/tools/lanczos/lanczos_resample_y4m.c
@@ -219,8 +219,7 @@
const int ruvsize = ruvwidth * ruvheight;
const int bits = COEFF_PREC_BITS;
- const int horz_downshift = bits - INT_EXTRA_PREC_BITS;
- const int vert_downshift = bits + INT_EXTRA_PREC_BITS;
+ const int int_extra_bits = INT_EXTRA_PREC_BITS;
get_resample_filter(horz_p, horz_q, horz_a, horz_x0, bits, &horz_rf);
// show_resample_filter(&horz_rf);
@@ -258,18 +257,16 @@
}
s = src;
r = res;
- resample_2d(s, ywidth, yheight, ywidth, &horz_rf, &vert_rf, horz_downshift,
- vert_downshift, &clip, r, rywidth, ryheight, rywidth);
+ resample_2d(s, ywidth, yheight, ywidth, &horz_rf, &vert_rf, int_extra_bits,
+ &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf, &vert_rf,
- horz_downshift, vert_downshift, &clip, r, ruvwidth, ruvheight,
- ruvwidth);
+ int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf, &vert_rf,
- horz_downshift, vert_downshift, &clip, r, ruvwidth, ruvheight,
- ruvwidth);
+ int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
if (bytes_per_pel == 1) {
uint8_t *d = outbuf;
r = res;
diff --git a/tools/lanczos/lanczos_resample_yuv.c b/tools/lanczos/lanczos_resample_yuv.c
index 2df0110..8cc4a1e 100644
--- a/tools/lanczos/lanczos_resample_yuv.c
+++ b/tools/lanczos/lanczos_resample_yuv.c
@@ -196,8 +196,7 @@
const int ruvsize = ruvwidth * ruvheight;
const int bits = COEFF_PREC_BITS;
- const int horz_downshift = bits - INT_EXTRA_PREC_BITS;
- const int vert_downshift = bits + INT_EXTRA_PREC_BITS;
+ const int int_extra_bits = INT_EXTRA_PREC_BITS;
get_resample_filter(horz_p, horz_q, horz_a, horz_x0, bits, &horz_rf);
// show_resample_filter(&horz_rf);
@@ -230,18 +229,16 @@
}
s = src;
r = res;
- resample_2d(s, ywidth, yheight, ywidth, &horz_rf, &vert_rf, horz_downshift,
- vert_downshift, &clip, r, rywidth, ryheight, rywidth);
+ resample_2d(s, ywidth, yheight, ywidth, &horz_rf, &vert_rf, int_extra_bits,
+ &clip, r, rywidth, ryheight, rywidth);
s += ysize;
r += rysize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf, &vert_rf,
- horz_downshift, vert_downshift, &clip, r, ruvwidth, ruvheight,
- ruvwidth);
+ int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
s += uvsize;
r += ruvsize;
resample_2d(s, uvwidth, uvheight, uvwidth, &horz_rf, &vert_rf,
- horz_downshift, vert_downshift, &clip, r, ruvwidth, ruvheight,
- ruvwidth);
+ int_extra_bits, &clip, r, ruvwidth, ruvheight, ruvwidth);
if (bytes_per_pel == 1) {
uint8_t *d = outbuf;
r = res;