FFmpeg
uops_tmpl.c
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2026 Niklas Haas
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <libavutil/bswap.h>
22 
23 #include "uops_tmpl.h"
24 
25 #ifndef BIT_DEPTH
26 # define BIT_DEPTH 8
27 #endif
28 
29 #if IS_FLOAT && BIT_DEPTH == 32
30 # define PIXEL_TYPE SWS_PIXEL_F32
31 # define pixel_t float
32 # define inter_t float
33 # define vec3_t v3f32_t
34 # define PX F32
35 # define px f32
36 #elif BIT_DEPTH == 32
37 # define PIXEL_MAX 0xFFFFFFFFu
38 # define PIXEL_SWAP av_bswap32
39 # define pixel_t uint32_t
40 # define inter_t int64_t
41 # define PX U32
42 # define px u32
43 #elif BIT_DEPTH == 16
44 # define PIXEL_MAX 0xFFFFu
45 # define PIXEL_SWAP av_bswap16
46 # define pixel_t uint16_t
47 # define inter_t int64_t
48 # define PX U16
49 # define px u16
50 #elif BIT_DEPTH == 8
51 # define PIXEL_MAX 0xFFu
52 # define pixel_t uint8_t
53 # define inter_t int32_t
54 # define PX U8
55 # define px u8
56 #else
57 # error Invalid BIT_DEPTH
58 #endif
59 
60 /*********************************
61  * Generic read/write operations *
62  *********************************/
63 
64 DECL_READ(read_planar, const SwsCompMask mask)
65 {
66  SWS_LOOP
67  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
68  if (X) x[i] = in0[i];
69  if (Y) y[i] = in1[i];
70  if (Z) z[i] = in2[i];
71  if (W) w[i] = in3[i];
72  }
73 
74  if (X) iter->in[0] += SIZEOF_BLOCK;
75  if (Y) iter->in[1] += SIZEOF_BLOCK;
76  if (Z) iter->in[2] += SIZEOF_BLOCK;
77  if (W) iter->in[3] += SIZEOF_BLOCK;
78 
79  CONTINUE(x, y, z, w);
80 }
81 
82 DECL_READ(read_packed, const SwsCompMask mask)
83 {
84  const int elems = W ? 4 : Z ? 3 : Y ? 2 : 1;
85 
86  SWS_LOOP
87  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
88  if (X) x[i] = in0[elems * i + 0];
89  if (Y) y[i] = in0[elems * i + 1];
90  if (Z) z[i] = in0[elems * i + 2];
91  if (W) w[i] = in0[elems * i + 3];
92  }
93 
94  iter->in[0] += SIZEOF_BLOCK * elems;
95  CONTINUE(x, y, z, w);
96 }
97 
98 DECL_WRITE(write_planar, const SwsCompMask mask)
99 {
100  SWS_LOOP
101  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
102  if (X) out0[i] = x[i];
103  if (Y) out1[i] = y[i];
104  if (Z) out2[i] = z[i];
105  if (W) out3[i] = w[i];
106  }
107 
108  if (X) iter->out[0] += SIZEOF_BLOCK;
109  if (Y) iter->out[1] += SIZEOF_BLOCK;
110  if (Z) iter->out[2] += SIZEOF_BLOCK;
111  if (W) iter->out[3] += SIZEOF_BLOCK;
112 }
113 
114 DECL_WRITE(write_packed, const SwsCompMask mask)
115 {
116  const int elems = W ? 4 : Z ? 3 : Y ? 2 : 1;
117 
118  SWS_LOOP
119  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
120  if (X) out0[elems * i + 0] = x[i];
121  if (Y) out0[elems * i + 1] = y[i];
122  if (Z) out0[elems * i + 2] = z[i];
123  if (W) out0[elems * i + 3] = w[i];
124  }
125 
126  iter->out[0] += SIZEOF_BLOCK * elems;
127 }
128 
129 #if BIT_DEPTH == 8
130 
132 {
134 
135  SWS_LOOP
136  for (int i = 0; i < SWS_BLOCK_SIZE; i += 8) {
137  const pixel_t val = ((const pixel_t *) in0)[i >> 3];
138  x[i + 0] = (val >> 7) & 1;
139  x[i + 1] = (val >> 6) & 1;
140  x[i + 2] = (val >> 5) & 1;
141  x[i + 3] = (val >> 4) & 1;
142  x[i + 4] = (val >> 3) & 1;
143  x[i + 5] = (val >> 2) & 1;
144  x[i + 6] = (val >> 1) & 1;
145  x[i + 7] = (val >> 0) & 1;
146  }
147 
148  iter->in[0] += SIZEOF_BLOCK >> 3;
149  CONTINUE(x, y, z, w);
150 }
151 
152 DECL_READ(read_nibble, const SwsCompMask mask)
153 {
155 
156  SWS_LOOP
157  for (int i = 0; i < SWS_BLOCK_SIZE; i += 2) {
158  const pixel_t val = in0[i >> 1];
159  x[i + 0] = val >> 4; /* high nibble */
160  x[i + 1] = val & 0xF; /* low nibble */
161  }
162 
163  iter->in[0] += SIZEOF_BLOCK >> 1;
164  CONTINUE(x, y, z, w);
165 }
166 
167 DECL_READ(read_palette, const SwsCompMask mask)
168 {
170 
171  SWS_LOOP
172  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
173  const pixel_t index = in0[i];
174  const pixel_t *value = &in1[index * 4];
175  x[i] = value[0];
176  y[i] = value[1];
177  z[i] = value[2];
178  w[i] = value[3];
179  }
180 
181  iter->in[0] += SIZEOF_BLOCK;
182  CONTINUE(x, y, z, w);
183 }
184 
185 DECL_WRITE(write_bit, const SwsCompMask mask)
186 {
188 
189  SWS_LOOP
190  for (int i = 0; i < SWS_BLOCK_SIZE; i += 8) {
191  out0[i >> 3] = x[i + 0] << 7 |
192  x[i + 1] << 6 |
193  x[i + 2] << 5 |
194  x[i + 3] << 4 |
195  x[i + 4] << 3 |
196  x[i + 5] << 2 |
197  x[i + 6] << 1 |
198  x[i + 7];
199  }
200 
201  iter->out[0] += SIZEOF_BLOCK >> 3;
202 }
203 
204 DECL_WRITE(write_nibble, const SwsCompMask mask)
205 {
207 
208  SWS_LOOP
209  for (int i = 0; i < SWS_BLOCK_SIZE; i += 2)
210  out0[i >> 1] = x[i] << 4 | x[i + 1];
211 
212  iter->out[0] += SIZEOF_BLOCK >> 1;
213 }
214 
215 #endif /* BIT_DEPTH == 8 */
216 
217 SWS_FOR(PX, READ_PLANAR, DECL_IMPL_READ, read_planar)
218 SWS_FOR(PX, READ_PACKED, DECL_IMPL_READ, read_packed)
219 SWS_FOR(PX, READ_NIBBLE, DECL_IMPL_READ, read_nibble)
220 SWS_FOR(PX, READ_BIT, DECL_IMPL_READ, read_bit)
221 SWS_FOR(PX, READ_PALETTE, DECL_IMPL_READ, read_palette)
222 SWS_FOR(PX, WRITE_PLANAR, DECL_IMPL_WRITE, write_planar)
223 SWS_FOR(PX, WRITE_PACKED, DECL_IMPL_WRITE, write_packed)
224 SWS_FOR(PX, WRITE_NIBBLE, DECL_IMPL_WRITE, write_nibble)
225 SWS_FOR(PX, WRITE_BIT, DECL_IMPL_WRITE, write_bit)
226 
227 SWS_FOR_STRUCT(PX, READ_PLANAR, DECL_ENTRY)
228 SWS_FOR_STRUCT(PX, READ_PACKED, DECL_ENTRY)
229 SWS_FOR_STRUCT(PX, READ_NIBBLE, DECL_ENTRY)
230 SWS_FOR_STRUCT(PX, READ_BIT, DECL_ENTRY)
231 SWS_FOR_STRUCT(PX, READ_PALETTE, DECL_ENTRY)
232 SWS_FOR_STRUCT(PX, WRITE_PLANAR, DECL_ENTRY)
233 SWS_FOR_STRUCT(PX, WRITE_PACKED, DECL_ENTRY)
234 SWS_FOR_STRUCT(PX, WRITE_NIBBLE, DECL_ENTRY)
235 SWS_FOR_STRUCT(PX, WRITE_BIT, DECL_ENTRY)
236 
237 /*****************************
238  * Scaling / filtering reads *
239  *****************************/
240 
242 {
243  if (params->uop->par.filter.type != SWS_PIXEL_F32)
244  return AVERROR(ENOTSUP);
245 
246  const SwsFilterWeights *filter = params->uop->data.kernel;
247  static_assert(sizeof(out->priv.ptr) <= sizeof(int32_t[2]),
248  ">8 byte pointers not supported");
249 
250  /* Pre-convert weights to float */
251  float *weights = av_calloc(filter->num_weights, sizeof(float));
252  if (!weights)
253  return AVERROR(ENOMEM);
254 
255  for (int i = 0; i < filter->num_weights; i++)
256  weights[i] = (float) filter->weights[i] / SWS_FILTER_SCALE;
257 
258  out->priv.ptr = weights;
259  out->priv.i32[2] = filter->filter_size;
260  out->free = ff_op_priv_free;
261  return 0;
262 }
263 
264 /* Fully general vertical planar filter case */
265 DECL_READ(read_planar_fv, const SwsCompMask mask, const SwsPixelType type)
266 {
268  const SwsOpExec *exec = iter->exec;
269  const float *restrict weights = impl->priv.ptr;
270  const int filter_size = impl->priv.i32[2];
271  weights += filter_size * iter->y;
272 
273  block_t xs, ys, zs, ws;
274  if (X) memset(&xs.f32, 0, sizeof(xs.f32));
275  if (Y) memset(&ys.f32, 0, sizeof(ys.f32));
276  if (Z) memset(&zs.f32, 0, sizeof(zs.f32));
277  if (W) memset(&ws.f32, 0, sizeof(ws.f32));
278 
279  for (int j = 0; j < filter_size; j++) {
280  const float weight = weights[j];
281 
282  SWS_LOOP
283  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
284  if (X) xs.f32[i] += weight * in0[i];
285  if (Y) ys.f32[i] += weight * in1[i];
286  if (Z) zs.f32[i] += weight * in2[i];
287  if (W) ws.f32[i] += weight * in3[i];
288  }
289 
290  if (X) in0 = bump_ptr(in0, exec->in_stride[0]);
291  if (Y) in1 = bump_ptr(in1, exec->in_stride[1]);
292  if (Z) in2 = bump_ptr(in2, exec->in_stride[2]);
293  if (W) in3 = bump_ptr(in3, exec->in_stride[3]);
294  }
295 
296  if (X) iter->in[0] += SIZEOF_BLOCK;
297  if (Y) iter->in[1] += SIZEOF_BLOCK;
298  if (Z) iter->in[2] += SIZEOF_BLOCK;
299  if (W) iter->in[3] += SIZEOF_BLOCK;
300 
301  CONTINUE(&xs, &ys, &zs, &ws);
302 }
303 
305 {
306  if (params->uop->par.filter.type != SWS_PIXEL_F32)
307  return AVERROR(ENOTSUP);
308 
309  SwsFilterWeights *filter = params->uop->data.kernel;
310  out->priv.ptr = av_refstruct_ref(filter->weights);
311  out->priv.i32[2] = filter->filter_size;
312  out->free = ff_op_priv_unref;
313  return 0;
314 }
315 
316 /* Fully general horizontal planar filter case */
317 DECL_READ(read_planar_fh, const SwsCompMask mask, const SwsPixelType type)
318 {
320  const SwsOpExec *exec = iter->exec;
321  const int *restrict weights = impl->priv.ptr;
322  const int filter_size = impl->priv.i32[2];
323  const float scale = 1.0f / SWS_FILTER_SCALE;
324  const int xpos = iter->x;
325  weights += filter_size * iter->x;
326 
327  block_t xs, ys, zs, ws;
328  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
329  const int offset = exec->in_offset_x[xpos + i];
330  pixel_t *start0 = bump_ptr(in0, offset);
331  pixel_t *start1 = bump_ptr(in1, offset);
332  pixel_t *start2 = bump_ptr(in2, offset);
333  pixel_t *start3 = bump_ptr(in3, offset);
334 
335  inter_t sx = 0, sy = 0, sz = 0, sw = 0;
336  for (int j = 0; j < filter_size; j++) {
337  const int weight = weights[j];
338  if (X) sx += weight * start0[j];
339  if (Y) sy += weight * start1[j];
340  if (Z) sz += weight * start2[j];
341  if (W) sw += weight * start3[j];
342  }
343 
344  if (X) xs.f32[i] = (float) sx * scale;
345  if (Y) ys.f32[i] = (float) sy * scale;
346  if (Z) zs.f32[i] = (float) sz * scale;
347  if (W) ws.f32[i] = (float) sw * scale;
348 
349  weights += filter_size;
350  }
351 
352  CONTINUE(&xs, &ys, &zs, &ws);
353 }
354 
355 SWS_FOR(PX, READ_PLANAR_FV, DECL_IMPL_READ, read_planar_fv)
356 SWS_FOR(PX, READ_PLANAR_FH, DECL_IMPL_READ, read_planar_fh)
357 SWS_FOR_STRUCT(PX, READ_PLANAR_FV, DECL_ENTRY, .setup = fn(setup_filter_v) )
358 SWS_FOR_STRUCT(PX, READ_PLANAR_FH, DECL_ENTRY, .setup = fn(setup_filter_h) )
359 
360 /***************************
361  * Permutation and copying *
362  ***************************/
363 
364 DECL_FUNC(permute, const SwsCompMask mask, int num_moves,
365  int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5,
366  int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
367 {
368  const int8_t dst[SWS_UOP_MOVE_MAX] = { d0, d1, d2, d3, d4, d5 };
369  const int8_t src[SWS_UOP_MOVE_MAX] = { s0, s1, s2, s3, s4, s5 };
370 
371  pixel_t *ptr[5] = { NULL, x, y, z, w };
372  for (int n = 0; n < num_moves; n++)
373  ptr[dst[n] + 1] = ptr[src[n] + 1];
374 
375  /* The unneeded registers may still alias the used ones, so point them
376  * back at the stack to avoid collisions */
377  block_t xx, yy, zz, ww;
378  CONTINUE(X ? ptr[1] : xx.px,
379  Y ? ptr[2] : yy.px,
380  Z ? ptr[3] : zz.px,
381  W ? ptr[4] : ww.px);
382 }
383 
384 DECL_FUNC(copy, const SwsCompMask mask, int num_moves,
385  int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5,
386  int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
387 {
388  const size_t block_size = SWS_BLOCK_SIZE * sizeof(pixel_t);
389  const int8_t dst[SWS_UOP_MOVE_MAX] = { d0, d1, d2, d3, d4, d5 };
390  const int8_t src[SWS_UOP_MOVE_MAX] = { s0, s1, s2, s3, s4, s5 };
391 
392  block_t data[5];
393  memcpy(&data[1].px, x, block_size);
394  memcpy(&data[2].px, y, block_size);
395  memcpy(&data[3].px, z, block_size);
396  memcpy(&data[4].px, w, block_size);
397 
398  for (int n = 0; n < num_moves; n++)
399  data[dst[n] + 1] = data[src[n] + 1];
400 
401  memcpy(x, &data[1].px, block_size);
402  memcpy(y, &data[2].px, block_size);
403  memcpy(z, &data[3].px, block_size);
404  memcpy(w, &data[4].px, block_size);
405 
406  CONTINUE(x, y, z, w);
407 }
408 
409 SWS_FOR(PX, PERMUTE, DECL_IMPL, permute)
411 SWS_FOR_STRUCT(PX, PERMUTE, DECL_ENTRY)
413 
414 /*********************
415  * Format conversion *
416  *********************/
417 
418 #define DECL_CAST(DST, dst) \
419  DECL_FUNC(to_##dst, const SwsCompMask mask) \
420  { \
421  block_t xx, yy, zz, ww; \
422  \
423  SWS_LOOP \
424  for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \
425  if (X) xx.dst[i] = x[i]; \
426  if (Y) yy.dst[i] = y[i]; \
427  if (Z) zz.dst[i] = z[i]; \
428  if (W) ww.dst[i] = w[i]; \
429  } \
430  \
431  CONTINUE(&xx, &yy, &zz, &ww); \
432  } \
433  \
434  SWS_FOR(PX, TO_##DST, DECL_IMPL, to_##dst) \
435  SWS_FOR_STRUCT(PX, TO_##DST, DECL_ENTRY)
436 
437 DECL_CAST(U8, u8)
438 DECL_CAST(U16, u16)
439 DECL_CAST(U32, u32)
440 DECL_CAST(F32, f32)
441 
442 /********************
443  * Bit manipulation *
444  ********************/
445 
446 #if !IS_FLOAT
447 DECL_FUNC(lshift, const SwsCompMask mask, const uint8_t amount)
448 {
449  SWS_LOOP
450  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
451  if (X) x[i] <<= amount;
452  if (Y) y[i] <<= amount;
453  if (Z) z[i] <<= amount;
454  if (W) w[i] <<= amount;
455  }
456 
457  CONTINUE(x, y, z, w);
458 }
459 
460 DECL_FUNC(rshift, const SwsCompMask mask, const uint8_t amount)
461 {
462  SWS_LOOP
463  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
464  if (X) x[i] >>= amount;
465  if (Y) y[i] >>= amount;
466  if (Z) z[i] >>= amount;
467  if (W) w[i] >>= amount;
468  }
469 
470  CONTINUE(x, y, z, w);
471 }
472 #endif
473 
474 SWS_FOR(PX, LSHIFT, DECL_IMPL, lshift)
475 SWS_FOR(PX, RSHIFT, DECL_IMPL, rshift)
476 
477 SWS_FOR_STRUCT(PX, LSHIFT, DECL_ENTRY)
479 
480 #ifdef PIXEL_SWAP
481 DECL_FUNC(swap_bytes, const SwsCompMask mask)
482 {
483  SWS_LOOP
484  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
485  if (X) x[i] = PIXEL_SWAP(x[i]);
486  if (Y) y[i] = PIXEL_SWAP(y[i]);
487  if (Z) z[i] = PIXEL_SWAP(z[i]);
488  if (W) w[i] = PIXEL_SWAP(w[i]);
489  }
490 
491  CONTINUE(x, y, z, w);
492 }
493 #endif /* PIXEL_SWAP */
494 
495 SWS_FOR(PX, SWAP_BYTES, DECL_IMPL, swap_bytes)
496 SWS_FOR_STRUCT(PX, SWAP_BYTES, DECL_ENTRY)
497 
498 #ifdef PIXEL_MAX
499 DECL_FUNC(expand_bit, const SwsCompMask mask)
500 {
501  SWS_LOOP
502  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
503  if (X) x[i] = x[i] ? PIXEL_MAX : 0;
504  if (Y) y[i] = y[i] ? PIXEL_MAX : 0;
505  if (Z) z[i] = z[i] ? PIXEL_MAX : 0;
506  if (W) w[i] = w[i] ? PIXEL_MAX : 0;
507  }
508 
509  CONTINUE(x, y, z, w);
510 }
511 #endif
512 
513 #if BIT_DEPTH == 8
514 DECL_FUNC(expand_pair, const SwsCompMask mask)
515 {
516  block_t x16, y16, z16, w16;
517 
518  SWS_LOOP
519  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
520  if (X) x16.u16[i] = x[i] << 8 | x[i];
521  if (Y) y16.u16[i] = y[i] << 8 | y[i];
522  if (Z) z16.u16[i] = z[i] << 8 | z[i];
523  if (W) w16.u16[i] = w[i] << 8 | w[i];
524  }
525 
526  CONTINUE(&x16, &y16, &z16, &w16);
527 }
528 
529 DECL_FUNC(expand_quad, const SwsCompMask mask)
530 {
531  block_t x32, y32, z32, w32;
532 
533  SWS_LOOP
534  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
535  if (X) x32.u32[i] = (uint32_t) x[i] << 24 | x[i] << 16 | x[i] << 8 | x[i];
536  if (Y) y32.u32[i] = (uint32_t) y[i] << 24 | y[i] << 16 | y[i] << 8 | y[i];
537  if (Z) z32.u32[i] = (uint32_t) z[i] << 24 | z[i] << 16 | z[i] << 8 | z[i];
538  if (W) w32.u32[i] = (uint32_t) w[i] << 24 | w[i] << 16 | w[i] << 8 | w[i];
539  }
540 
541  CONTINUE(&x32, &y32, &z32, &w32);
542 }
543 #endif /* BIT_DEPTH == 8 */
544 
545 SWS_FOR(PX, EXPAND_BIT, DECL_IMPL, expand_bit)
546 SWS_FOR(PX, EXPAND_PAIR, DECL_IMPL, expand_pair)
547 SWS_FOR(PX, EXPAND_QUAD, DECL_IMPL, expand_quad)
548 SWS_FOR_STRUCT(PX, EXPAND_BIT, DECL_ENTRY)
549 SWS_FOR_STRUCT(PX, EXPAND_PAIR, DECL_ENTRY)
550 SWS_FOR_STRUCT(PX, EXPAND_QUAD, DECL_ENTRY)
551 
552 /*************************
553  * Packing and unpacking *
554  ************************/
555 
556 #if !IS_FLOAT
558  const uint8_t bx, const uint8_t by,
559  const uint8_t bz, const uint8_t bw)
560 {
561  const uint8_t sx = bw + bz + by;
562  const uint8_t sy = bw + bz;
563  const uint8_t sz = bw;
564  const uint8_t sw = 0;
565 
566  const pixel_t mx = (1 << bx) - 1;
567  const pixel_t my = (1 << by) - 1;
568  const pixel_t mz = (1 << bz) - 1;
569  const pixel_t mw = (1 << bw) - 1;
570 
571  SWS_LOOP
572  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
573  const pixel_t val = x[i];
574  if (X) x[i] = (val >> sx) & mx;
575  if (Y) y[i] = (val >> sy) & my;
576  if (Z) z[i] = (val >> sz) & mz;
577  if (W) w[i] = (val >> sw) & mw;
578  }
579 
580  CONTINUE(x, y, z, w);
581 }
582 
584  const uint8_t bx, const uint8_t by,
585  const uint8_t bz, const uint8_t bw)
586 {
587  const uint8_t sx = bw + bz + by;
588  const uint8_t sy = bw + bz;
589  const uint8_t sz = bw;
590  const uint8_t sw = 0;
591 
592  SWS_LOOP
593  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
594  pixel_t val = 0;
595  if (X) val |= x[i] << sx;
596  if (Y) val |= y[i] << sy;
597  if (Z) val |= z[i] << sz;
598  if (W) val |= w[i] << sw;
599  x[i] = val;
600  }
601 
602  CONTINUE(x, y, z, w);
603 }
604 #endif /* !IS_FLOAT */
605 
606 SWS_FOR(PX, UNPACK, DECL_IMPL, unpack)
607 SWS_FOR(PX, PACK, DECL_IMPL, pack)
608 SWS_FOR_STRUCT(PX, UNPACK, DECL_ENTRY)
610 
611 /***********************
612  * Pixel data clearing *
613  ***********************/
614 
615 #ifdef PIXEL_MAX
616 DECL_FUNC(clear, const SwsCompMask mask, const SwsCompMask one,
617  const SwsCompMask zero)
618 {
619  #define ONE(N) SWS_COMP_TEST(one, N)
620  #define ZERO(N) SWS_COMP_TEST(zero, N)
621  const pixel_t cx = ONE(0) ? PIXEL_MAX : ZERO(0) ? 0 : impl->priv.px[0];
622  const pixel_t cy = ONE(1) ? PIXEL_MAX : ZERO(1) ? 0 : impl->priv.px[1];
623  const pixel_t cz = ONE(2) ? PIXEL_MAX : ZERO(2) ? 0 : impl->priv.px[2];
624  const pixel_t cw = ONE(3) ? PIXEL_MAX : ZERO(3) ? 0 : impl->priv.px[3];
625 
626  SWS_LOOP
627  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
628  if (X) x[i] = cx;
629  if (Y) y[i] = cy;
630  if (Z) z[i] = cz;
631  if (W) w[i] = cw;
632  }
633 
634  CONTINUE(x, y, z, w);
635 }
636 #endif
637 
638 SWS_FOR(PX, CLEAR, DECL_IMPL, clear)
640 
641 /*************************
642  * Arithmetic operations *
643  *************************/
644 
646 {
647  const pixel_t scale = impl->priv.px[0];
648 
649  SWS_LOOP
650  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
651  if (X) x[i] *= scale;
652  if (Y) y[i] *= scale;
653  if (Z) z[i] *= scale;
654  if (W) w[i] *= scale;
655  }
656 
657  CONTINUE(x, y, z, w);
658 }
659 
661 {
662  SWS_LOOP
663  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
664  if (X) x[i] += impl->priv.px[0];
665  if (Y) y[i] += impl->priv.px[1];
666  if (Z) z[i] += impl->priv.px[2];
667  if (W) w[i] += impl->priv.px[3];
668  }
669 
670  CONTINUE(x, y, z, w);
671 }
672 
674 {
675  SWS_LOOP
676  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
677  if (X) x[i] = FFMIN(x[i], impl->priv.px[0]);
678  if (Y) y[i] = FFMIN(y[i], impl->priv.px[1]);
679  if (Z) z[i] = FFMIN(z[i], impl->priv.px[2]);
680  if (W) w[i] = FFMIN(w[i], impl->priv.px[3]);
681  }
682 
683  CONTINUE(x, y, z, w);
684 }
685 
687 {
688  SWS_LOOP
689  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
690  if (X) x[i] = FFMAX(x[i], impl->priv.px[0]);
691  if (Y) y[i] = FFMAX(y[i], impl->priv.px[1]);
692  if (Z) z[i] = FFMAX(z[i], impl->priv.px[2]);
693  if (W) w[i] = FFMAX(w[i], impl->priv.px[3]);
694  }
695 
696  CONTINUE(x, y, z, w);
697 }
698 
700 SWS_FOR(PX, ADD, DECL_IMPL, add)
707 
708 /*************
709  * Dithering *
710  *************/
711 
713 {
714  const SwsUOp *uop = params->uop;
715  const SwsDitherUOp *dither = &uop->par.dither;
716  const int size = 1 << dither->size_log2;
717  if (size >= SWS_BLOCK_SIZE) {
718  /* No extra padding needed */
719  out->priv.ptr = av_refstruct_ref(uop->data.ptr);
720  out->free = ff_op_priv_unref;
721  return 0;
722  }
723 
724  const int stride = FFMAX(size, SWS_BLOCK_SIZE);
725  const int height = ff_sws_dither_height(dither);
726  pixel_t *matrix = av_malloc(sizeof(pixel_t) * height * stride);
727  if (!matrix)
728  return AVERROR(ENOMEM);
729  out->priv.ptr = matrix;
730  out->free = ff_op_priv_free;
731 
732  /* Pad to multiple of block size. We don't need extra padding for the
733  * height because ff_sws_dither_height() already includes any padding
734  * necessary for the y_offset */
735  for (int y = 0; y < height; y++) {
736  pixel_t *row = &matrix[y * stride];
737  for (int x = 0; x < size; x++)
738  row[x] = uop->data.ptr[y * size + x].px;
739  for (int x = size; x < stride; x++)
740  row[x] = row[x % size];
741  }
742 
743  return 0;
744 }
745 
747  const uint8_t off0, const uint8_t off1,
748  const uint8_t off2, const uint8_t off3,
749  const uint8_t size_log2)
750 {
751  const int size = 1 << size_log2;
752  const int stride = FFMAX(size, SWS_BLOCK_SIZE);
753 
754  const pixel_t *matrix = impl->priv.ptr;
755  matrix += (iter->y & (size - 1)) * stride;
756  matrix += (iter->x & (size - 1)) & ~(SWS_BLOCK_SIZE - 1);
757 
758  const pixel_t *const row0 = &matrix[off0 * stride];
759  const pixel_t *const row1 = &matrix[off1 * stride];
760  const pixel_t *const row2 = &matrix[off2 * stride];
761  const pixel_t *const row3 = &matrix[off3 * stride];
762 
763  SWS_LOOP
764  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
765  if (X) x[i] += row0[i];
766  if (Y) y[i] += row1[i];
767  if (Z) z[i] += row2[i];
768  if (W) w[i] += row3[i];
769  }
770 
771  CONTINUE(x, y, z, w);
772 }
773 
774 SWS_FOR(PX, DITHER, DECL_IMPL, dither)
775 SWS_FOR_STRUCT(PX, DITHER, DECL_ENTRY, .setup = fn(setup_dither) )
776 
777 /*********************
778  * Linear operations *
779  *********************/
780 
781 typedef struct {
782  /* Stored in split form for convenience */
783  pixel_t m[4][4];
784  pixel_t k[4];
785 } fn(LinCoeffs);
786 
788 {
789  const SwsUOp *uop = params->uop;
790  fn(LinCoeffs) c;
791 
792  for (int i = 0; i < 4; i++) {
793  for (int j = 0; j < 4; j++)
794  c.m[i][j] = uop->data.mat4[i][j].px;
795  c.k[i] = uop->data.mat4[i][4].px;
796  }
797 
798  out->priv.ptr = av_memdup(&c, sizeof(c));
799  out->free = ff_op_priv_free;
800  return out->priv.ptr ? 0 : AVERROR(ENOMEM);
801 }
802 
803 /**
804  * Fully general case for a 5x5 linear affine transformation. Should never be
805  * called without constant `mask`. This function will compile down to the
806  * appropriately optimized version for the required subset of operations when
807  * called with a constant mask.
808  */
809 DECL_FUNC(linear, const SwsCompMask mask, const uint32_t one, const uint32_t zero)
810 {
811  const fn(LinCoeffs) c = *(const fn(LinCoeffs) *) impl->priv.ptr;
812 
813  SWS_LOOP
814  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
815  const pixel_t xx = x[i];
816  const pixel_t yy = y[i];
817  const pixel_t zz = z[i];
818  const pixel_t ww = w[i];
819 
820 #define LIN_VAL(I, J, val) \
821  ((one & SWS_MASK(I, J)) ? (val) : c.m[I][J] * (val))
822 
823 #define LIN_ROW(I, var) do { \
824  var[i] = (zero & SWS_MASK(I, 4)) ? 0 : c.k[I]; \
825  if (!(zero & SWS_MASK(I, 0))) var[i] += LIN_VAL(I, 0, xx); \
826  if (!(zero & SWS_MASK(I, 1))) var[i] += LIN_VAL(I, 1, yy); \
827  if (!(zero & SWS_MASK(I, 2))) var[i] += LIN_VAL(I, 2, zz); \
828  if (!(zero & SWS_MASK(I, 3))) var[i] += LIN_VAL(I, 3, ww); \
829 } while (0)
830 
831  if (X) LIN_ROW(0, x);
832  if (Y) LIN_ROW(1, y);
833  if (Z) LIN_ROW(2, z);
834  if (W) LIN_ROW(3, w);
835  }
836 
837  CONTINUE(x, y, z, w);
838 }
839 
842 
843 /******************
844  * Look-up tables *
845  ******************/
846 
847 DECL_SETUP(setup_lut3d, params, out)
848 {
849  const SwsLut3D *lut = params->uop->data.lut3d;
850  out->priv.ptr = (void *) av_refstruct_ref_c(lut);
851  out->free = ff_op_priv_unref;
852  return 0;
853 }
854 
855 #if IS_FLOAT
856 av_always_inline static vec3_t fn(vec3)(v3u16_t v)
857 {
858  return (vec3_t) { v.x, v.y, v.z };
859 }
860 
861 #define lerp(a, b, w) ((a) + (w) * ((pixel_t) (b) - (a)))
862 
863 av_always_inline static
864 vec3_t fn(lerp3)(vec3_t a, vec3_t b, pixel_t w)
865 {
866  return (vec3_t) {
867  lerp(a.x, b.x, w),
868  lerp(a.y, b.y, w),
869  lerp(a.z, b.z, w),
870  };
871 }
872 
873 av_always_inline static
874 vec3_t fn(lut3d_static)(const SwsLut3D *restrict lut3d, vec3_t rgb)
875 {
876  const int r_base = (int) rgb.x;
877  const int g_base = (int) rgb.y;
878  const int b_base = (int) rgb.z;
879 
880  int off0 = (r_base < INPUT_LUT_SIZE - 1);
881  int off1 = (g_base < INPUT_LUT_SIZE - 1) * INPUT_LUT_SIZE;
882  int off2 = (b_base < INPUT_LUT_SIZE - 1) * INPUT_LUT_SIZE * INPUT_LUT_SIZE;
883  pixel_t f0 = rgb.x - r_base;
884  pixel_t f1 = rgb.y - g_base;
885  pixel_t f2 = rgb.z - b_base;
886 
887  /* Sort offsets descending by relative weight */
888  if (f0 < f1) {
889  FFSWAP(pixel_t, f0, f1);
890  FFSWAP(int, off0, off1);
891  }
892  if (f0 < f2) {
893  FFSWAP(pixel_t, f0, f2);
894  FFSWAP(int, off0, off2);
895  }
896  if (f1 < f2) {
897  FFSWAP(pixel_t, f1, f2);
898  FFSWAP(int, off1, off2);
899  }
900 
901  /* Tetrahedral interpolation */
902  const pixel_t w0 = 1 - f0;
903  const pixel_t w1 = f0 - f1;
904  const pixel_t w2 = f1 - f2;
905  const pixel_t w3 = f2;
906 
907  const v3u16_t *restrict base = &lut3d->input[b_base][g_base][r_base];
908  const vec3_t v0 = fn(vec3)(base[0]);
909  const vec3_t v1 = fn(vec3)(base[off0]);
910  const vec3_t v2 = fn(vec3)(base[off0 + off1]);
911  const vec3_t v3 = fn(vec3)(base[off0 + off1 + off2]);
912 
913  return (vec3_t) {
914  w0 * v0.x + w1 * v1.x + w2 * v2.x + w3 * v3.x,
915  w0 * v0.y + w1 * v1.y + w2 * v2.y + w3 * v3.y,
916  w0 * v0.z + w1 * v1.z + w2 * v2.z + w3 * v3.z,
917  };
918 }
919 
920 av_always_inline static
921 vec3_t fn(lut3d_dynamic)(const SwsLut3D *restrict lut3d, vec3_t rgb)
922 {
923  rgb.x *= (TONE_LUT_SIZE - 1) / (pixel_t) UINT16_MAX;
924 
925  /* Linear interpolation */
926  const int Ix = (int) rgb.x;
927  const pixel_t If = rgb.x - Ix;
928 
929  const v2u16_t a = lut3d->tone_map[Ix];
930  const v2u16_t b = lut3d->tone_map[Ix + 1];
931 
932  const pixel_t k = lerp(a.y, b.y, If);
933  const pixel_t bias = (1 << 15) - k;
934  const pixel_t scale = k / (pixel_t) (1 << 15);
935 
936  rgb.x = lerp(a.x, b.x, If);
937  rgb.y = bias + scale * rgb.y;
938  rgb.z = bias + scale * rgb.z;
939 
940  /* Re-scale to output LUT size */
941  rgb.x *= (OUTPUT_LUT_SIZE_I - 1) / (pixel_t) UINT16_MAX;
942  rgb.y *= (OUTPUT_LUT_SIZE_PT - 1) / (pixel_t) UINT16_MAX;
943  rgb.z *= (OUTPUT_LUT_SIZE_PT - 1) / (pixel_t) UINT16_MAX;
944 
945  /* Trilinear interpolation */
946  const int lo0 = (int) rgb.x;
947  const int lo1 = (int) rgb.y;
948  const int lo2 = (int) rgb.z;
949 
950  const int hi0 = FFMIN(lo0 + 1, OUTPUT_LUT_SIZE_I - 1);
951  const int hi1 = FFMIN(lo1 + 1, OUTPUT_LUT_SIZE_PT - 1);
952  const int hi2 = FFMIN(lo2 + 1, OUTPUT_LUT_SIZE_PT - 1);
953 
954  const pixel_t w0 = rgb.x - lo0;
955  const vec3_t c000 = fn(vec3)(lut3d->output[lo2][lo1][lo0]);
956  const vec3_t c001 = fn(vec3)(lut3d->output[lo2][lo1][hi0]);
957  const vec3_t c00 = fn(lerp3)(c000, c001, w0);
958  const vec3_t c010 = fn(vec3)(lut3d->output[lo2][hi1][lo0]);
959  const vec3_t c011 = fn(vec3)(lut3d->output[lo2][hi1][hi0]);
960  const vec3_t c01 = fn(lerp3)(c010, c011, w0);
961  const vec3_t c100 = fn(vec3)(lut3d->output[hi2][lo1][lo0]);
962  const vec3_t c101 = fn(vec3)(lut3d->output[hi2][lo1][hi0]);
963  const vec3_t c10 = fn(lerp3)(c100, c101, w0);
964  const vec3_t c110 = fn(vec3)(lut3d->output[hi2][hi1][lo0]);
965  const vec3_t c111 = fn(vec3)(lut3d->output[hi2][hi1][hi0]);
966  const vec3_t c11 = fn(lerp3)(c110, c111, w0);
967 
968  const pixel_t w1 = rgb.y - lo1;
969  const vec3_t c0 = fn(lerp3)(c00, c01, w1);
970  const vec3_t c1 = fn(lerp3)(c10, c11, w1);
971 
972  const pixel_t w2 = rgb.z - lo2;
973  return fn(lerp3)(c0, c1, w2);
974 }
975 
976 DECL_FUNC(lut3d, const SwsCompMask mask, const int dynamic)
977 {
978  const SwsLut3D *restrict lut3d = impl->priv.ptr;
979 
980  SWS_LOOP
981  for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
982  vec3_t c = { x[i], y[i], z[i] };
983  c = fn(lut3d_static)(lut3d, c);
984  if (dynamic)
985  c = fn(lut3d_dynamic)(lut3d, c);
986 
987  x[i] = c.x;
988  y[i] = c.y;
989  z[i] = c.z;
990  }
991 
992  CONTINUE(x, y, z, w);
993 }
994 #endif /* IS_FLOAT */
995 
996 SWS_FOR(PX, LUT_3D, DECL_IMPL, lut3d)
997 SWS_FOR_STRUCT(PX, LUT_3D, DECL_ENTRY, .setup = fn(setup_lut3d) )
998 
999 #undef PIXEL_MAX
1000 #undef PIXEL_SWAP
1001 #undef pixel_t
1002 #undef inter_t
1003 #undef vec3_t
1004 #undef PX
1005 #undef px
DECL_IMPL_WRITE
#define DECL_IMPL_WRITE(...)
Definition: uops_tmpl.h:133
PIXEL_MAX
#define PIXEL_MAX
Definition: uops_tmpl.c:51
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
MAX
#define MAX
Definition: blend_modes.c:46
out
static FILE * out
Definition: movenc.c:55
SIZEOF_BLOCK
#define SIZEOF_BLOCK
Definition: uops_tmpl.h:50
Z
#define Z
Definition: uops_tmpl.h:83
matrix
Definition: vc1dsp.c:43
OUTPUT_LUT_SIZE_I
@ OUTPUT_LUT_SIZE_I
Definition: lut3d.h:46
v3u16_t
Definition: csputils.h:72
block_t::f32
float f32[SWS_BLOCK_SIZE]
Definition: uops_tmpl.h:47
DECL_ENTRY
#define DECL_ENTRY(SETUP, NAME,...)
Definition: uops_tmpl.h:139
mask
int mask
Definition: mediacodecdec_common.c:154
SwsUOp::data
union SwsUOp::@597 data
SwsFilterWeights
Represents a computed filter kernel.
Definition: filters.h:85
b
#define b
Definition: input.c:43
permute
static void permute(int16_t dst[64], const int16_t src[64], enum idct_permutation_type perm_type)
Definition: dct.c:158
data
const char data[16]
Definition: mxf.c:149
linear
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:135
SWS_UOP_MOVE_MAX
#define SWS_UOP_MOVE_MAX
Definition: uops.h:206
base
uint8_t base
Definition: vp3data.h:128
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
TONE_LUT_SIZE
@ TONE_LUT_SIZE
Definition: lut3d.h:40
c1
static const uint64_t c1
Definition: murmur3.c:52
SwsOpExec::in_stride
ptrdiff_t in_stride[4]
Definition: ops_dispatch.h:42
ff_op_priv_unref
static void ff_op_priv_unref(SwsOpPriv *priv)
Definition: ops_chain.h:149
setup_linear
static int setup_linear(const SwsImplParams *params, SwsImplResult *out)
Definition: ops.c:280
ONE
#define ONE(N)
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:302
av_always_inline
#define av_always_inline
Definition: attributes.h:76
rgb
Definition: rpzaenc.c:60
setup_dither
static int setup_dither(const SwsImplParams *params, SwsImplResult *out)
Definition: ops.c:273
mx
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
Definition: dsp.h:57
DECL_WRITE
DECL_WRITE(write_planar, const SwsCompMask mask)
Definition: uops_tmpl.c:98
PX
#define PX
Definition: uops_tmpl.c:54
weight
const h264_weight_func weight
Definition: h264dsp_init.c:33
val
static double val(void *priv, double ch)
Definition: aeval.c:77
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
SWS_COMP_ELEMS
#define SWS_COMP_ELEMS(N)
Definition: uops.h:100
SWS_FOR
#define SWS_FOR(TYPE, UOP, MACRO,...)
Definition: uops_macros.h:17
SWS_FOR_STRUCT
#define SWS_FOR_STRUCT(TYPE, UOP, MACRO,...)
Definition: uops_macros.h:19
float
float
Definition: af_crystalizer.c:122
SwsAArch64OpImplParams::uop
SwsUOpType uop
Definition: ops_impl.h:48
W
#define W(a, i, v)
Definition: jpegls.h:119
dither
static const uint16_t dither[8][8]
Definition: vf_gradfun.c:46
SCALE
#define SCALE(c)
Definition: dcadata.c:7338
LINEAR
#define LINEAR
Definition: vf_perspective.c:36
SwsCompMask
uint8_t SwsCompMask
Bit-mask of components.
Definition: uops.h:88
params
SwsAArch64OpImplParams params
Definition: ops.c:51
COPY
#define COPY(src, name)
RSHIFT
#define RSHIFT(a, b)
Definition: common.h:56
my
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
Definition: dsp.h:57
read_bit
static unsigned int BS_FUNC() read_bit(BSCTX *bc)
Return one bit from the buffer.
Definition: bitstream_template.h:211
SwsOpExec
Copyright (C) 2026 Niklas Haas.
Definition: ops_dispatch.h:36
LIN_ROW
#define LIN_ROW(I, var)
xs
#define xs(width, name, var, subs,...)
Definition: cbs_vp9.c:305
v2u16_t
Definition: csputils.h:68
NULL
#define NULL
Definition: coverity.c:32
SwsUOp::mat4
SwsPixel mat4[4][5]
Definition: uops.h:277
ADD
#define ADD(a, b)
Definition: dct32_template.c:123
bias
static int bias(int x, int c)
Definition: vqcdec.c:115
block_t
Definition: uops_tmpl.h:43
DECL_IMPL
#define DECL_IMPL(FUNC, NAME, TYPE, UOP,...)
Definition: uops_tmpl.h:119
SWS_BLOCK_SIZE
#define SWS_BLOCK_SIZE
Copyright (C) 2026 Niklas Haas.
Definition: uops_tmpl.h:40
SwsPixelType
SwsPixelType
Definition: uops.h:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
SwsUOp::par
SwsUOpParams par
Definition: uops.h:269
ff_sws_setup_vec4
int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out)
Definition: ops_chain.c:200
SwsUOp
Definition: uops.h:264
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
SWS_LOOP
#define SWS_LOOP
Definition: uops_tmpl.h:68
height
#define height
Definition: dsp.h:89
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
size
int size
Definition: twinvq_data.h:10344
mz
static double mz(int i, double w0, double r, double alpha)
Definition: af_atilt.c:55
av_malloc
#define av_malloc(s)
Definition: ops_static.c:52
inter_t
#define inter_t
Definition: uops_tmpl.c:53
fn
#define fn(a)
Definition: aap_template.c:37
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
lerp
static double lerp(double a, double b, double x)
Definition: perlin.c:75
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
zero
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:121
Y
#define Y
Definition: boxblur.h:37
OUTPUT_LUT_SIZE_PT
@ OUTPUT_LUT_SIZE_PT
Definition: lut3d.h:47
CONTINUE
#define CONTINUE(...)
Definition: uops_tmpl.h:107
DECL_FUNC
DECL_FUNC(permute, const SwsCompMask mask, int num_moves, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
Definition: uops_tmpl.c:364
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
SwsLut3D
Append a set of operations for applying a gamut/tone mapping 3D LUT to the pixels.
Definition: lut3d.h:50
unpack
static int unpack(const uint8_t *src, const uint8_t *src_end, uint8_t *dst, int width, int height)
Unpack buffer.
Definition: eatgv.c:73
SwsOpExec::in_offset_x
int32_t * in_offset_x
Pixel offset map; for horizontal scaling, in bytes.
Definition: ops_dispatch.h:81
weights
static const int weights[]
Definition: hevc_pel.c:32
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
MIN
#define MIN(a, b)
Definition: qt-faststart.c:45
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ff_op_priv_free
static void ff_op_priv_free(SwsOpPriv *priv)
Definition: ops_chain.h:144
bswap.h
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
bump_ptr
#define bump_ptr(ptr, bump)
Definition: uops_tmpl.h:78
DECL_SETUP
DECL_SETUP(setup_filter_v, params, out)
Definition: uops_tmpl.c:241
DECL_CAST
#define DECL_CAST(DST, dst)
Definition: uops_tmpl.c:418
SwsUOp::ptr
SwsPixel * ptr
Definition: uops.h:274
pixel_t
#define pixel_t
Definition: uops_tmpl.c:52
block_t::u32
uint32_t u32[SWS_BLOCK_SIZE]
Definition: uops_tmpl.h:46
av_refstruct_ref_c
const void * av_refstruct_ref_c(const void *obj)
Analog of av_refstruct_ref(), but for constant objects.
Definition: refstruct.c:149
X
@ X
Definition: vf_addroi.c:27
CLEAR
#define CLEAR(destin)
Definition: wavpackenc.c:50
px
#define px
Definition: uops_tmpl.c:55
ff_sws_setup_scalar
int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out)
Definition: ops_chain.c:185
SWS_FILTER_SCALE
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
Definition: filters.h:40
block_t::u16
uint16_t u16[SWS_BLOCK_SIZE]
Definition: uops_tmpl.h:45
SwsDitherUOp
Definition: uops.h:237
SwsUOpParams::dither
SwsDitherUOp dither
Definition: uops.h:260
ZERO
#define ZERO(N)
SWS_PIXEL_F32
@ SWS_PIXEL_F32
Definition: uops.h:44
w
uint8_t w
Definition: llvidencdsp.c:39
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
uops_tmpl.h
setup_filter_v
static int setup_filter_v(const SwsImplParams *params, SwsImplResult *out)
Definition: ops.c:46
DECL_READ
DECL_READ(read_planar, const SwsCompMask mask)
Definition: uops_tmpl.c:64
int32_t
int32_t
Definition: audioconvert.c:56
rgb
static const SheerTable rgb[2]
Definition: sheervideodata.h:32
ff_sws_dither_height
int ff_sws_dither_height(const SwsDitherUOp *dither)
Computes (1 << size_log2) + MAX(y_offset).
Definition: uops.c:232
stride
#define stride
Definition: h264pred_template.c:536
INPUT_LUT_SIZE
@ INPUT_LUT_SIZE
Definition: lut3d.h:36
DECL_IMPL_READ
#define DECL_IMPL_READ(...)
Definition: uops_tmpl.h:128
src
#define src
Definition: vp8dsp.c:248
min
float min
Definition: vorbis_enc_data.h:429
setup_filter_h
static int setup_filter_h(const SwsImplParams *params, SwsImplResult *out)
Definition: ops.c:76