| @@ -137,66 +137,49 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) · 136 unmodified lines |
| 137 | 137 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); |
| 138 | 138 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; |
| 139 | 139 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; |
| 140 | | − for (i = 0; i < (desc->nb_components - !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(flags & FF_DRAW_PROCESS_ALPHA))); i++) |
| 141 | | − draw->comp_mask[desc->comp[i].plane] |= |
| 142 | | − 1 << desc->comp[i].offset; |
| 143 | 140 | return 0; |
| 144 | 141 | } |
| 145 | 142 | |
| 146 | 143 | void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) |
| 147 | 144 | { |
| 148 | 145 | unsigned i; |
| 149 | | − uint8_t rgba_map[4]; |
| 146 | + uint8_t tmp8[4]; |
| 147 | + const AVPixFmtDescriptor *desc = draw->desc; |
| 150 | 148 | |
| 151 | 149 | if (rgba != color->rgba) |
| 152 | 150 | memcpy(color->rgba, rgba, sizeof(color->rgba)); |
| 153 | | − if ((draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && |
| 154 | | − ff_fill_rgba_map(rgba_map, draw->format) >= 0) { |
| 155 | | − if (draw->nb_planes == 1) { |
| 156 | | − for (i = 0; i < 4; i++) { |
| 157 | | − color->comp[0].u8[rgba_map[i]] = rgba[i]; |
| 158 | | − if (draw->desc->comp[rgba_map[i]].depth > 8) { |
| 159 | | − color->comp[0].u16[rgba_map[i]] = color->comp[0].u8[rgba_map[i]] << 8; |
| 160 | | − } |
| 161 | | − } |
| 162 | | − } else { |
| 163 | | − for (i = 0; i < 4; i++) { |
| 164 | | − color->comp[rgba_map[i]].u8[0] = rgba[i]; |
| 165 | | − if (draw->desc->comp[rgba_map[i]].depth > 8) |
| 166 | | − color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8); |
| 167 | | − } |
| 168 | | − } |
| 151 | + |
| 152 | + memset(color->comp, 0, sizeof(color->comp)); |
| 153 | + |
| 154 | + if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) { |
| 155 | + memcpy(tmp8, rgba, sizeof(tmp8)); |
| 169 | 156 | } else if (draw->nb_planes >= 2) { |
| 170 | 157 | /* assume YUV */ |
| 171 | | − const AVPixFmtDescriptor *desc = draw->desc; |
| 172 | | − color->comp[desc->comp[0].plane].u8[desc->comp[0].offset] = draw->full_range ? RGB_TO_Y_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); |
| 173 | | − color->comp[desc->comp[1].plane].u8[desc->comp[1].offset] = draw->full_range ? RGB_TO_U_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0); |
| 174 | | − color->comp[desc->comp[2].plane].u8[desc->comp[2].offset] = draw->full_range ? RGB_TO_V_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0); |
| 175 | | − color->comp[3].u8[0] = rgba[3]; |
| 176 | | −#define EXPAND(compn) \ |
| 177 | | − if (desc->comp[compn].depth > 8) \ |
| 178 | | − color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \ |
| 179 | | − color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << \ |
| 180 | | − (draw->desc->comp[compn].depth + draw->desc->comp[compn].shift - 8) |
| 181 | | − EXPAND(3); |
| 182 | | − EXPAND(2); |
| 183 | | − EXPAND(1); |
| 184 | | − EXPAND(0); |
| 158 | + tmp8[0] = draw->full_range ? RGB_TO_Y_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); |
| 159 | + tmp8[1] = draw->full_range ? RGB_TO_U_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0); |
| 160 | + tmp8[2] = draw->full_range ? RGB_TO_V_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0); |
| 161 | + tmp8[3] = rgba[3]; |
| 185 | 162 | } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A || |
| 186 | 163 | draw->format == AV_PIX_FMT_GRAY16LE || draw->format == AV_PIX_FMT_YA16LE || |
| 187 | 164 | draw->format == AV_PIX_FMT_GRAY9LE || |
| 188 | 165 | draw->format == AV_PIX_FMT_GRAY10LE || |
| 189 | 166 | draw->format == AV_PIX_FMT_GRAY12LE || |
| 190 | 167 | draw->format == AV_PIX_FMT_GRAY14LE) { |
| 191 | | − const AVPixFmtDescriptor *desc = draw->desc; |
| 192 | | − color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); |
| 193 | | − EXPAND(0); |
| 194 | | − color->comp[1].u8[0] = rgba[3]; |
| 195 | | − EXPAND(1); |
| 168 | + tmp8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); |
| 169 | + tmp8[1] = rgba[3]; |
| 196 | 170 | } else { |
| 197 | 171 | av_log(NULL, AV_LOG_WARNING, |
| 198 | 172 | "Color conversion not implemented for %s\n", draw->desc->name); |
| 199 | 173 | memset(color, 128, sizeof(*color)); |
| 174 | + return; |
| 175 | + } |
| 176 | + |
| 177 | + for (i = 0; i < desc->nb_components; i++) { |
| 178 | + if (desc->comp[i].depth > 8) |
| 179 | + color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = tmp8[i] << |
| 180 | + (draw->desc->comp[i].depth + draw->desc->comp[i].shift - 8); |
| 181 | + else |
| 182 | + color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = tmp8[i]; |
| 200 | 183 | } |
| 201 | 184 | } |
| 202 | 185 | |
| @@ -302,11 +285,6 @@ static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end) · 99 unmodified lines |
| 302 | 285 | *w >>= sub; |
| 303 | 286 | } |
| 304 | 287 | |
| 305 | | −static int component_used(FFDrawContext *draw, int plane, int comp) |
| 306 | | −{ |
| 307 | | − return (draw->comp_mask[plane] >> comp) & 1; |
| 308 | | −} |
| 309 | | − |
| 310 | 288 | /* If alpha is in the [ 0 ; 0x1010101 ] range, |
| 311 | 289 | then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range, |
| 312 | 290 | and >> 24 gives a correct rounding. */ |
| @@ -366,6 +344,9 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, · 53 unmodified lines |
| 366 | 344 | int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; |
| 367 | 345 | uint8_t *p0, *p; |
| 368 | 346 | |
| 347 | + nb_comp = draw->desc->nb_components - |
| 348 | + !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
| 349 | + |
| 369 | 350 | /* TODO optimize if alpha = 0xFF */ |
| 370 | 351 | clip_interval(dst_w, &x0, &w, NULL); |
| 371 | 352 | clip_interval(dst_h, &y0, &h, NULL); |
| @@ -381,7 +362,6 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, · 9 unmodified lines |
| 381 | 362 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
| 382 | 363 | nb_planes += !nb_planes; |
| 383 | 364 | for (plane = 0; plane < nb_planes; plane++) { |
| 384 | | − nb_comp = draw->pixelstep[plane]; |
| 385 | 365 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); |
| 386 | 366 | w_sub = w; |
| 387 | 367 | h_sub = h; |
| @@ -391,17 +371,19 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, · 3 unmodified lines |
| 391 | 371 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); |
| 392 | 372 | for (comp = 0; comp < nb_comp; comp++) { |
| 393 | 373 | const int depth = draw->desc->comp[comp].depth; |
| 374 | + const int offset = draw->desc->comp[comp].offset; |
| 375 | + const int index = offset / ((depth + 7) / 8); |
| 394 | 376 | |
| 395 | | − if (!component_used(draw, plane, comp)) |
| 377 | + if (draw->desc->comp[comp].plane != plane) |
| 396 | 378 | continue; |
| 397 | | − p = p0 + comp; |
| 379 | + p = p0 + offset; |
| 398 | 380 | if (top) { |
| 399 | 381 | if (depth <= 8) { |
| 400 | | − blend_line(p, color->comp[plane].u8[comp], alpha >> 1, |
| 382 | + blend_line(p, color->comp[plane].u8[index], alpha >> 1, |
| 401 | 383 | draw->pixelstep[plane], w_sub, |
| 402 | 384 | draw->hsub[plane], left, right); |
| 403 | 385 | } else { |
| 404 | | − blend_line16(p, color->comp[plane].u16[comp], alpha >> 1, |
| 386 | + blend_line16(p, color->comp[plane].u16[index], alpha >> 1, |
| 405 | 387 | draw->pixelstep[plane], w_sub, |
| 406 | 388 | draw->hsub[plane], left, right); |
| 407 | 389 | } |
| @@ -409,14 +391,14 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, · 1 unmodified line |
| 409 | 391 | } |
| 410 | 392 | if (depth <= 8) { |
| 411 | 393 | for (y = 0; y < h_sub; y++) { |
| 412 | | − blend_line(p, color->comp[plane].u8[comp], alpha, |
| 394 | + blend_line(p, color->comp[plane].u8[index], alpha, |
| 413 | 395 | draw->pixelstep[plane], w_sub, |
| 414 | 396 | draw->hsub[plane], left, right); |
| 415 | 397 | p += dst_linesize[plane]; |
| 416 | 398 | } |
| 417 | 399 | } else { |
| 418 | 400 | for (y = 0; y < h_sub; y++) { |
| 419 | | − blend_line16(p, color->comp[plane].u16[comp], alpha, |
| 401 | + blend_line16(p, color->comp[plane].u16[index], alpha, |
| 420 | 402 | draw->pixelstep[plane], w_sub, |
| 421 | 403 | draw->hsub[plane], left, right); |
| 422 | 404 | p += dst_linesize[plane]; |
| @@ -424,11 +406,11 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, · 1 unmodified line |
| 424 | 406 | } |
| 425 | 407 | if (bottom) { |
| 426 | 408 | if (depth <= 8) { |
| 427 | | − blend_line(p, color->comp[plane].u8[comp], alpha >> 1, |
| 409 | + blend_line(p, color->comp[plane].u8[index], alpha >> 1, |
| 428 | 410 | draw->pixelstep[plane], w_sub, |
| 429 | 411 | draw->hsub[plane], left, right); |
| 430 | 412 | } else { |
| 431 | | − blend_line16(p, color->comp[plane].u16[comp], alpha >> 1, |
| 413 | + blend_line16(p, color->comp[plane].u16[index], alpha >> 1, |
| 432 | 414 | draw->pixelstep[plane], w_sub, |
| 433 | 415 | draw->hsub[plane], left, right); |
| 434 | 416 | } |
| @@ -544,6 +526,9 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 109 unmodified lines |
| 544 | 526 | uint8_t *p0, *p; |
| 545 | 527 | const uint8_t *m; |
| 546 | 528 | |
| 529 | + nb_comp = draw->desc->nb_components - |
| 530 | + !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
| 531 | + |
| 547 | 532 | clip_interval(dst_w, &x0, &mask_w, &xm0); |
| 548 | 533 | clip_interval(dst_h, &y0, &mask_h, &ym0); |
| 549 | 534 | mask += ym0 * mask_linesize; |
| @@ -559,7 +544,6 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 9 unmodified lines |
| 559 | 544 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
| 560 | 545 | nb_planes += !nb_planes; |
| 561 | 546 | for (plane = 0; plane < nb_planes; plane++) { |
| 562 | | − nb_comp = draw->pixelstep[plane]; |
| 563 | 547 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); |
| 564 | 548 | w_sub = mask_w; |
| 565 | 549 | h_sub = mask_h; |
| @@ -569,21 +553,23 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 3 unmodified lines |
| 569 | 553 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); |
| 570 | 554 | for (comp = 0; comp < nb_comp; comp++) { |
| 571 | 555 | const int depth = draw->desc->comp[comp].depth; |
| 556 | + const int offset = draw->desc->comp[comp].offset; |
| 557 | + const int index = offset / ((depth + 7) / 8); |
| 572 | 558 | |
| 573 | | − if (!component_used(draw, plane, comp)) |
| 559 | + if (draw->desc->comp[comp].plane != plane) |
| 574 | 560 | continue; |
| 575 | | − p = p0 + comp; |
| 561 | + p = p0 + offset; |
| 576 | 562 | m = mask; |
| 577 | 563 | if (top) { |
| 578 | 564 | if (depth <= 8) { |
| 579 | 565 | blend_line_hv(p, draw->pixelstep[plane], |
| 580 | | − color->comp[plane].u8[comp], alpha, |
| 566 | + color->comp[plane].u8[index], alpha, |
| 581 | 567 | m, mask_linesize, l2depth, w_sub, |
| 582 | 568 | draw->hsub[plane], draw->vsub[plane], |
| 583 | 569 | xm0, left, right, top); |
| 584 | 570 | } else { |
| 585 | 571 | blend_line_hv16(p, draw->pixelstep[plane], |
| 586 | | − color->comp[plane].u16[comp], alpha, |
| 572 | + color->comp[plane].u16[index], alpha, |
| 587 | 573 | m, mask_linesize, l2depth, w_sub, |
| 588 | 574 | draw->hsub[plane], draw->vsub[plane], |
| 589 | 575 | xm0, left, right, top); |
| @@ -594,7 +580,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 4 unmodified lines |
| 594 | 580 | if (depth <= 8) { |
| 595 | 581 | for (y = 0; y < h_sub; y++) { |
| 596 | 582 | blend_line_hv(p, draw->pixelstep[plane], |
| 597 | | − color->comp[plane].u8[comp], alpha, |
| 583 | + color->comp[plane].u8[index], alpha, |
| 598 | 584 | m, mask_linesize, l2depth, w_sub, |
| 599 | 585 | draw->hsub[plane], draw->vsub[plane], |
| 600 | 586 | xm0, left, right, 1 << draw->vsub[plane]); |
| @@ -604,7 +590,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 3 unmodified lines |
| 604 | 590 | } else { |
| 605 | 591 | for (y = 0; y < h_sub; y++) { |
| 606 | 592 | blend_line_hv16(p, draw->pixelstep[plane], |
| 607 | | − color->comp[plane].u16[comp], alpha, |
| 593 | + color->comp[plane].u16[index], alpha, |
| 608 | 594 | m, mask_linesize, l2depth, w_sub, |
| 609 | 595 | draw->hsub[plane], draw->vsub[plane], |
| 610 | 596 | xm0, left, right, 1 << draw->vsub[plane]); |
| @@ -615,13 +601,13 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, · 4 unmodified lines |
| 615 | 601 | if (bottom) { |
| 616 | 602 | if (depth <= 8) { |
| 617 | 603 | blend_line_hv(p, draw->pixelstep[plane], |
| 618 | | − color->comp[plane].u8[comp], alpha, |
| 604 | + color->comp[plane].u8[index], alpha, |
| 619 | 605 | m, mask_linesize, l2depth, w_sub, |
| 620 | 606 | draw->hsub[plane], draw->vsub[plane], |
| 621 | 607 | xm0, left, right, bottom); |
| 622 | 608 | } else { |
| 623 | 609 | blend_line_hv16(p, draw->pixelstep[plane], |
| 624 | | − color->comp[plane].u16[comp], alpha, |
| 610 | + color->comp[plane].u16[index], alpha, |
| 625 | 611 | m, mask_linesize, l2depth, w_sub, |
| 626 | 612 | draw->hsub[plane], draw->vsub[plane], |
| 627 | 613 | xm0, left, right, bottom); |