Browse code

Fix blend_subrect to respect the boundaries of the destination image

Originally committed as revision 10019 to svn://svn.ffmpeg.org/ffmpeg/trunk

Reimar Döffinger authored on 2007/08/10 01:15:59
Showing 1 changed files
... ...
@@ -422,31 +422,36 @@ void fill_border(VideoState *s, int x, int y, int w, int h, int color)
422 422
 
423 423
 #define BPP 1
424 424
 
425
-static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
425
+static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
426 426
 {
427 427
     int wrap, wrap3, width2, skip2;
428 428
     int y, u, v, a, u1, v1, a1, w, h;
429 429
     uint8_t *lum, *cb, *cr;
430 430
     const uint8_t *p;
431 431
     const uint32_t *pal;
432
-
433
-    lum = dst->data[0] + rect->y * dst->linesize[0];
434
-    cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
435
-    cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
436
-
437
-    width2 = (rect->w + 1) >> 1;
438
-    skip2 = rect->x >> 1;
432
+    int dstx, dsty, dstw, dsth;
433
+
434
+    dstx = FFMIN(FFMAX(rect->x, 0), imgw);
435
+    dstw = FFMIN(FFMAX(rect->w, 0), imgw - dstx);
436
+    dsty = FFMIN(FFMAX(rect->y, 0), imgh);
437
+    dsth = FFMIN(FFMAX(rect->h, 0), imgh - dsty);
438
+    lum = dst->data[0] + dsty * dst->linesize[0];
439
+    cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
440
+    cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
441
+
442
+    width2 = (dstw + 1) >> 1;
443
+    skip2 = dstx >> 1;
439 444
     wrap = dst->linesize[0];
440 445
     wrap3 = rect->linesize;
441 446
     p = rect->bitmap;
442 447
     pal = rect->rgba_palette;  /* Now in YCrCb! */
443 448
 
444
-    if (rect->y & 1) {
445
-        lum += rect->x;
449
+    if (dsty & 1) {
450
+        lum += dstx;
446 451
         cb += skip2;
447 452
         cr += skip2;
448 453
 
449
-        if (rect->x & 1) {
454
+        if (dstx & 1) {
450 455
             YUVA_IN(y, u, v, a, p, pal);
451 456
             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
452 457
             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
... ...
@@ -456,7 +461,7 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
456 456
             lum++;
457 457
             p += BPP;
458 458
         }
459
-        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
459
+        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
460 460
             YUVA_IN(y, u, v, a, p, pal);
461 461
             u1 = u;
462 462
             v1 = v;
... ...
@@ -481,17 +486,17 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
481 481
             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
482 482
             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
483 483
         }
484
-        p += wrap3 + (wrap3 - rect->w * BPP);
485
-        lum += wrap + (wrap - rect->w - rect->x);
484
+        p += wrap3 + (wrap3 - dstw * BPP);
485
+        lum += wrap + (wrap - dstw - dstx);
486 486
         cb += dst->linesize[1] - width2 - skip2;
487 487
         cr += dst->linesize[2] - width2 - skip2;
488 488
     }
489
-    for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
490
-        lum += rect->x;
489
+    for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
490
+        lum += dstx;
491 491
         cb += skip2;
492 492
         cr += skip2;
493 493
 
494
-        if (rect->x & 1) {
494
+        if (dstx & 1) {
495 495
             YUVA_IN(y, u, v, a, p, pal);
496 496
             u1 = u;
497 497
             v1 = v;
... ...
@@ -511,7 +516,7 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
511 511
             p += -wrap3 + BPP;
512 512
             lum += -wrap + 1;
513 513
         }
514
-        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
514
+        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
515 515
             YUVA_IN(y, u, v, a, p, pal);
516 516
             u1 = u;
517 517
             v1 = v;
... ...
@@ -566,18 +571,18 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
566 566
             p += -wrap3 + BPP;
567 567
             lum += -wrap + 1;
568 568
         }
569
-        p += wrap3 + (wrap3 - rect->w * BPP);
570
-        lum += wrap + (wrap - rect->w - rect->x);
569
+        p += wrap3 + (wrap3 - dstw * BPP);
570
+        lum += wrap + (wrap - dstw - dstx);
571 571
         cb += dst->linesize[1] - width2 - skip2;
572 572
         cr += dst->linesize[2] - width2 - skip2;
573 573
     }
574 574
     /* handle odd height */
575 575
     if (h) {
576
-        lum += rect->x;
576
+        lum += dstx;
577 577
         cb += skip2;
578 578
         cr += skip2;
579 579
 
580
-        if (rect->x & 1) {
580
+        if (dstx & 1) {
581 581
             YUVA_IN(y, u, v, a, p, pal);
582 582
             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
583 583
             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
... ...
@@ -587,7 +592,7 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
587 587
             lum++;
588 588
             p += BPP;
589 589
         }
590
-        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
590
+        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
591 591
             YUVA_IN(y, u, v, a, p, pal);
592 592
             u1 = u;
593 593
             v1 = v;
... ...
@@ -705,7 +710,8 @@ static void video_image_display(VideoState *is)
705 705
                     pict.linesize[2] = vp->bmp->pitches[1];
706 706
 
707 707
                     for (i = 0; i < sp->sub.num_rects; i++)
708
-                        blend_subrect(&pict, &sp->sub.rects[i]);
708
+                        blend_subrect(&pict, &sp->sub.rects[i],
709
+                                      vp->bmp->w, vp->bmp->h);
709 710
 
710 711
                     SDL_UnlockYUVOverlay (vp->bmp);
711 712
                 }