80 int *is_packed_rgba,
uint8_t rgba_map_ptr[4])
93 if (*is_packed_rgba) {
95 for (i = 0; i < 4; i++)
96 dst_color[rgba_map[i]] = rgba_color[i];
101 for (i = 0; i < w; i++)
102 memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]);
104 memcpy(rgba_map_ptr, rgba_map,
sizeof(rgba_map[0]) * 4);
108 dst_color[0] =
RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
109 dst_color[1] =
RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
110 dst_color[2] =
RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
111 dst_color[3] = rgba_color[3];
113 for (plane = 0; plane < 4; plane++) {
115 int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
117 pixel_step[
plane] = 1;
121 while(plane && line[plane-1])
125 memset(line[plane], dst_color[plane], line_size);
134 int hsub,
int vsub,
int x,
int y,
int w,
int h)
139 for (plane = 0; plane < 4 && dst[
plane]; plane++) {
140 int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
141 int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
145 p = dst[
plane] + (y >> vsub1) * dst_linesize[plane];
146 for (i = 0; i <
height; i++) {
147 memcpy(p + (x >> hsub1) * pixelstep[plane],
148 src[plane], width * pixelstep[plane]);
149 p += dst_linesize[
plane];
155 uint8_t *
src[4],
int src_linesize[4],
int pixelstep[4],
156 int hsub,
int vsub,
int x,
int y,
int y2,
int w,
int h)
161 for (plane = 0; plane < 4 && dst[
plane]; plane++) {
162 int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
163 int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
167 p = dst[
plane] + (y >> vsub1) * dst_linesize[plane];
168 for (i = 0; i <
height; i++) {
169 memcpy(p + (x >> hsub1) * pixelstep[plane],
170 src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), width * pixelstep[plane]);
171 p += dst_linesize[
plane];
180 unsigned i, nb_planes = 0;
183 if (!desc || !desc->
name)
199 if (pixelstep[c->
plane] != 0 &&
202 if (pixelstep[c->
plane] == 6 &&
206 if (pixelstep[c->
plane] >= 8)
210 memset(draw, 0,
sizeof(*draw));
229 if (rgba != color->
rgba)
230 memcpy(color->
rgba, rgba,
sizeof(color->
rgba));
234 for (i = 0; i < 4; i++) {
235 color->
comp[0].
u8[rgba_map[i]] = rgba[i];
237 color->
comp[0].
u16[rgba_map[i]] = color->
comp[0].
u8[rgba_map[i]] << 8;
241 for (i = 0; i < 4; i++) {
242 color->
comp[rgba_map[i]].
u8[0] = rgba[i];
253 color->
comp[3].
u8[0] = rgba[3];
254 #define EXPAND(compn) \
255 if (desc->comp[compn].depth > 8) \
256 color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \
257 color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << \
258 (draw->desc->comp[compn].depth + draw->desc->comp[compn].shift - 8)
265 color->
comp[1].
u8[0] = rgba[3];
269 color->
comp[1].
u8[0] = rgba[3];
273 "Color conversion not implemented for %s\n", draw->
desc->
name);
274 memset(color, 128,
sizeof(*color));
279 int plane,
int x,
int y)
282 (y >> draw->
vsub[
plane]) * linesize[plane] +
287 uint8_t *dst[],
int dst_linesize[],
289 int dst_x,
int dst_y,
int src_x,
int src_y,
292 int plane, y, wp, hp;
295 for (plane = 0; plane < draw->
nb_planes; plane++) {
296 p =
pointer_at(draw, src, src_linesize, plane, src_x, src_y);
297 q =
pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
300 for (y = 0; y < hp; y++) {
302 p += src_linesize[
plane];
303 q += dst_linesize[
plane];
309 uint8_t *dst[],
int dst_linesize[],
310 int dst_x,
int dst_y,
int w,
int h)
312 int plane, x, y, wp, hp;
316 for (plane = 0; plane < draw->
nb_planes; plane++) {
317 p0 =
pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
330 for (x = 0; x < wp; x++) {
336 p = p0 + dst_linesize[
plane];
337 for (y = 1; y < hp; y++) {
339 p += dst_linesize[
plane];
370 int mask = (1 << sub) - 1;
372 *start = (-*x) & mask;
374 *start =
FFMIN(*start, *w);
382 return (draw->
comp_mask[plane] >> comp) & 1;
389 int dx,
int w,
unsigned hsub,
int left,
int right)
391 unsigned asrc = alpha *
src;
392 unsigned tau = 0x1010101 -
alpha;
396 unsigned suba = (left *
alpha) >> hsub;
397 *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
400 for (x = 0; x < w; x++) {
401 *dst = (*dst * tau + asrc) >> 24;
405 unsigned suba = (right *
alpha) >> hsub;
406 *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
411 int dx,
int w,
unsigned hsub,
int left,
int right)
413 unsigned asrc = alpha *
src;
414 unsigned tau = 0x10001 -
alpha;
418 unsigned suba = (left *
alpha) >> hsub;
420 AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
423 for (x = 0; x < w; x++) {
425 AV_WL16(dst, (value * tau + asrc) >> 16);
429 unsigned suba = (right *
alpha) >> hsub;
431 AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
436 uint8_t *dst[],
int dst_linesize[],
437 int dst_w,
int dst_h,
438 int x0,
int y0,
int w,
int h)
441 int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
447 if (w <= 0 || h <= 0 || !color->rgba[3])
451 alpha = 0x10203 * color->
rgba[3] + 0x2;
454 alpha = 0x101 * color->
rgba[3] + 0x2;
457 nb_planes += !nb_planes;
458 for (plane = 0; plane < nb_planes; plane++) {
460 p0 =
pointer_at(draw, dst, dst_linesize, plane, x0, y0);
467 for (comp = 0; comp < nb_comp; comp++) {
477 draw->
hsub[plane], left, right);
481 draw->
hsub[plane], left, right);
483 p += dst_linesize[
plane];
486 for (y = 0; y < h_sub; y++) {
489 draw->
hsub[plane], left, right);
490 p += dst_linesize[
plane];
493 for (y = 0; y < h_sub; y++) {
496 draw->
hsub[plane], left, right);
497 p += dst_linesize[
plane];
504 draw->
hsub[plane], left, right);
508 draw->
hsub[plane], left, right);
516 const uint8_t *
mask,
int mask_linesize,
int l2depth,
517 unsigned w,
unsigned h,
unsigned shift,
unsigned xm0)
519 unsigned xm, x, y, t = 0;
520 unsigned xmshf = 3 - l2depth;
521 unsigned xmmod = 7 >> l2depth;
522 unsigned mbits = (1 << (1 << l2depth)) - 1;
523 unsigned mmult = 255 / mbits;
526 for (y = 0; y <
h; y++) {
528 for (x = 0; x < w; x++) {
529 t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
533 mask += mask_linesize;
535 alpha = (t >>
shift) * alpha;
536 AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16);
540 const uint8_t *
mask,
int mask_linesize,
int l2depth,
541 unsigned w,
unsigned h,
unsigned shift,
unsigned xm0)
543 unsigned xm, x, y, t = 0;
544 unsigned xmshf = 3 - l2depth;
545 unsigned xmmod = 7 >> l2depth;
546 unsigned mbits = (1 << (1 << l2depth)) - 1;
547 unsigned mmult = 255 / mbits;
549 for (y = 0; y <
h; y++) {
551 for (x = 0; x < w; x++) {
552 t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
556 mask += mask_linesize;
558 alpha = (t >>
shift) * alpha;
559 *dst = ((0x1010101 -
alpha) * *dst + alpha * src) >> 24;
564 const uint8_t *
mask,
int mask_linesize,
int l2depth,
int w,
565 unsigned hsub,
unsigned vsub,
566 int xm,
int left,
int right,
int hband)
572 left, hband, hsub + vsub, xm);
576 for (x = 0; x < w; x++) {
578 1 << hsub, hband, hsub + vsub, xm);
584 right, hband, hsub + vsub, xm);
589 const uint8_t *
mask,
int mask_linesize,
int l2depth,
int w,
590 unsigned hsub,
unsigned vsub,
591 int xm,
int left,
int right,
int hband)
596 blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
597 left, hband, hsub + vsub, xm);
601 for (x = 0; x < w; x++) {
602 blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
603 1 << hsub, hband, hsub + vsub, xm);
608 blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
609 right, hband, hsub + vsub, xm);
613 uint8_t *dst[],
int dst_linesize[],
int dst_w,
int dst_h,
614 const uint8_t *
mask,
int mask_linesize,
int mask_w,
int mask_h,
615 int l2depth,
unsigned endianness,
int x0,
int y0)
618 int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
624 mask += ym0 * mask_linesize;
625 if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3])
630 alpha = (0x10307 * color->
rgba[3] + 0x3) >> 8;
632 alpha = (0x101 * color->
rgba[3] + 0x2) >> 8;
635 nb_planes += !nb_planes;
636 for (plane = 0; plane < nb_planes; plane++) {
638 p0 =
pointer_at(draw, dst, dst_linesize, plane, x0, y0);
645 for (comp = 0; comp < nb_comp; comp++) {
655 color->
comp[plane].
u8[comp], alpha,
656 m, mask_linesize, l2depth, w_sub,
657 draw->
hsub[plane], draw->
vsub[plane],
658 xm0, left, right, top);
661 color->
comp[plane].
u16[comp], alpha,
662 m, mask_linesize, l2depth, w_sub,
663 draw->
hsub[plane], draw->
vsub[plane],
664 xm0, left, right, top);
666 p += dst_linesize[
plane];
667 m += top * mask_linesize;
670 for (y = 0; y < h_sub; y++) {
672 color->
comp[plane].
u8[comp], alpha,
673 m, mask_linesize, l2depth, w_sub,
674 draw->
hsub[plane], draw->
vsub[plane],
675 xm0, left, right, 1 << draw->
vsub[plane]);
676 p += dst_linesize[
plane];
680 for (y = 0; y < h_sub; y++) {
682 color->
comp[plane].
u16[comp], alpha,
683 m, mask_linesize, l2depth, w_sub,
684 draw->
hsub[plane], draw->
vsub[plane],
685 xm0, left, right, 1 << draw->
vsub[plane]);
686 p += dst_linesize[
plane];
693 color->
comp[plane].
u8[comp], alpha,
694 m, mask_linesize, l2depth, w_sub,
695 draw->
hsub[plane], draw->
vsub[plane],
696 xm0, left, right, bottom);
699 color->
comp[plane].
u16[comp], alpha,
700 m, mask_linesize, l2depth, w_sub,
701 draw->
hsub[plane], draw->
vsub[plane],
702 xm0, left, right, bottom);
717 value += round_dir ? (1 <<
shift) - 1 : 1 << (shift - 1);
718 return (value >> shift) <<
shift;
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
int plane
Which of the 4 planes contains the component.
static enum AVPixelFormat pix_fmt
static int shift(int a, int b)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
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.
ptrdiff_t const GLvoid * data
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
#define AV_LOG_WARNING
Something somehow does not look correct.
packed RGB 8:8:8, 24bpp, RGBRGB...
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.
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Various defines for YUV<->RGB conversion.
Convenience header that includes libavutil's core.
planar GBR 4:4:4 36bpp, little-endian
static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
planar GBR 4:4:4 36bpp, big-endian
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
static void clip_interval(int wmax, int *x, int *w, int *dx)
Clip interval [x; x+w[ within [0; wmax[.
int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, int value)
Round a dimension according to subsampling.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
planar GBRA 4:4:4:4 64bpp, big-endian
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
static av_cold int end(AVCodecContext *avctx)
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
uint8_t comp_mask[MAX_PLANES]
planar GBR 4:4:4 48bpp, big-endian
planar GBR 4:4:4 27bpp, big-endian
static double alpha(void *priv, double x, double y)
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
static const uint16_t mask[17]
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
simple assert() macros that are a bit more flexible than ISO C assert().
static void blend_line_hv(uint8_t *dst, int dst_delta, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, int w, unsigned hsub, unsigned vsub, int xm, int left, int right, int hband)
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
planar GBR 4:4:4:4 48bpp, big-endian
uint8_t nb_components
The number of components each pixel has, (1-4)
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
static void blend_line_hv16(uint8_t *dst, int dst_delta, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, int w, unsigned hsub, unsigned vsub, int xm, int left, int right, int hband)
GLsizei GLboolean const GLfloat * value
#define AV_PIX_FMT_FLAG_PSEUDOPAL
The pixel format is "pseudo-paletted".
packed RGB 8:8:8, 24bpp, BGRBGR...
union FFDrawColor::@173 comp[MAX_PLANES]
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
static uint8_t * pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], int plane, int x, int y)
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
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...
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
planar GBR 4:4:4:4 48bpp, little-endian
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const 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.
static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, unsigned w, unsigned h, unsigned shift, unsigned xm0)
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
planar GBR 4:4:4 30bpp, big-endian
planar GBR 4:4:4 42bpp, little-endian
static const char * format
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.
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)
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
planar GBR 4:4:4 42bpp, big-endian
static int component_used(FFDrawContext *draw, int plane, int comp)
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
int offset
Number of elements before the component of the first pixel.
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
planar GBRA 4:4:4:4 32bpp
planar GBR 4:4:4 27bpp, little-endian
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, unsigned w, unsigned h, unsigned shift, unsigned xm0)
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
#define RGB_TO_Y_CCIR(r, g, b)
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])
Y , 16bpp, little-endian.
int pixelstep[MAX_PLANES]
16 bits gray, 16 bits alpha (little-endian)
const struct AVPixFmtDescriptor * desc
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.
planar GBR 4:4:4 48bpp, little-endian
#define av_malloc_array(a, b)
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)
int depth
Number of bits in the component.
planar GBRA 4:4:4:4 64bpp, little-endian
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
AVPixelFormat
Pixel format.
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
enum AVPixelFormat format
planar GBR 4:4:4 30bpp, little-endian
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
int step
Number of elements between 2 horizontally consecutive pixels.
#define AV_CEIL_RSHIFT(a, b)