Fix Image::alpha_blend for 48-bit RGB.
authorCarl Hetherington <cth@carlh.net>
Sat, 25 Oct 2014 22:51:09 +0000 (23:51 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 25 Oct 2014 22:51:09 +0000 (23:51 +0100)
src/lib/image.cc

index bc64ba3b82373cb34bce1aff4e0f450d93ce5b29..3c67690685d68954785fcf2a38d32faf5ea4b0fa 100644 (file)
@@ -364,19 +364,6 @@ Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
        assert (other->pixel_format() == PIX_FMT_RGBA);
        int const other_bpp = 4;
 
-       int this_bpp = 0;
-       switch (_pixel_format) {
-       case PIX_FMT_BGRA:
-       case PIX_FMT_RGBA:
-               this_bpp = 4;
-               break;
-       case PIX_FMT_RGB24:
-               this_bpp = 3;
-               break;
-       default:
-               assert (false);
-       }
-
        int start_tx = position.x;
        int start_ox = 0;
 
@@ -393,22 +380,69 @@ Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
                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 * stride()[0] + start_tx * 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] = op[0] + (tp[0] * (1 - alpha));
-                       tp[1] = op[1] + (tp[1] * (1 - alpha));
-                       tp[2] = op[2] + (tp[2] * (1 - alpha));
-                       tp[3] = op[3] + (tp[3] * (1 - alpha));
-                       
-                       tp += this_bpp;
-                       op += other_bpp;
+       switch (_pixel_format) {
+       case PIX_FMT_RGB24:
+       {
+               int const this_bpp = 3;
+               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] + start_tx * 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] = op[0] + (tp[0] * (1 - alpha));
+                               tp[1] = op[1] + (tp[1] * (1 - alpha));
+                               tp[2] = op[2] + (tp[2] * (1 - alpha));
+                               
+                               tp += this_bpp;
+                               op += other_bpp;
+                       }
                }
+               break;
+       }
+       case PIX_FMT_BGRA:
+       case PIX_FMT_RGBA:
+       {
+               int const this_bpp = 4;
+               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] + start_tx * 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] = op[0] + (tp[0] * (1 - alpha));
+                               tp[1] = op[1] + (tp[1] * (1 - alpha));
+                               tp[2] = op[2] + (tp[2] * (1 - alpha));
+                               tp[3] = op[3] + (tp[3] * (1 - alpha));
+                               
+                               tp += this_bpp;
+                               op += other_bpp;
+                       }
+               }
+               break;
+       }
+       case PIX_FMT_RGB48LE:
+       {
+               int const this_bpp = 6;
+               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] + start_tx * 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;
+                               /* Blend high bytes */
+                               tp[1] = op[0] + (tp[1] * (1 - alpha));
+                               tp[3] = op[1] + (tp[3] * (1 - alpha));
+                               tp[5] = op[2] + (tp[5] * (1 - alpha));
+                               
+                               tp += this_bpp;
+                               op += other_bpp;
+                       }
+               }
+               break;
+       }
+       default:
+               assert (false);
        }
 }
-
+       
 void
 Image::copy (shared_ptr<const Image> other, Position<int> position)
 {