/* * Copyright © 2018, VideoLAN and dav1d authors * Copyright © 2018, Two Orioles, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include <stdlib.h>#include <string.h> #include "common/attributes.h"#include "common/intops.h" #include "src/mc.h"#include "src/tables.h" #if BITDEPTH == 8#define get_intermediate_bits(bitdepth_max) 4// Output in interval [-5132, 9212], fits in int16_t as is#define PREP_BIAS 0#else// 4 for 10 bits/component, 2 for 12 bits/component#define get_intermediate_bits(bitdepth_max) (14 - bitdepth_from_max(bitdepth_max))// Output in interval [-20588, 36956] (10-bit), [-20602, 36983] (12-bit)// Subtract a bias to ensure the output fits in int16_t#define PREP_BIAS 8192#endif static NOINLINE voidput_c(pixel *dst, const ptrdiff_t dst_stride, const pixel *src, const ptrdiff_t src_stride, const int w, int h){ do { pixel_copy(dst, src, w); dst += dst_stride; src += src_stride; } while (--h);} static NOINLINE voidprep_c(int16_t *tmp, const pixel *src, const ptrdiff_t src_stride, const int w, int h HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); do { for (int x = 0; x < w; x++) tmp[x] = (src[x] << intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h);} #define FILTER_8TAP(src, x, F, stride) \ (F[0] * src[x + -3 * stride] + \ F[1] * src[x + -2 * stride] + \ F[2] * src[x + -1 * stride] + \ F[3] * src[x + +0 * stride] + \ F[4] * src[x + +1 * stride] + \ F[5] * src[x + +2 * stride] + \ F[6] * src[x + +3 * stride] + \ F[7] * src[x + +4 * stride]) #define DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh) \ ((FILTER_8TAP(src, x, F, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define DAV1D_FILTER_8TAP_CLIP(src, x, F, stride, sh) \ iclip_pixel(DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh)) #define GET_H_FILTER(mx) \ const int8_t *const fh = !(mx) ? NULL : w > 4 ? \ dav1d_mc_subpel_filters[filter_type & 3][(mx) - 1] : \ dav1d_mc_subpel_filters[3 + (filter_type & 1)][(mx) - 1] #define GET_V_FILTER(my) \ const int8_t *const fv = !(my) ? NULL : h > 4 ? \ dav1d_mc_subpel_filters[filter_type >> 2][(my) - 1] : \ dav1d_mc_subpel_filters[3 + ((filter_type >> 2) & 1)][(my) - 1] #define GET_FILTERS() \ GET_H_FILTER(mx); \ GET_V_FILTER(my) static NOINLINE voidput_etap_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my, const int filter_type HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; GET_FILTERS(); dst_stride = PXSTRIDE(dst_stride); src_stride = PXSTRIDE(src_stride); if (fh) { if (fv) { int tmp_h = h + 7; int16_t mid[128 * 135], *mid_ptr = mid; src -= src_stride * 3; do { for (int x = 0; x < w; x++) mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; do { for (int x = 0; x < w; x++) dst[x] = DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128, 6 + intermediate_bits); mid_ptr += 128; dst += dst_stride; } while (--h); } else { do { for (int x = 0; x < w; x++) { const int px = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits); } dst += dst_stride; src += src_stride; } while (--h); } } else if (fv) { do { for (int x = 0; x < w; x++) dst[x] = DAV1D_FILTER_8TAP_CLIP(src, x, fv, src_stride, 6); dst += dst_stride; src += src_stride; } while (--h); } else put_c(dst, dst_stride, src, src_stride, w, h);} static NOINLINE voidput_etap_scaled_c(pixel *dst, const ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy, const int filter_type HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; int tmp_h = (((h - 1) * dy + my) >> 10) + 8; int16_t mid[128 * (256 + 7)], *mid_ptr = mid; src_stride = PXSTRIDE(src_stride); src -= src_stride * 3; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { GET_H_FILTER(imx >> 6); mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1, 6 - intermediate_bits) : src[ioff] << intermediate_bits; imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; for (int y = 0; y < h; y++) { int x; GET_V_FILTER(my >> 6); for (x = 0; x < w; x++) dst[x] = fv ? DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128, 6 + intermediate_bits) : iclip_pixel((mid_ptr[x] + intermediate_rnd) >> intermediate_bits); my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; dst += PXSTRIDE(dst_stride); }} static NOINLINE voidprep_etap_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my, const int filter_type HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); GET_FILTERS(); src_stride = PXSTRIDE(src_stride); if (fh) { if (fv) { int tmp_h = h + 7; int16_t mid[128 * 135], *mid_ptr = mid; src -= src_stride * 3; do { for (int x = 0; x < w; x++) mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; do { for (int x = 0; x < w; x++) { int t = DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6) - PREP_BIAS; assert(t >= INT16_MIN && t <= INT16_MAX); tmp[x] = t; } mid_ptr += 128; tmp += w; } while (--h); } else { do { for (int x = 0; x < w; x++) tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h); } } else if (fv) { do { for (int x = 0; x < w; x++) tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fv, src_stride, 6 - intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h); } else prep_c(tmp, src, src_stride, w, h HIGHBD_TAIL_SUFFIX);} static NOINLINE voidprep_etap_scaled_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy, const int filter_type HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); int tmp_h = (((h - 1) * dy + my) >> 10) + 8; int16_t mid[128 * (256 + 7)], *mid_ptr = mid; src_stride = PXSTRIDE(src_stride); src -= src_stride * 3; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { GET_H_FILTER(imx >> 6); mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1, 6 - intermediate_bits) : src[ioff] << intermediate_bits; imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; for (int y = 0; y < h; y++) { int x; GET_V_FILTER(my >> 6); for (x = 0; x < w; x++) tmp[x] = (fv ? DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6) : mid_ptr[x]) - PREP_BIAS; my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; tmp += w; }} #define filter_fns(type, type_h, type_v) \static void put_etap_##type##_c(pixel *const dst, \ const ptrdiff_t dst_stride, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my \ HIGHBD_DECL_SUFFIX) \{ \ put_etap_c(dst, dst_stride, src, src_stride, w, h, mx, my, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void put_etap_##type##_scaled_c(pixel *const dst, \ const ptrdiff_t dst_stride, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my, \ const int dx, const int dy \ HIGHBD_DECL_SUFFIX) \{ \ put_etap_scaled_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void prep_etap_##type##_c(int16_t *const tmp, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my \ HIGHBD_DECL_SUFFIX) \{ \ prep_etap_c(tmp, src, src_stride, w, h, mx, my, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} \static void prep_etap_##type##_scaled_c(int16_t *const tmp, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my, \ const int dx, const int dy \ HIGHBD_DECL_SUFFIX) \{ \ prep_etap_scaled_c(tmp, src, src_stride, w, h, mx, my, dx, dy, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \} filter_fns(regular, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_REGULAR)filter_fns(regular_sharp, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SHARP)filter_fns(regular_smooth, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SMOOTH)filter_fns(smooth, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SMOOTH)filter_fns(smooth_regular, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_REGULAR)filter_fns(smooth_sharp, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SHARP)filter_fns(sharp, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SHARP)filter_fns(sharp_regular, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_REGULAR)filter_fns(sharp_smooth, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SMOOTH) #define FILTER_BILIN(src, x, mxy, stride) \ (16 * src[x] + ((mxy) * (src[x + stride] - src[x]))) #define FILTER_BILIN_RND(src, x, mxy, stride, sh) \ ((FILTER_BILIN(src, x, mxy, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define FILTER_BILIN_CLIP(src, x, mxy, stride, sh) \ iclip_pixel(FILTER_BILIN_RND(src, x, mxy, stride, sh)) static void put_bilin_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; dst_stride = PXSTRIDE(dst_stride); src_stride = PXSTRIDE(src_stride); if (mx) { if (my) { int16_t mid[128 * 129], *mid_ptr = mid; int tmp_h = h + 1; do { for (int x = 0; x < w; x++) mid_ptr[x] = FILTER_BILIN_RND(src, x, mx, 1, 4 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid; do { for (int x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my, 128, 4 + intermediate_bits); mid_ptr += 128; dst += dst_stride; } while (--h); } else { do { for (int x = 0; x < w; x++) { const int px = FILTER_BILIN_RND(src, x, mx, 1, 4 - intermediate_bits); dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits); } dst += dst_stride; src += src_stride; } while (--h); } } else if (my) { do { for (int x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(src, x, my, src_stride, 4); dst += dst_stride; src += src_stride; } while (--h); } else put_c(dst, dst_stride, src, src_stride, w, h);} static void put_bilin_scaled_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); int tmp_h = (((h - 1) * dy + my) >> 10) + 2; int16_t mid[128 * (256 + 1)], *mid_ptr = mid; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { mid_ptr[x] = FILTER_BILIN_RND(src, ioff, imx >> 6, 1, 4 - intermediate_bits); imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += PXSTRIDE(src_stride); } while (--tmp_h); mid_ptr = mid; do { int x; for (x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my >> 6, 128, 4 + intermediate_bits); my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; dst += PXSTRIDE(dst_stride); } while (--h);} static void prep_bilin_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my HIGHBD_DECL_SUFFIX){ const int intermediate_bits = get_intermediate_bits(bitdepth_max); src_stride = PXSTRIDE(src_stride); if (mx) { if (my) { int16_t mid[128 * 129], *mid_ptr = mid; int tmp_h = h + 1; Lines 1–500 of 963. Load more
/* * Copyright © 2018, VideoLAN and dav1d authors * Copyright © 2018, Two Orioles, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include <stdlib.h> #include <string.h> #include "common/attributes.h" #include "common/intops.h" #include "src/mc.h" #include "src/tables.h" #if BITDEPTH == 8 #define get_intermediate_bits(bitdepth_max) 4 // Output in interval [-5132, 9212], fits in int16_t as is #define PREP_BIAS 0 #else // 4 for 10 bits/component, 2 for 12 bits/component #define get_intermediate_bits(bitdepth_max) (14 - bitdepth_from_max(bitdepth_max)) // Output in interval [-20588, 36956] (10-bit), [-20602, 36983] (12-bit) // Subtract a bias to ensure the output fits in int16_t #define PREP_BIAS 8192 #endif static NOINLINE void put_c(pixel *dst, const ptrdiff_t dst_stride, const pixel *src, const ptrdiff_t src_stride, const int w, int h) { do { pixel_copy(dst, src, w); dst += dst_stride; src += src_stride; } while (--h); } static NOINLINE void prep_c(int16_t *tmp, const pixel *src, const ptrdiff_t src_stride, const int w, int h HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); do { for (int x = 0; x < w; x++) tmp[x] = (src[x] << intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h); } #define FILTER_8TAP(src, x, F, stride) \ (F[0] * src[x + -3 * stride] + \ F[1] * src[x + -2 * stride] + \ F[2] * src[x + -1 * stride] + \ F[3] * src[x + +0 * stride] + \ F[4] * src[x + +1 * stride] + \ F[5] * src[x + +2 * stride] + \ F[6] * src[x + +3 * stride] + \ F[7] * src[x + +4 * stride]) #define DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh) \ ((FILTER_8TAP(src, x, F, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define DAV1D_FILTER_8TAP_CLIP(src, x, F, stride, sh) \ iclip_pixel(DAV1D_FILTER_8TAP_RND(src, x, F, stride, sh)) #define GET_H_FILTER(mx) \ const int8_t *const fh = !(mx) ? NULL : w > 4 ? \ dav1d_mc_subpel_filters[filter_type & 3][(mx) - 1] : \ dav1d_mc_subpel_filters[3 + (filter_type & 1)][(mx) - 1] #define GET_V_FILTER(my) \ const int8_t *const fv = !(my) ? NULL : h > 4 ? \ dav1d_mc_subpel_filters[filter_type >> 2][(my) - 1] : \ dav1d_mc_subpel_filters[3 + ((filter_type >> 2) & 1)][(my) - 1] #define GET_FILTERS() \ GET_H_FILTER(mx); \ GET_V_FILTER(my) static NOINLINE void put_etap_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my, const int filter_type HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; GET_FILTERS(); dst_stride = PXSTRIDE(dst_stride); src_stride = PXSTRIDE(src_stride); if (fh) { if (fv) { int tmp_h = h + 7; int16_t mid[128 * 135], *mid_ptr = mid; src -= src_stride * 3; do { for (int x = 0; x < w; x++) mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; do { for (int x = 0; x < w; x++) dst[x] = DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128, 6 + intermediate_bits); mid_ptr += 128; dst += dst_stride; } while (--h); } else { do { for (int x = 0; x < w; x++) { const int px = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits); } dst += dst_stride; src += src_stride; } while (--h); } } else if (fv) { do { for (int x = 0; x < w; x++) dst[x] = DAV1D_FILTER_8TAP_CLIP(src, x, fv, src_stride, 6); dst += dst_stride; src += src_stride; } while (--h); } else put_c(dst, dst_stride, src, src_stride, w, h); } static NOINLINE void put_etap_scaled_c(pixel *dst, const ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy, const int filter_type HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; int tmp_h = (((h - 1) * dy + my) >> 10) + 8; int16_t mid[128 * (256 + 7)], *mid_ptr = mid; src_stride = PXSTRIDE(src_stride); src -= src_stride * 3; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { GET_H_FILTER(imx >> 6); mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1, 6 - intermediate_bits) : src[ioff] << intermediate_bits; imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; for (int y = 0; y < h; y++) { int x; GET_V_FILTER(my >> 6); for (x = 0; x < w; x++) dst[x] = fv ? DAV1D_FILTER_8TAP_CLIP(mid_ptr, x, fv, 128, 6 + intermediate_bits) : iclip_pixel((mid_ptr[x] + intermediate_rnd) >> intermediate_bits); my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; dst += PXSTRIDE(dst_stride); } } static NOINLINE void prep_etap_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my, const int filter_type HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); GET_FILTERS(); src_stride = PXSTRIDE(src_stride); if (fh) { if (fv) { int tmp_h = h + 7; int16_t mid[128 * 135], *mid_ptr = mid; src -= src_stride * 3; do { for (int x = 0; x < w; x++) mid_ptr[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; do { for (int x = 0; x < w; x++) { int t = DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6) - PREP_BIAS; assert(t >= INT16_MIN && t <= INT16_MAX); tmp[x] = t; } mid_ptr += 128; tmp += w; } while (--h); } else { do { for (int x = 0; x < w; x++) tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fh, 1, 6 - intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h); } } else if (fv) { do { for (int x = 0; x < w; x++) tmp[x] = DAV1D_FILTER_8TAP_RND(src, x, fv, src_stride, 6 - intermediate_bits) - PREP_BIAS; tmp += w; src += src_stride; } while (--h); } else prep_c(tmp, src, src_stride, w, h HIGHBD_TAIL_SUFFIX); } static NOINLINE void prep_etap_scaled_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy, const int filter_type HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); int tmp_h = (((h - 1) * dy + my) >> 10) + 8; int16_t mid[128 * (256 + 7)], *mid_ptr = mid; src_stride = PXSTRIDE(src_stride); src -= src_stride * 3; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { GET_H_FILTER(imx >> 6); mid_ptr[x] = fh ? DAV1D_FILTER_8TAP_RND(src, ioff, fh, 1, 6 - intermediate_bits) : src[ioff] << intermediate_bits; imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid + 128 * 3; for (int y = 0; y < h; y++) { int x; GET_V_FILTER(my >> 6); for (x = 0; x < w; x++) tmp[x] = (fv ? DAV1D_FILTER_8TAP_RND(mid_ptr, x, fv, 128, 6) : mid_ptr[x]) - PREP_BIAS; my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; tmp += w; } } #define filter_fns(type, type_h, type_v) \ static void put_etap_##type##_c(pixel *const dst, \ const ptrdiff_t dst_stride, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my \ HIGHBD_DECL_SUFFIX) \ { \ put_etap_c(dst, dst_stride, src, src_stride, w, h, mx, my, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \ } \ static void put_etap_##type##_scaled_c(pixel *const dst, \ const ptrdiff_t dst_stride, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my, \ const int dx, const int dy \ HIGHBD_DECL_SUFFIX) \ { \ put_etap_scaled_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \ } \ static void prep_etap_##type##_c(int16_t *const tmp, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my \ HIGHBD_DECL_SUFFIX) \ { \ prep_etap_c(tmp, src, src_stride, w, h, mx, my, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \ } \ static void prep_etap_##type##_scaled_c(int16_t *const tmp, \ const pixel *const src, \ const ptrdiff_t src_stride, \ const int w, const int h, \ const int mx, const int my, \ const int dx, const int dy \ HIGHBD_DECL_SUFFIX) \ { \ prep_etap_scaled_c(tmp, src, src_stride, w, h, mx, my, dx, dy, \ type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \ } filter_fns(regular, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_REGULAR) filter_fns(regular_sharp, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SHARP) filter_fns(regular_smooth, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SMOOTH) filter_fns(smooth, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SMOOTH) filter_fns(smooth_regular, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_REGULAR) filter_fns(smooth_sharp, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SHARP) filter_fns(sharp, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SHARP) filter_fns(sharp_regular, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_REGULAR) filter_fns(sharp_smooth, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SMOOTH) #define FILTER_BILIN(src, x, mxy, stride) \ (16 * src[x] + ((mxy) * (src[x + stride] - src[x]))) #define FILTER_BILIN_RND(src, x, mxy, stride, sh) \ ((FILTER_BILIN(src, x, mxy, stride) + ((1 << (sh)) >> 1)) >> (sh)) #define FILTER_BILIN_CLIP(src, x, mxy, stride, sh) \ iclip_pixel(FILTER_BILIN_RND(src, x, mxy, stride, sh)) static void put_bilin_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); const int intermediate_rnd = (1 << intermediate_bits) >> 1; dst_stride = PXSTRIDE(dst_stride); src_stride = PXSTRIDE(src_stride); if (mx) { if (my) { int16_t mid[128 * 129], *mid_ptr = mid; int tmp_h = h + 1; do { for (int x = 0; x < w; x++) mid_ptr[x] = FILTER_BILIN_RND(src, x, mx, 1, 4 - intermediate_bits); mid_ptr += 128; src += src_stride; } while (--tmp_h); mid_ptr = mid; do { for (int x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my, 128, 4 + intermediate_bits); mid_ptr += 128; dst += dst_stride; } while (--h); } else { do { for (int x = 0; x < w; x++) { const int px = FILTER_BILIN_RND(src, x, mx, 1, 4 - intermediate_bits); dst[x] = iclip_pixel((px + intermediate_rnd) >> intermediate_bits); } dst += dst_stride; src += src_stride; } while (--h); } } else if (my) { do { for (int x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(src, x, my, src_stride, 4); dst += dst_stride; src += src_stride; } while (--h); } else put_c(dst, dst_stride, src, src_stride, w, h); } static void put_bilin_scaled_c(pixel *dst, ptrdiff_t dst_stride, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, int my, const int dx, const int dy HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); int tmp_h = (((h - 1) * dy + my) >> 10) + 2; int16_t mid[128 * (256 + 1)], *mid_ptr = mid; do { int x; int imx = mx, ioff = 0; for (x = 0; x < w; x++) { mid_ptr[x] = FILTER_BILIN_RND(src, ioff, imx >> 6, 1, 4 - intermediate_bits); imx += dx; ioff += imx >> 10; imx &= 0x3ff; } mid_ptr += 128; src += PXSTRIDE(src_stride); } while (--tmp_h); mid_ptr = mid; do { int x; for (x = 0; x < w; x++) dst[x] = FILTER_BILIN_CLIP(mid_ptr, x, my >> 6, 128, 4 + intermediate_bits); my += dy; mid_ptr += (my >> 10) * 128; my &= 0x3ff; dst += PXSTRIDE(dst_stride); } while (--h); } static void prep_bilin_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride, const int w, int h, const int mx, const int my HIGHBD_DECL_SUFFIX) { const int intermediate_bits = get_intermediate_bits(bitdepth_max); src_stride = PXSTRIDE(src_stride); if (mx) { if (my) { int16_t mid[128 * 129], *mid_ptr = mid; int tmp_h = h + 1;