38#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
44#if ARCH_AARCH64 && HAVE_NEON
46#elif ARCH_X86_64 && HAVE_X86ASM
50#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
103 for (
int i = 0;
i < 4;
i++) {
114 for (
int i = 0;
i < 4;
i++) {
115 const int src = swiz->
in[
i];
126 for (
int i = 0;
i < 4;
i++) {
136 switch (
op->rw.mode) {
170 for (
int i = 0;
i < 4;
i++)
178 for (
int i = 0;
i < 4;
i++)
186 for (
int i = 0;
i < 4;
i++) {
192 for (
int i = 0;
i < 4;
i++) {
201 for (
int i = 0;
i < 4;
i++) {
203 x[
i] =
op->clear.value[
i];
209 for (
int i = 0;
i < 4;
i++)
215 for (
int i = 0;
i < 4;
i++)
216 x[
i] = x[
i].den ?
Q((x[
i].
num / x[
i].den) >>
op->shift.amount) : x[
i];
220 const AVRational64 orig[4] = { x[0], x[1], x[2], x[3] };
221 for (
int i = 0;
i < 4;
i++)
222 x[
i] = orig[
op->swizzle.in[
i]];
227 for (
int i = 0;
i < 4;
i++)
228 x[
i] = x[
i].den ?
Q(x[
i].
num / x[
i].den) : x[
i];
233 for (
int i = 0;
i < 4;
i++) {
234 if (
op->dither.y_offset[
i] >= 0 && x[
i].
den)
239 for (
int i = 0;
i < 4;
i++)
243 for (
int i = 0;
i < 4;
i++)
247 const AVRational64 orig[4] = { x[0], x[1], x[2], x[3] };
248 for (
int i = 0;
i < 4;
i++) {
250 for (
int j = 0; j < 4; j++)
257 for (
int i = 0;
i < 4;
i++)
267 for (
int i = 0;
i < 3;
i++)
287 return ((
a &
b) & flags_and) | ((
a |
b) & flags_or);
295 for (
int i = 0;
i < 4;
i++) {
317 for (
int n = 0; n < ops->
num_ops; n++) {
330 memcpy(
op->comps.min, prev.
min,
sizeof(prev.
min));
331 memcpy(
op->comps.max, prev.
max,
sizeof(prev.
max));
337 for (
int i = 0;
i < 4;
i++) {
342 #define FORWARD(I, J, EXPR) do { \
343 SwsCompFlags flags = prev.flags[J]; \
344 op->comps.flags[I] = merge_comp_flags(op->comps.flags[I], (EXPR)); \
345 op->comps.dep_in[I] |= prev.dep_in[J]; \
348 #define RESET(I) do { \
349 op->comps.flags[I] = SWS_COMP_GARBAGE; \
350 op->comps.min[I] = op->comps.max[I] = (AVRational64) {0}; \
351 op->comps.dep_in[I] = SWS_COMP_NONE; \
358 for (
int i = 0;
i <
op->rw.elems;
i++) {
360 switch (
op->rw.mode) {
383 if (
op->rw.filter.op) {
389 for (
int i = 0;
i < 4;
i++) {
391 op->comps.min[
i] = prev.
min[
i];
392 op->comps.max[
i] = prev.
max[
i];
396 for (
int i = 0;
i <
op->rw.elems;
i++)
398 for (
int i = 0;
i < 4;
i++)
403 for (
int i = 0;
i < 4;
i++)
409 for (
int i = 0;
i < 4;
i++) {
411 if (
op->clamp.limit[
i].den)
419 for (
int i = 0;
i < 4;
i++) {
421 op->comps.min[
i] = prev.
min[
i];
422 op->comps.max[
i] = prev.
max[
i];
423 if (
op->dither.y_offset[
i] < 0)
432 for (
int i = 0;
i < 4;
i++) {
433 const int pattern =
op->pack.pattern[
i];
437 op->comps.min[
i] =
Q(0);
438 op->comps.max[
i] =
Q((1ULL << pattern) - 1);
444 for (
int i = 0;
i < 4;
i++) {
445 if (
op->pack.pattern[
i])
452 for (
int i = 0;
i < 4;
i++) {
455 if (
op->clear.value[
i].num == 0)
457 if (
op->clear.value[
i].den == 1)
465 for (
int i = 0;
i < 4;
i++)
469 for (
int i = 0;
i < 4;
i++) {
478 for (
int i = 0;
i < 4;
i++) {
481 for (
int j = 0; j < 4; j++) {
498 if (
op->lin.m[
i][4].num) {
500 if (
op->lin.m[
i][4].den != 1)
510 for (
int i = 0;
i < 4;
i++) {
512 if (
op->scale.factor.den != 1)
514 if (
op->scale.factor.num < 0)
524 for (
int i = 0;
i < 3;
i++) {
527 for (
int j = 0; j < 3; j++)
530 op->comps.min[
i] =
Q(0);
531 op->comps.max[
i] =
Q(UINT16_MAX);
535 op->comps.min[3] = prev.
min[3];
536 op->comps.max[3] = prev.
max[3];
549 for (
int n = ops->
num_ops - 1; n >= 0; n--) {
553 for (
int i = 0;
i < 4;
i++) {
554 op->comps.dep_out[
i] = need_out[
i];
562 for (
int i = 0;
i <
op->rw.elems;
i++)
564 for (
int i =
op->rw.elems;
i < 4;
i++)
565 need_in[
i] = need_out[
i];
577 for (
int i = 0;
i < 4;
i++)
578 need_in[
i] = need_out[
i];
581 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++)
582 need_in[0] |= need_out[
i];
585 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++)
586 need_in[
i] = need_out[0];
589 for (
int i = 0;
i < 4;
i++) {
591 need_in[
i] = need_out[
i];
595 for (
int i = 0;
i < 4;
i++)
596 need_in[
op->swizzle.in[
i]] |= need_out[
i];
599 for (
int i = 0;
i < 4;
i++) {
600 for (
int j = 0; j < 4; j++) {
601 if (
op->lin.m[
i][j].num)
602 need_in[j] |= need_out[
i];
607 for (
int i = 0;
i < 3;
i++)
608 need_in[
i] = need_out[0] | need_out[1] | need_out[2];
609 need_in[3] = need_out[3];
613 memcpy(need_out, need_in,
sizeof(need_in));
647 for (
int i = 0;
i < 4;
i++)
685 for (
int i = 0;
i <
copy->num_ops;
i++) {
689 if (
op->rw.filter.kernel)
728 const int end = ops->
num_ops - count;
730 for (
int i = 0;
i < count;
i++)
778 for (
int i = 0;
i < num_planes;
i++) {
800 for (
int i = 0;
i < 4;
i++) {
801 for (
int j = 0; j < 5; j++) {
830 for (
int i = 0;
i < 4;
i++) {
842 }
else if (q.
den == 1) {
844 }
else if (q.
num > 1000 || q.
num < -1000 || q.
den > 1000 || q.
den < -1000) {
854 for (
int i = 0;
i < 4;
i++) {
887 if (!
op->rw.filter.op)
903 op->pack.pattern[0],
op->pack.pattern[1],
904 op->pack.pattern[2],
op->pack.pattern[3]);
912 op->swizzle.x,
op->swizzle.y,
op->swizzle.z,
op->swizzle.w);
921 1 <<
op->dither.size_log2, 1 <<
op->dither.size_log2,
922 op->dither.y_offset[0],
op->dither.y_offset[1],
923 op->dither.y_offset[2],
op->dither.y_offset[3]);
936 for (
int i = 0;
i < 4;
i++) {
938 for (
int j = 0; j < 5; j++) {
948 if (
op->scale.factor.den != 1)
960 av_bprintf(bp,
"%-20s: %s",
name,
op->lut3d.dynamic ?
"dynamic" :
"static");
970 for (
int i = 0;
i < nb_planes;
i++)
971 inorder &= order[
i] ==
i;
976 for (
int i = 0;
i < nb_planes;
i++)
1017 if (range_mask &
mask) {
1024 av_log(log, lev_extra,
"%s\n", bp.str);
1027 bool has_deps =
false;
1028 for (
int i = 0;
i < 4;
i++)
1029 has_deps |=
op->comps.dep_in[
i] ||
op->comps.dep_out[
i];
1037 av_log(log, lev_extra,
"%s\n", bp.str);
1042 av_log(log,
lev,
" ('X' unused, 'z' byteswapped, '=' copied, '$' const, '+' integer, '0' zero)\n");
const SwsOpBackend backend_aarch64
static double val(void *priv, double ch)
static double bound(const double threshold, const double val)
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
#define AV_BPRINT_SIZE_AUTOMATIC
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static LevelCodes lev[4+3+3]
AVRational64 ff_mul_q64(AVRational64 b, AVRational64 c)
Multiply two 64-bit rationals.
static AVRational64 ff_make_q64(int64_t num, int64_t den)
Create an AVRational64.
static double ff_q2d_64(AVRational64 a)
Convert an AVRational64 to a double.
AVRational64 ff_add_q64(AVRational64 b, AVRational64 c)
Add two 64-bit rationals.
int ff_cmp_q64(AVRational64 a, AVRational64 b)
Compare two 64-bit rationals.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
static const int weights[]
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
static int shift(int a, int b)
static int16_t mult(Float11 *f1, Float11 *f2)
Macro definitions for various function/variable attributes.
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
static const struct @257111027162314367033347246032313251342043035002 planes[]
static const uint16_t mask[17]
#define FFSWAP(type, a, b)
Memory handling functions.
int ff_sws_op_list_max_size(const SwsOpList *ops)
Returns the size of the largest pixel type used in ops.
void ff_sws_op_list_update_comps(SwsOpList *ops)
Infer + propagate known information about components.
void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op)
Describe an operation in human-readable form.
const SwsOpBackend backend_c
Copyright (C) 2025 Niklas Haas.
uint32_t ff_sws_linear_mask(const SwsLinearOp *c)
static void print_q4(AVBPrint *bp, const AVRational64 q4[4], SwsCompMask mask)
static void desc_plane_order(AVBPrint *bp, int nb_planes, const uint8_t *order)
static void print_deps(AVBPrint *bp, const SwsCompMask *deps)
int ff_sws_op_list_insert_at(SwsOpList *ops, int index, SwsOp *op)
const SwsOpBackend backend_x86
static void op_uninit(SwsOp *op)
const SwsOp * ff_sws_op_list_input(const SwsOpList *ops)
Returns the input operation for a given op list, or NULL if there is none (e.g.
void ff_sws_op_list_free(SwsOpList **p_ops)
const SwsOpBackend *const ff_sws_op_backends[]
static AVRational64 av_min_q64(AVRational64 a, AVRational64 b)
const SwsOpBackend backend_murder
int ff_sws_op_list_append(SwsOpList *ops, SwsOp *op)
These will take over ownership of op and set it to {0}, even on failure.
void ff_sws_comp_mask_swizzle(SwsCompMask *mask, const SwsSwizzleOp *swiz)
SwsOpList * ff_sws_op_list_alloc(void)
#define FORWARD(I, J, EXPR)
const char * ff_sws_op_type_name(SwsOpType op)
static AVRational64 av_max_q64(AVRational64 a, AVRational64 b)
static char describe_comp_flags(SwsCompFlags flags)
SwsCompMask ff_sws_comp_mask_needed(const SwsOp *op)
const char * ff_sws_pixel_type_name(SwsPixelType type)
static SwsCompFlags merge_comp_flags(SwsCompFlags a, SwsCompFlags b)
SwsCompMask ff_sws_comp_mask_q4(const AVRational64 q[4])
int ff_sws_rw_op_planes(const SwsOp *op)
Return the number of planes involved in a read/write operation.
const SwsOp * ff_sws_op_list_output(const SwsOpList *ops)
Returns the output operation for a given op list, or NULL if there is none.
bool ff_sws_op_list_is_noop(const SwsOpList *ops)
Returns whether an op list represents a true no-op operation, i.e.
void ff_sws_op_list_print(void *log, int lev, int lev_extra, const SwsOpList *ops)
Print out the contents of an operation list.
static const char *const rw_mode_names[]
void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
Apply an operation to an AVRational64.
void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count)
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
static void apply_filter_weights(SwsComps *comps, const SwsComps *prev, const SwsFilterWeights *weights)
SwsOpType
Copyright (C) 2025 Niklas Haas.
@ SWS_RW_PLANAR
Note: 1-component reads are either SWS_RW_PLANAR or SWS_RW_PACKED, depending on the underlying interp...
#define SWS_OP_NEEDED(op, idx)
static void ff_sws_pack_op_decode(const SwsOp *op, uint64_t mask[4], int shift[4])
Utilities for rational number calculation.
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
const void * av_refstruct_ref_c(const void *obj)
Analog of av_refstruct_ref(), but for constant objects.
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
64-bit Rational number (pair of numerator and denominator).
Represents a computed filter kernel.
int src_size
Copy of the parameters used to generate this filter, for reference.
char name[16]
Extra metadata about the filter, used to inform the optimizer / range tracker about the filter's beha...
int filter_size
The number of source texels to convolve over for each row.
Helper struct for representing a list of operations.
SwsComps comps_src
Source component metadata associated with pixel values from each corresponding component (in plane/me...
SwsReadWriteMode mode
Examples: rgba = 4x u8 packed yuv444p = 3x u8 rgb565 = 1x u16 <- use SWS_OP_UNPACK to unpack monow = ...
struct SwsReadWriteOp::@312356277033155231251141106170064356360153154105 filter
Filter kernel to apply to each plane while sampling.
#define ff_sws_comp_mask_str(mask)
#define SWS_COMP_TEST(mask, X)
static av_const bool ff_sws_pixel_type_is_int(SwsPixelType type)
uint8_t SwsCompMask
Bit-mask of components.
static av_const int ff_sws_pixel_type_size(SwsPixelType type)
static void copy(const float *p1, float *p2, const int length)