| /** |
| * Copyright (C) 2025 Niklas Haas |
| * |
| * This file is part of FFmpeg. |
| * |
| * FFmpeg is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * FFmpeg is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with FFmpeg; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include "ops_backend.h" |
| |
| #ifndef BIT_DEPTH |
| # error Should only be included from ops_tmpl_*.c! |
| #endif |
| |
| #define WRAP_CONVERT_UINT(N) \ |
| DECL_PATTERN(convert_uint##N) \ |
| { \ |
| u##N##block_t xu, yu, zu, wu; \ |
| \ |
| SWS_LOOP \ |
| for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \ |
| if (X) \ |
| xu[i] = x[i]; \ |
| if (Y) \ |
| yu[i] = y[i]; \ |
| if (Z) \ |
| zu[i] = z[i]; \ |
| if (W) \ |
| wu[i] = w[i]; \ |
| } \ |
| \ |
| CONTINUE(u##N##block_t, xu, yu, zu, wu); \ |
| } \ |
| \ |
| WRAP_COMMON_PATTERNS(convert_uint##N, \ |
| .op = SWS_OP_CONVERT, \ |
| .convert.to = SWS_PIXEL_U##N, \ |
| ); |
| |
| #if BIT_DEPTH != 8 |
| WRAP_CONVERT_UINT(8) |
| #endif |
| |
| #if BIT_DEPTH != 16 |
| WRAP_CONVERT_UINT(16) |
| #endif |
| |
| #if BIT_DEPTH != 32 || defined(IS_FLOAT) |
| WRAP_CONVERT_UINT(32) |
| #endif |
| |
| DECL_PATTERN(clear) |
| { |
| SWS_LOOP |
| for (int i = 0; i < SWS_BLOCK_SIZE; i++) { |
| if (!X) |
| x[i] = impl->priv.px[0]; |
| if (!Y) |
| y[i] = impl->priv.px[1]; |
| if (!Z) |
| z[i] = impl->priv.px[2]; |
| if (!W) |
| w[i] = impl->priv.px[3]; |
| } |
| |
| CONTINUE(block_t, x, y, z, w); |
| } |
| |
| #define WRAP_CLEAR(X, Y, Z, W) \ |
| DECL_IMPL(clear##_##X##Y##Z##W) \ |
| { \ |
| CALL(clear, X, Y, Z, W); \ |
| } \ |
| \ |
| DECL_ENTRY(clear##_##X##Y##Z##W, \ |
| .setup = ff_sws_setup_q4, \ |
| .op = SWS_OP_CLEAR, \ |
| .flexible = true, \ |
| .unused = { !X, !Y, !Z, !W }, \ |
| ); |
| |
| WRAP_CLEAR(1, 1, 1, 0) /* rgba alpha */ |
| WRAP_CLEAR(0, 1, 1, 1) /* argb alpha */ |
| |
| WRAP_CLEAR(0, 0, 1, 1) /* vuya chroma */ |
| WRAP_CLEAR(1, 0, 0, 1) /* yuva chroma */ |
| WRAP_CLEAR(1, 1, 0, 0) /* ayuv chroma */ |
| WRAP_CLEAR(0, 1, 0, 1) /* uyva chroma */ |
| WRAP_CLEAR(1, 0, 1, 0) /* xvyu chroma */ |
| |
| WRAP_CLEAR(1, 0, 0, 0) /* gray -> yuva */ |
| WRAP_CLEAR(0, 1, 0, 0) /* gray -> ayuv */ |
| WRAP_CLEAR(0, 0, 1, 0) /* gray -> vuya */ |
| |
| DECL_PATTERN(min) |
| { |
| SWS_LOOP |
| for (int i = 0; i < SWS_BLOCK_SIZE; i++) { |
| if (X) |
| x[i] = FFMIN(x[i], impl->priv.px[0]); |
| if (Y) |
| y[i] = FFMIN(y[i], impl->priv.px[1]); |
| if (Z) |
| z[i] = FFMIN(z[i], impl->priv.px[2]); |
| if (W) |
| w[i] = FFMIN(w[i], impl->priv.px[3]); |
| } |
| |
| CONTINUE(block_t, x, y, z, w); |
| } |
| |
| DECL_PATTERN(max) |
| { |
| SWS_LOOP |
| for (int i = 0; i < SWS_BLOCK_SIZE; i++) { |
| if (X) |
| x[i] = FFMAX(x[i], impl->priv.px[0]); |
| if (Y) |
| y[i] = FFMAX(y[i], impl->priv.px[1]); |
| if (Z) |
| z[i] = FFMAX(z[i], impl->priv.px[2]); |
| if (W) |
| w[i] = FFMAX(w[i], impl->priv.px[3]); |
| } |
| |
| CONTINUE(block_t, x, y, z, w); |
| } |
| |
| WRAP_COMMON_PATTERNS(min, |
| .op = SWS_OP_MIN, |
| .setup = ff_sws_setup_q4, |
| .flexible = true, |
| ); |
| |
| WRAP_COMMON_PATTERNS(max, |
| .op = SWS_OP_MAX, |
| .setup = ff_sws_setup_q4, |
| .flexible = true, |
| ); |
| |
| DECL_PATTERN(scale) |
| { |
| const pixel_t scale = impl->priv.px[0]; |
| |
| SWS_LOOP |
| for (int i = 0; i < SWS_BLOCK_SIZE; i++) { |
| if (X) |
| x[i] *= scale; |
| if (Y) |
| y[i] *= scale; |
| if (Z) |
| z[i] *= scale; |
| if (W) |
| w[i] *= scale; |
| } |
| |
| CONTINUE(block_t, x, y, z, w); |
| } |
| |
| WRAP_COMMON_PATTERNS(scale, |
| .op = SWS_OP_SCALE, |
| .setup = ff_sws_setup_q, |
| .flexible = true, |
| ); |