From 71f4c72692a6c21b9f41273f93ecc97f0d595812 Mon Sep 17 00:00:00 2001
From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
Date: Fri, 20 Jun 2014 20:28:55 +0300
Subject: [PATCH] Issue #3302 fix WIP
---
libavfilter/drawutils.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
index 4437c2c..8b6a738 100644
|
a
|
b
|
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
|
| 182 | 182 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); |
| 183 | 183 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; |
| 184 | 184 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; |
| 185 | | for (i = 0; i < ((desc->nb_components - 1) | 1); i++) |
| | 185 | for (i = 0; i < desc->nb_components; i++) |
| 186 | 186 | draw->comp_mask[desc->comp[i].plane] |= |
| 187 | 187 | 1 << (desc->comp[i].offset_plus1 - 1); |
| 188 | 188 | return 0; |
| … |
… |
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
|
| 397 | 397 | |
| 398 | 398 | static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, |
| 399 | 399 | uint8_t *mask, int mask_linesize, int l2depth, |
| 400 | | unsigned w, unsigned h, unsigned shift, unsigned xm0) |
| | 400 | unsigned w, unsigned h, unsigned shift, unsigned xm0, int strategy) |
| 401 | 401 | { |
| | 402 | if (strategy == 1) { |
| | 403 | /* Reverting expression: alpha = (0x10307 * color->rgba[3] + 0x3) >> 8 */ |
| | 404 | *dst = ((alpha << 8) - 0x3) / 0x10307; |
| | 405 | return; |
| | 406 | } |
| 402 | 407 | unsigned xm, x, y, t = 0; |
| 403 | 408 | unsigned xmshf = 3 - l2depth; |
| 404 | 409 | unsigned xmmod = 7 >> l2depth; |
| … |
… |
static void blend_line_hv(uint8_t *dst, int dst_delta,
|
| 422 | 427 | unsigned src, unsigned alpha, |
| 423 | 428 | uint8_t *mask, int mask_linesize, int l2depth, int w, |
| 424 | 429 | unsigned hsub, unsigned vsub, |
| 425 | | int xm, int left, int right, int hband) |
| | 430 | int xm, int left, int right, int hband, int strategy) |
| 426 | 431 | { |
| 427 | 432 | int x; |
| 428 | 433 | |
| 429 | 434 | if (left) { |
| 430 | 435 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, |
| 431 | | left, hband, hsub + vsub, xm); |
| | 436 | left, hband, hsub + vsub, xm, strategy); |
| 432 | 437 | dst += dst_delta; |
| 433 | 438 | xm += left; |
| 434 | 439 | } |
| 435 | 440 | for (x = 0; x < w; x++) { |
| 436 | 441 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, |
| 437 | | 1 << hsub, hband, hsub + vsub, xm); |
| | 442 | 1 << hsub, hband, hsub + vsub, xm, strategy); |
| 438 | 443 | dst += dst_delta; |
| 439 | 444 | xm += 1 << hsub; |
| 440 | 445 | } |
| 441 | 446 | if (right) |
| 442 | 447 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, |
| 443 | | right, hband, hsub + vsub, xm); |
| | 448 | right, hband, hsub + vsub, xm, strategy); |
| 444 | 449 | } |
| 445 | 450 | |
| 446 | 451 | void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, |
| 447 | 452 | uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, |
| 448 | 453 | uint8_t *mask, int mask_linesize, int mask_w, int mask_h, |
| 449 | | int l2depth, unsigned endianness, int x0, int y0) |
| | 454 | int l2depth, unsigned endianness, int x0, int y0 /* TODO , int strategy */) |
| 450 | 455 | { |
| 451 | 456 | unsigned alpha, nb_planes, nb_comp, plane, comp; |
| 452 | 457 | int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; |
| … |
… |
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
| 475 | 480 | continue; |
| 476 | 481 | p = p0 + comp; |
| 477 | 482 | m = mask; |
| | 483 | /* Treat alpha component specially. TODO Support more cases */ |
| | 484 | int strategy = 0 /* use existing algorithm */; |
| | 485 | if (draw->format == AV_PIX_FMT_RGBA && comp == 3) |
| | 486 | strategy = 1 /* just set *dst to alpha */; |
| | 487 | |
| 478 | 488 | if (top) { |
| 479 | 489 | blend_line_hv(p, draw->pixelstep[plane], |
| 480 | 490 | color->comp[plane].u8[comp], alpha, |
| 481 | 491 | m, mask_linesize, l2depth, w_sub, |
| 482 | 492 | draw->hsub[plane], draw->vsub[plane], |
| 483 | | xm0, left, right, top); |
| | 493 | xm0, left, right, top, strategy); |
| 484 | 494 | p += dst_linesize[plane]; |
| 485 | 495 | m += top * mask_linesize; |
| 486 | 496 | } |
| … |
… |
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
| 489 | 499 | color->comp[plane].u8[comp], alpha, |
| 490 | 500 | m, mask_linesize, l2depth, w_sub, |
| 491 | 501 | draw->hsub[plane], draw->vsub[plane], |
| 492 | | xm0, left, right, 1 << draw->vsub[plane]); |
| | 502 | xm0, left, right, 1 << draw->vsub[plane], strategy); |
| 493 | 503 | p += dst_linesize[plane]; |
| 494 | 504 | m += mask_linesize << draw->vsub[plane]; |
| 495 | 505 | } |
| … |
… |
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
|
| 498 | 508 | color->comp[plane].u8[comp], alpha, |
| 499 | 509 | m, mask_linesize, l2depth, w_sub, |
| 500 | 510 | draw->hsub[plane], draw->vsub[plane], |
| 501 | | xm0, left, right, bottom); |
| | 511 | xm0, left, right, bottom, strategy); |
| 502 | 512 | } |
| 503 | 513 | } |
| 504 | 514 | } |