Round image line sizes up to 32. Seems to help with LHS image corruption with both...
[dcpomatic.git] / src / lib / image.cc
index 602b20842393b8845d85098f87dec6d278d89881..c8849303cac99e8ed01c1e6f6d5e80bffade6706 100644 (file)
@@ -207,6 +207,42 @@ Image::make_black ()
        }
 }
 
+void
+Image::alpha_blend (shared_ptr<Image> other, Position position)
+{
+       /* Only implemented for RGBA onto RGB24 so far */
+       assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA);
+
+       int start_tx = position.x;
+       int start_ox = 0;
+
+       if (start_tx < 0) {
+               start_ox = -start_tx;
+               start_tx = 0;
+       }
+
+       int start_ty = position.y;
+       int start_oy = 0;
+
+       if (start_ty < 0) {
+               start_oy = -start_ty;
+               start_ty = 0;
+       }
+
+       for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
+               uint8_t* tp = data()[0] + ty * line_size()[0] + position.x * 3;
+               uint8_t* op = other->data()[0] + oy * other->line_size()[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;
+               }
+       }
+}
+
 /** Construct a SimpleImage of a given size and format, allocating memory
  *  as required.
  *
@@ -217,20 +253,22 @@ SimpleImage::SimpleImage (PixelFormat p, Size s)
        : Image (p)
        , _size (s)
 {
-       _data = (uint8_t **) av_malloc (components() * sizeof (uint8_t *));
-       _line_size = (int *) av_malloc (components() * sizeof (int));
+       _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
+       _data[0] = _data[1] = _data[2] = _data[3] = 0;
+       _line_size = (int *) av_malloc (4);
+       _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
 
        switch (p) {
        case PIX_FMT_RGB24:
-               _line_size[0] = s.width * 3;
+               _line_size[0] = round_up (s.width * 3, 32);
                break;
        case PIX_FMT_RGBA:
-               _line_size[0] = s.width * 4;
+               _line_size[0] = round_up (s.width * 4, 32);
                break;
        case PIX_FMT_YUV420P:
-               _line_size[0] = s.width;
-               _line_size[1] = s.width / 2;
-               _line_size[2] = s.width / 2;
+               _line_size[0] = round_up (s.width, 32);
+               _line_size[1] = round_up (s.width / 2, 32);
+               _line_size[2] = round_up (s.width / 2, 32);
                break;
        default:
                assert (false);