Merge master.
[dcpomatic.git] / src / lib / image.cc
index 18ddbc98dc7bdbffa64a9f9f55185e1a5ab948a8..78e8bbb2a9cb6fbb48410cc873b9c72c0a60ad3e 100644 (file)
@@ -376,8 +376,18 @@ Image::make_black ()
 void
 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
 {
-       /* Only implemented for RGBA onto RGB24 so far */
-       assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
+       int this_bpp = 0;
+       int other_bpp = 0;
+
+       if (_pixel_format == PIX_FMT_BGRA && other->pixel_format() == PIX_FMT_RGBA) {
+               this_bpp = 4;
+               other_bpp = 4;
+       } else if (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA) {
+               this_bpp = 3;
+               other_bpp = 4;
+       } else {
+               assert (false);
+       }
 
        int start_tx = position.x;
        int start_ox = 0;
@@ -396,15 +406,15 @@ Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
        }
 
        for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
-               uint8_t* tp = data()[0] + ty * stride()[0] + position.x * 3;
+               uint8_t* tp = data()[0] + ty * stride()[0] + position.x * this_bpp;
                uint8_t* op = other->data()[0] + oy * other->stride()[0];
                for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
                        float const alpha = float (op[3]) / 255;
                        tp[0] = (tp[0] * (1 - alpha)) + op[0] * alpha;
                        tp[1] = (tp[1] * (1 - alpha)) + op[1] * alpha;
                        tp[2] = (tp[2] * (1 - alpha)) + op[2] * alpha;
-                       tp += 3;
-                       op += 4;
+                       tp += this_bpp;
+                       op += other_bpp;
                }
        }
 }
@@ -499,13 +509,13 @@ Image::Image (AVPixelFormat p, libdcp::Size s, bool aligned)
 void
 Image::allocate ()
 {
-       _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
+       _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
        _data[0] = _data[1] = _data[2] = _data[3] = 0;
        
-       _line_size = (int *) av_malloc (4 * sizeof (int));
+       _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
        _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
        
-       _stride = (int *) av_malloc (4 * sizeof (int));
+       _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
        _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
 
        for (int i = 0; i < components(); ++i) {
@@ -521,7 +531,7 @@ Image::allocate ()
                   seem to mind.  The nasty + 1 in this malloc makes sure there is always a byte
                   for that instruction to read safely.
                */
-               _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i) + 1);
+               _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
        }
 }