drawutils.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Stefano Sabatini <stefano.sabatini-lala poste it>
3  * Copyright 2012 Nicolas George <nicolas.george normalesup org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <string.h>
23 
24 #include "libavutil/avutil.h"
25 #include "libavutil/colorspace.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/pixdesc.h"
28 #include "drawutils.h"
29 #include "formats.h"
30 
31 enum { RED = 0, GREEN, BLUE, ALPHA };
32 
34 {
35  switch (pix_fmt) {
36  case AV_PIX_FMT_0RGB:
37  case AV_PIX_FMT_ARGB: rgba_map[ALPHA] = 0; rgba_map[RED ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
38  case AV_PIX_FMT_0BGR:
39  case AV_PIX_FMT_ABGR: rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED ] = 3; break;
40  case AV_PIX_FMT_RGB0:
41  case AV_PIX_FMT_RGBA:
42  case AV_PIX_FMT_RGB24: rgba_map[RED ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
43  case AV_PIX_FMT_BGRA:
44  case AV_PIX_FMT_BGR0:
45  case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break;
46  default: /* unsupported */
47  return AVERROR(EINVAL);
48  }
49  return 0;
50 }
51 
52 int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4],
53  enum AVPixelFormat pix_fmt, uint8_t rgba_color[4],
54  int *is_packed_rgba, uint8_t rgba_map_ptr[4])
55 {
56  uint8_t rgba_map[4] = {0};
57  int i;
58  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt);
59  int hsub = pix_desc->log2_chroma_w;
60 
61  *is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0;
62 
63  if (*is_packed_rgba) {
64  pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
65  for (i = 0; i < 4; i++)
66  dst_color[rgba_map[i]] = rgba_color[i];
67 
68  line[0] = av_malloc(w * pixel_step[0]);
69  for (i = 0; i < w; i++)
70  memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]);
71  if (rgba_map_ptr)
72  memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4);
73  } else {
74  int plane;
75 
76  dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
77  dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
78  dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
79  dst_color[3] = rgba_color[3];
80 
81  for (plane = 0; plane < 4; plane++) {
82  int line_size;
83  int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
84 
85  pixel_step[plane] = 1;
86  line_size = (w >> hsub1) * pixel_step[plane];
87  line[plane] = av_malloc(line_size);
88  memset(line[plane], dst_color[plane], line_size);
89  }
90  }
91 
92  return 0;
93 }
94 
95 void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
96  uint8_t *src[4], int pixelstep[4],
97  int hsub, int vsub, int x, int y, int w, int h)
98 {
99  int i, plane;
100  uint8_t *p;
101 
102  for (plane = 0; plane < 4 && dst[plane]; plane++) {
103  int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
104  int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
105 
106  p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
107  for (i = 0; i < (h >> vsub1); i++) {
108  memcpy(p + (x >> hsub1) * pixelstep[plane],
109  src[plane], (w >> hsub1) * pixelstep[plane]);
110  p += dst_linesize[plane];
111  }
112  }
113 }
114 
115 void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
116  uint8_t *src[4], int src_linesize[4], int pixelstep[4],
117  int hsub, int vsub, int x, int y, int y2, int w, int h)
118 {
119  int i, plane;
120  uint8_t *p;
121 
122  for (plane = 0; plane < 4 && dst[plane]; plane++) {
123  int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
124  int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
125 
126  p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
127  for (i = 0; i < (h >> vsub1); i++) {
128  memcpy(p + (x >> hsub1) * pixelstep[plane],
129  src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * pixelstep[plane]);
130  p += dst_linesize[plane];
131  }
132  }
133 }
134 
136 {
137  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
138  const AVComponentDescriptor *c;
139  unsigned i, nb_planes = 0;
140  int pixelstep[MAX_PLANES] = { 0 };
141 
142  if (!desc->name)
143  return AVERROR(EINVAL);
145  return AVERROR(ENOSYS);
146  for (i = 0; i < desc->nb_components; i++) {
147  c = &desc->comp[i];
148  /* for now, only 8-bits formats */
149  if (c->depth_minus1 != 8 - 1)
150  return AVERROR(ENOSYS);
151  if (c->plane >= MAX_PLANES)
152  return AVERROR(ENOSYS);
153  /* strange interleaving */
154  if (pixelstep[c->plane] != 0 &&
155  pixelstep[c->plane] != c->step_minus1 + 1)
156  return AVERROR(ENOSYS);
157  pixelstep[c->plane] = c->step_minus1 + 1;
158  if (pixelstep[c->plane] >= 8)
159  return AVERROR(ENOSYS);
160  nb_planes = FFMAX(nb_planes, c->plane + 1);
161  }
162  if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3)
163  return AVERROR(ENOSYS); /* exclude NV12 and NV21 */
164  memset(draw, 0, sizeof(*draw));
165  draw->desc = desc;
166  draw->format = format;
167  draw->nb_planes = nb_planes;
168  memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
169  if (nb_planes >= 3 && !(desc->flags & PIX_FMT_RGB)) {
170  draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
171  draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
172  }
173  for (i = 0; i < ((desc->nb_components - 1) | 1); i++)
174  draw->comp_mask[desc->comp[i].plane] |=
175  1 << (desc->comp[i].offset_plus1 - 1);
176  return 0;
177 }
178 
180 {
181  unsigned i;
182  uint8_t rgba_map[4];
183 
184  if (rgba != color->rgba)
185  memcpy(color->rgba, rgba, sizeof(color->rgba));
186  if ((draw->desc->flags & PIX_FMT_RGB) && draw->nb_planes == 1 &&
187  ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
188  for (i = 0; i < 4; i++)
189  color->comp[0].u8[rgba_map[i]] = rgba[i];
190  } else if (draw->nb_planes == 3 || draw->nb_planes == 4) {
191  /* assume YUV */
192  color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
193  color->comp[1].u8[0] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
194  color->comp[2].u8[0] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
195  color->comp[3].u8[0] = rgba[3];
196  } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) {
197  color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
198  color->comp[1].u8[0] = rgba[3];
199  } else {
201  "Color conversion not implemented for %s\n", draw->desc->name);
202  memset(color, 128, sizeof(*color));
203  }
204 }
205 
206 static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[],
207  int plane, int x, int y)
208 {
209  return data[plane] +
210  (y >> draw->vsub[plane]) * linesize[plane] +
211  (x >> draw->hsub[plane]) * draw->pixelstep[plane];
212 }
213 
215  uint8_t *dst[], int dst_linesize[],
216  uint8_t *src[], int src_linesize[],
217  int dst_x, int dst_y, int src_x, int src_y,
218  int w, int h)
219 {
220  int plane, y, wp, hp;
221  uint8_t *p, *q;
222 
223  for (plane = 0; plane < draw->nb_planes; plane++) {
224  p = pointer_at(draw, src, src_linesize, plane, src_x, src_y);
225  q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
226  wp = (w >> draw->hsub[plane]) * draw->pixelstep[plane];
227  hp = (h >> draw->vsub[plane]);
228  for (y = 0; y < hp; y++) {
229  memcpy(q, p, wp);
230  p += src_linesize[plane];
231  q += dst_linesize[plane];
232  }
233  }
234 }
235 
237  uint8_t *dst[], int dst_linesize[],
238  int dst_x, int dst_y, int w, int h)
239 {
240  int plane, x, y, wp, hp;
241  uint8_t *p0, *p;
242 
243  for (plane = 0; plane < draw->nb_planes; plane++) {
244  p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
245  wp = (w >> draw->hsub[plane]);
246  hp = (h >> draw->vsub[plane]);
247  if (!hp)
248  return;
249  p = p0;
250  /* copy first line from color */
251  for (x = 0; x < wp; x++) {
252  memcpy(p, color->comp[plane].u8, draw->pixelstep[plane]);
253  p += draw->pixelstep[plane];
254  }
255  wp *= draw->pixelstep[plane];
256  /* copy next lines from first line */
257  p = p0 + dst_linesize[plane];
258  for (y = 1; y < hp; y++) {
259  memcpy(p, p0, wp);
260  p += dst_linesize[plane];
261  }
262  }
263 }
264 
265 /**
266  * Clip interval [x; x+w[ within [0; wmax[.
267  * The resulting w may be negative if the final interval is empty.
268  * dx, if not null, return the difference between in and out value of x.
269  */
270 static void clip_interval(int wmax, int *x, int *w, int *dx)
271 {
272  if (dx)
273  *dx = 0;
274  if (*x < 0) {
275  if (dx)
276  *dx = -*x;
277  *w += *x;
278  *x = 0;
279  }
280  if (*x + *w > wmax)
281  *w = wmax - *x;
282 }
283 
284 /**
285  * Decompose w pixels starting at x
286  * into start + (w starting at x) + end
287  * with x and w aligned on multiples of 1<<sub.
288  */
289 static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
290 {
291  int mask = (1 << sub) - 1;
292 
293  *start = (-*x) & mask;
294  *x += *start;
295  *start = FFMIN(*start, *w);
296  *w -= *start;
297  *end = *w & mask;
298  *w >>= sub;
299 }
300 
301 static int component_used(FFDrawContext *draw, int plane, int comp)
302 {
303  return (draw->comp_mask[plane] >> comp) & 1;
304 }
305 
306 /* If alpha is in the [ 0 ; 0x1010101 ] range,
307  then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range,
308  and >> 24 gives a correct rounding. */
309 static void blend_line(uint8_t *dst, unsigned src, unsigned alpha,
310  int dx, int w, unsigned hsub, int left, int right)
311 {
312  unsigned asrc = alpha * src;
313  unsigned tau = 0x1010101 - alpha;
314  int x;
315 
316  if (left) {
317  unsigned suba = (left * alpha) >> hsub;
318  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
319  dst += dx;
320  }
321  for (x = 0; x < w; x++) {
322  *dst = (*dst * tau + asrc) >> 24;
323  dst += dx;
324  }
325  if (right) {
326  unsigned suba = (right * alpha) >> hsub;
327  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
328  }
329 }
330 
332  uint8_t *dst[], int dst_linesize[],
333  int dst_w, int dst_h,
334  int x0, int y0, int w, int h)
335 {
336  unsigned alpha, nb_planes, nb_comp, plane, comp;
337  int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
338  uint8_t *p0, *p;
339 
340  /* TODO optimize if alpha = 0xFF */
341  clip_interval(dst_w, &x0, &w, NULL);
342  clip_interval(dst_h, &y0, &h, NULL);
343  if (w <= 0 || h <= 0 || !color->rgba[3])
344  return;
345  /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */
346  alpha = 0x10203 * color->rgba[3] + 0x2;
347  nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
348  for (plane = 0; plane < nb_planes; plane++) {
349  nb_comp = draw->pixelstep[plane];
350  p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
351  w_sub = w;
352  h_sub = h;
353  x_sub = x0;
354  y_sub = y0;
355  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
356  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
357  for (comp = 0; comp < nb_comp; comp++) {
358  if (!component_used(draw, plane, comp))
359  continue;
360  p = p0 + comp;
361  if (top) {
362  blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
363  draw->pixelstep[plane], w_sub,
364  draw->hsub[plane], left, right);
365  p += dst_linesize[plane];
366  }
367  for (y = 0; y < h_sub; y++) {
368  blend_line(p, color->comp[plane].u8[comp], alpha,
369  draw->pixelstep[plane], w_sub,
370  draw->hsub[plane], left, right);
371  p += dst_linesize[plane];
372  }
373  if (bottom)
374  blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
375  draw->pixelstep[plane], w_sub,
376  draw->hsub[plane], left, right);
377  }
378  }
379 }
380 
381 static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha,
382  uint8_t *mask, int mask_linesize, int l2depth,
383  unsigned w, unsigned h, unsigned shift, unsigned xm0)
384 {
385  unsigned xm, x, y, t = 0;
386  unsigned xmshf = 3 - l2depth;
387  unsigned xmmod = 7 >> l2depth;
388  unsigned mbits = (1 << (1 << l2depth)) - 1;
389  unsigned mmult = 255 / mbits;
390 
391  for (y = 0; y < h; y++) {
392  xm = xm0;
393  for (x = 0; x < w; x++) {
394  t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
395  * mmult;
396  xm++;
397  }
398  mask += mask_linesize;
399  }
400  alpha = (t >> shift) * alpha;
401  *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24;
402 }
403 
404 static void blend_line_hv(uint8_t *dst, int dst_delta,
405  unsigned src, unsigned alpha,
406  uint8_t *mask, int mask_linesize, int l2depth, int w,
407  unsigned hsub, unsigned vsub,
408  int xm, int left, int right, int hband)
409 {
410  int x;
411 
412  if (left) {
413  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
414  left, hband, hsub + vsub, xm);
415  dst += dst_delta;
416  xm += left;
417  }
418  for (x = 0; x < w; x++) {
419  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
420  1 << hsub, hband, hsub + vsub, xm);
421  dst += dst_delta;
422  xm += 1 << hsub;
423  }
424  if (right)
425  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
426  right, hband, hsub + vsub, xm);
427 }
428 
430  uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h,
431  uint8_t *mask, int mask_linesize, int mask_w, int mask_h,
432  int l2depth, unsigned endianness, int x0, int y0)
433 {
434  unsigned alpha, nb_planes, nb_comp, plane, comp;
435  int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
436  uint8_t *p0, *p, *m;
437 
438  clip_interval(dst_w, &x0, &mask_w, &xm0);
439  clip_interval(dst_h, &y0, &mask_h, &ym0);
440  mask += ym0 * mask_linesize;
441  if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3])
442  return;
443  /* alpha is in the [ 0 ; 0x10203 ] range,
444  alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */
445  alpha = (0x10307 * color->rgba[3] + 0x3) >> 8;
446  nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
447  for (plane = 0; plane < nb_planes; plane++) {
448  nb_comp = draw->pixelstep[plane];
449  p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
450  w_sub = mask_w;
451  h_sub = mask_h;
452  x_sub = x0;
453  y_sub = y0;
454  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
455  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
456  for (comp = 0; comp < nb_comp; comp++) {
457  if (!component_used(draw, plane, comp))
458  continue;
459  p = p0 + comp;
460  m = mask;
461  if (top) {
462  blend_line_hv(p, draw->pixelstep[plane],
463  color->comp[plane].u8[comp], alpha,
464  m, mask_linesize, l2depth, w_sub,
465  draw->hsub[plane], draw->vsub[plane],
466  xm0, left, right, top);
467  p += dst_linesize[plane];
468  m += top * mask_linesize;
469  }
470  for (y = 0; y < h_sub; y++) {
471  blend_line_hv(p, draw->pixelstep[plane],
472  color->comp[plane].u8[comp], alpha,
473  m, mask_linesize, l2depth, w_sub,
474  draw->hsub[plane], draw->vsub[plane],
475  xm0, left, right, 1 << draw->vsub[plane]);
476  p += dst_linesize[plane];
477  m += mask_linesize << draw->vsub[plane];
478  }
479  if (bottom)
480  blend_line_hv(p, draw->pixelstep[plane],
481  color->comp[plane].u8[comp], alpha,
482  m, mask_linesize, l2depth, w_sub,
483  draw->hsub[plane], draw->vsub[plane],
484  xm0, left, right, bottom);
485  }
486  }
487 }
488 
489 int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
490  int value)
491 {
492  unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max;
493 
494  if (!shift)
495  return value;
496  if (round_dir >= 0)
497  value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1);
498  return (value >> shift) << shift;
499 }
500 
502 {
503  enum AVPixelFormat i, pix_fmts[AV_PIX_FMT_NB + 1];
504  unsigned n = 0;
505  FFDrawContext draw;
506 
507  for (i = 0; i < AV_PIX_FMT_NB; i++)
508  if (ff_draw_init(&draw, i, flags) >= 0)
509  pix_fmts[n++] = i;
510  pix_fmts[n++] = AV_PIX_FMT_NONE;
511  return ff_make_format_list(pix_fmts);
512 }
513 
514 #ifdef TEST
515 
516 #undef printf
517 
518 int main(void)
519 {
520  enum AVPixelFormat f;
521  const AVPixFmtDescriptor *desc;
522  FFDrawContext draw;
524  int r, i;
525 
526  for (f = 0; f < AV_PIX_FMT_NB; f++) {
527  desc = av_pix_fmt_desc_get(f);
528  if (!desc->name)
529  continue;
530  printf("Testing %s...%*s", desc->name,
531  (int)(16 - strlen(desc->name)), "");
532  r = ff_draw_init(&draw, f, 0);
533  if (r < 0) {
534  char buf[128];
535  av_strerror(r, buf, sizeof(buf));
536  printf("no: %s\n", buf);
537  continue;
538  }
539  ff_draw_color(&draw, &color, (uint8_t[]) { 1, 0, 0, 1 });
540  for (i = 0; i < sizeof(color); i++)
541  if (((uint8_t *)&color)[i] != 128)
542  break;
543  if (i == sizeof(color)) {
544  printf("fallback color\n");
545  continue;
546  }
547  printf("ok\n");
548  }
549  return 0;
550 }
551 
552 #endif
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
Definition: drawutils.c:429
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:501
Definition: start.py:1
static int shift(int a, int b)
Definition: sonic.c:86
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
void ff_copy_rectangle2(FFDrawContext *draw, uint8_t *dst[], int dst_linesize[], uint8_t *src[], int src_linesize[], int dst_x, int dst_y, int src_x, int src_y, int w, int h)
Copy a rectangle from an image to another.
Definition: drawutils.c:214
Definition: drawutils.c:31
uint8_t hsub[MAX_PLANES]
Definition: drawutils.h:54
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
memory handling functions
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:1731
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
Sinusoidal phase f
Various defines for YUV<->RGB conversion.
external API header
static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
Definition: drawutils.c:309
packed BGR 8:8:8, 32bpp, 0BGR0BGR...
Definition: pixfmt.h:216
Definition: drawutils.c:31
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:66
static void clip_interval(int wmax, int *x, int *w, int *dx)
Clip interval [x; x+w[ within [0; wmax[.
Definition: drawutils.c:270
output residual component w
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, int value)
Round a dimension according to subsampling.
Definition: drawutils.c:489
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
packed RGB 8:8:8, 32bpp, RGB0RGB0...
Definition: pixfmt.h:215
window constants for m
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:77
end end
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:98
uint8_t comp_mask[MAX_PLANES]
Definition: drawutils.h:53
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
const char * name
Definition: pixdesc.h:56
Discrete Time axis x
uint16_t depth_minus1
number of bits in the component minus 1
Definition: pixdesc.h:43
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:86
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:75
static const uint16_t mask[17]
Definition: lzw.c:37
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:99
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:179
Definition: graph2dot.c:48
uint8_t u8[4]
Definition: drawutils.h:65
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
uint8_t vsub_max
Definition: drawutils.h:57
#define FFMAX(a, b)
Definition: common.h:56
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:96
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:97
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
8bit gray, 8bit alpha
Definition: pixfmt.h:141
#define FFMIN(a, b)
Definition: common.h:58
t
Definition: genspecsines3.m:6
#define MAX_PLANES
Definition: ffv1.h:50
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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 format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
static void blend_line_hv(uint8_t *dst, int dst_delta, unsigned src, unsigned alpha, uint8_t *mask, int mask_linesize, int l2depth, int w, unsigned hsub, unsigned vsub, int xm, int left, int right, int hband)
Definition: drawutils.c:404
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
y2
Definition: lab5.m:34
static uint8_t * pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], int plane, int x, int y)
Definition: drawutils.c:206
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:33
static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
Decompose w pixels starting at x into start + (w starting at x) + end with x and w aligned on multipl...
Definition: drawutils.c:289
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
misc drawing utilities
#define PIX_FMT_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:93
unsigned nb_planes
Definition: drawutils.h:51
uint8_t flags
Definition: pixdesc.h:76
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
void * buf
Definition: avisynth_c.h:594
uint8_t hsub_max
Definition: drawutils.h:56
double value
Definition: eval.c:82
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
Definition: drawutils.c:331
void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4], uint8_t *src[4], int src_linesize[4], int pixelstep[4], int hsub, int vsub, int x, int y, int y2, int w, int h)
Definition: drawutils.c:115
uint16_t step_minus1
Number of elements between 2 horizontally consecutive pixels minus 1.
Definition: pixdesc.h:35
packed BGR 8:8:8, 32bpp, BGR0BGR0...
Definition: pixfmt.h:217
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:135
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
static int component_used(FFDrawContext *draw, int plane, int comp)
Definition: drawutils.c:301
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:103
#define PIX_FMT_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale)
Definition: pixdesc.h:94
static int flags
Definition: cpu.c:23
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:53
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:107
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:29
Y , 8bpp.
Definition: pixfmt.h:76
static double c[64]
#define PIX_FMT_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:102
static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, uint8_t *mask, int mask_linesize, int l2depth, unsigned w, unsigned h, unsigned shift, unsigned xm0)
Definition: drawutils.c:381
union FFDrawColor::@112 comp[MAX_PLANES]
function y
Definition: D.m:1
#define RGB_TO_Y_CCIR(r, g, b)
Definition: colorspace.h:99
#define PIX_FMT_PSEUDOPAL
The pixel format is "pseudo-paletted".
Definition: pixdesc.h:100
uint16_t offset_plus1
Number of elements before the component of the first pixel plus 1.
Definition: pixdesc.h:41
printf("static const uint8_t my_array[100] = {\n")
int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4], enum AVPixelFormat pix_fmt, uint8_t rgba_color[4], int *is_packed_rgba, uint8_t rgba_map_ptr[4])
Definition: drawutils.c:52
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int pixelstep[MAX_PLANES]
Definition: drawutils.h:52
A list of supported formats for one end of a filter link.
Definition: formats.h:64
const struct AVPixFmtDescriptor * desc
Definition: drawutils.h:49
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:236
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:237
uint8_t vsub[MAX_PLANES]
Definition: drawutils.h:55
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:71
void INT64 start
Definition: avisynth_c.h:594
int main(int argc, char **argv)
Definition: main.c:22
void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4], uint8_t *src[4], int pixelstep[4], int hsub, int vsub, int x, int y, int w, int h)
Definition: drawutils.c:95
packed RGB 8:8:8, 32bpp, 0RGB0RGB...
Definition: pixfmt.h:214
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
enum AVPixelFormat format
Definition: drawutils.h:50
uint8_t rgba[4]
Definition: drawutils.h:61