/* * 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 */ #ifndef SWSCALE_OPS_H #define SWSCALE_OPS_H #include #include "utils.h" enum { SWS_CHUNK_SIZE = 32, }; /** * Represents a view into a single field of frame data. */ typedef struct SwsImg { enum AVPixelFormat fmt; uint8_t *data[4]; /* points to y=0 */ int linesize[4]; } SwsImg; typedef enum SwsOpType { SWS_OP_INVALID = 0, /* Input/output handling */ SWS_OP_READ_BYTES, /* gather bytes from planes */ SWS_OP_WRITE_BYTES, /* write bytes to planes */ SWS_OP_SWAP_BYTES, /* swap byte order */ SWS_OP_SWIZZLE, /* change channel order */ SWS_OP_EXPAND, /* bring into standard range for processing */ SWS_OP_COMPRESS, /* inverse of expand */ /* Look-up tables */ SWS_OP_LUT_1D, /* Y := lut[Y] (luma only) */ SWS_OP_LUT_3X1D, /* x,y,z := lut[x,y,z] (per channel) */ SWS_OP_LUT_1X2_Y_SAT, /* Y := lut[Y].x, CbCr *= lut[Y].y */ SWS_OP_LUT_3D, /* xyz := lut[z][y][x] */ } SwsOpType; typedef struct SwsRWBytesOp { int comps; /* number of components */ int bytes; /* bytes per component */ bool planar; /* data is planar (for comps > 1) */ bool be; /* big endian (for bytes > 1) */ } SwsRWBytesOp; typedef struct SwsSwizzleOp { /* Input component for each output component: * Output[x] := Input[swizzle.x] */ union { uint8_t mask; struct { unsigned x : 2; unsigned y : 2; unsigned z : 2; unsigned w : 2; }; }; } SwsSwizzleOp; #define SWS_SWIZZLE(X,Y,Z,W) (SwsSwizzleOp) {.x = X, .y = Y, .z = Z, .w = W} #define SWS_TO_RGBA SWS_SWIZZLE(0, 1, 2, 3) #define SWS_TO_ARGB SWS_SWIZZLE(3, 0, 1, 2) #define SWS_TO_BGRA SWS_SWIZZLE(2, 1, 0, 3) #define SWS_TO_ABGR SWS_SWIZZLE(3, 2, 1, 0) #define SWS_TO_GBRA SWS_SWIZZLE(1, 2, 0, 3) #define SWS_FROM_ARGB SWS_SWIZZLE(1, 2, 3, 0) #define SWS_FROM_GBRA SWS_SWIZZLE(2, 0, 1, 3) #define SWS_FROM_RGBA SWS_TO_RGBA #define SWS_FROM_BGRA SWS_TO_BGRA #define SWS_FROM_ABGR SWS_TO_ABGR typedef struct SwsExpandOp { int depth; /* number of significant bits */ bool msb; /* if true, data is packed into the msb */ /* Mask of components to treat as full range */ struct { uint8_t mask; struct { unsigned luma : 1; unsigned chroma : 1; }; } full; } SwsExpandOp; typedef struct SwsCompressOp { int depth; bool msb; } SwsCompressOp; typedef struct SwsLut1x1Op { const uint16_t *lut; int lut_size_log2; } SwsLut1x1Op; typedef struct SwsLut1x2Op { const v2u16_t *lut; int lut_size_log2; } SwsLut1x2Op; typedef struct SwsLut3x3Op { const v3u16_t *lut; int lut_size_log2[3]; bool tetrahedral; /* use tetrahedral instead of trilinear interpolation */ } SwsLut3x3Op; typedef struct SwsOp { SwsOpType type; union { SwsRWBytesOp rw_bytes; SwsSwizzleOp swizzle; SwsExpandOp expand; SwsCompressOp compress; SwsLut1x1Op lut1x1; SwsLut1x2Op lut1x2; SwsLut3x3Op lut3x3; }; } SwsOp; typedef struct SwsCompiledFunc { void (*process)(const SwsImg *out, const SwsImg *in, int y, int h, const void *priv); /* Optional private state and associated free() function */ void (*free)(void *priv); void *priv; } SwsCompiledFunc; static inline void ff_sws_compiled_func_free(SwsCompiledFunc *func) { if (func->free) func->free(func->priv); *func = (SwsCompiledFunc) {0}; } enum SwsOpFlags { SWS_OP_HBD = 1 << 0, /* Force the use of higher internal precision */ }; /** * Resolves a sequence of operations to a callable function pointer. The first * and last operations must be a read/write respectively. * * If there are any post-processing operations (e.g. LUT lookups, matrix * multiplications, and the like), data must be decoded before the first * such operation. * * `out_func` will contain direct references to any provided look-up tables * (SWS_OP_LUT_*), so their lifetime must exceed the lifetime of functions * using them. Changing the LUT contents will affect the output. * * Returns 0 or a negative error code. */ int ff_sws_op_compile(void *logctx, const SwsOp *ops, int num_ops, int flags, SwsCompiledFunc *out_func); #endif