| /* | |
| * Copyright (c) 2021, Alliance for Open Media. All rights reserved | |
| * | |
| * This source code is subject to the terms of the BSD 3-Clause Clear License | |
| * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear | |
| * License was not distributed with this source code in the LICENSE file, you | |
| * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the | |
| * Alliance for Open Media Patent License 1.0 was not distributed with this | |
| * source code in the PATENTS file, you can obtain it at | |
| * aomedia.org/license/patent-license/. | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdint.h> | |
| #include <stdbool.h> | |
| #include <string.h> | |
| #include <math.h> | |
| #define MAX_RATIONAL_FACTOR 16 | |
| #define MAX_FILTER_LEN 320 | |
| // Note: check window() function implementation for values of any | |
| // other params used by these windowing functions. | |
| typedef enum { | |
| WIN_LANCZOS, // Sinc window (i.e. Lanczos) | |
| WIN_LANCZOS_DIL, // Dilated Lanczos window | |
| WIN_GAUSSIAN, // Gaussian window | |
| WIN_GENGAUSSIAN, // Gaussian window | |
| WIN_COSINE, // Cosine window | |
| WIN_HAMMING, // Hamming Window | |
| WIN_BLACKMAN, // Blackman window | |
| WIN_KAISER, // Kaiser window | |
| } WIN_TYPE; | |
| typedef enum { EXT_REPEAT, EXT_SYMMETRIC, EXT_REFLECT, EXT_GRADIENT } EXT_TYPE; | |
| typedef struct { | |
| int p; | |
| int q; | |
| int length; | |
| EXT_TYPE ext_type; | |
| WIN_TYPE win_type; | |
| int filter_bits; | |
| int start; | |
| int steps[MAX_RATIONAL_FACTOR]; | |
| int16_t filter[MAX_RATIONAL_FACTOR][MAX_FILTER_LEN]; | |
| double phases[MAX_RATIONAL_FACTOR]; | |
| } RationalResampleFilter; | |
| typedef struct { | |
| int bits; | |
| int issigned; | |
| } ClipProfile; | |
| double get_centered_x0(int p, int q); | |
| // x0 is assumed to be in (-1, 1) | |
| double get_inverse_x0_numeric(int p, int q, double x0); | |
| // In the functions below using x0 as an argument, | |
| // x0 is assumed to be in (-1, 1); | |
| // or 99 (ascii value of 'c') meaning centered; | |
| // or 100 (ascii value of 'd') meaning co-sited chroma | |
| // if the chroma plane is subsampled. | |
| double get_inverse_x0(int p, int q, double x0, int subsampled); | |
| int get_resample_filter(int p, int q, int a, double x0, EXT_TYPE ext_type, | |
| WIN_TYPE win_type, int subsampled, int bits, | |
| RationalResampleFilter *rf); | |
| int get_resample_filter_inv(int p, int q, int a, double x0, EXT_TYPE ext_type, | |
| WIN_TYPE win_type, int subsampled, int bits, | |
| RationalResampleFilter *rf); | |
| // whether the resampler filter is a no-op | |
| int is_resampler_noop(RationalResampleFilter *rf); | |
| // 16-bit versions of high-level resampling functions | |
| // Assume no extension of the input x buffer | |
| void resample_1d(const int16_t *x, int inlen, RationalResampleFilter *rf, | |
| int downshift, ClipProfile *clip, int16_t *y, int outlen); | |
| void resample_2d(const int16_t *x, int inwidth, int inheight, int instride, | |
| RationalResampleFilter *rfh, RationalResampleFilter *rfv, | |
| int int_extra_bits, ClipProfile *clip, int16_t *y, | |
| int outwidth, int outheight, 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); | |
| // 8-bit versions of high-level resampling functions | |
| // Assume no extension of the input x buffer | |
| void resample_1d_8b(const uint8_t *x, int inlen, RationalResampleFilter *rf, | |
| int downshift, ClipProfile *clip, uint8_t *y, int outlen); | |
| void resample_2d_8b(const uint8_t *x, int inwidth, int inheight, int instride, | |
| RationalResampleFilter *rfh, RationalResampleFilter *rfv, | |
| int int_extra_bits, ClipProfile *clip, uint8_t *y, | |
| int outwidth, int outheight, int outstride); | |
| void resample_horz_8b(const uint8_t *x, int inwidth, int inheight, int instride, | |
| RationalResampleFilter *rfh, ClipProfile *clip, | |
| uint8_t *y, int outwidth, int outstride); | |
| void resample_vert_8b(const uint8_t *x, int inwidth, int inheight, int instride, | |
| RationalResampleFilter *rfv, ClipProfile *clip, | |
| uint8_t *y, int outheight, int outstride); | |
| void show_resample_filter(RationalResampleFilter *rf); | |
| int get_resampled_output_length(int inlen, int p, int q, int force_even); | |
| const char *ext2str(EXT_TYPE ext_type); |