summaryrefslogtreecommitdiff
path: root/src/lib/image.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-01-11 00:45:23 +0000
committerCarl Hetherington <cth@carlh.net>2018-01-11 00:45:23 +0000
commit3409c7f2c9328386f225d49bfe65fc7b7b9a8c68 (patch)
treec835f5b201f92af36cb0e99f2608686b4e47fb21 /src/lib/image.cc
parentd8abf12da18f85d212cd8d783eb86be5c8fc4810 (diff)
Harden alpha blend tests and fix alpha_blend again.
Diffstat (limited to 'src/lib/image.cc')
-rw-r--r--src/lib/image.cc58
1 files changed, 48 insertions, 10 deletions
diff --git a/src/lib/image.cc b/src/lib/image.cc
index cb03e1a73..c3795dfa2 100644
--- a/src/lib/image.cc
+++ b/src/lib/image.cc
@@ -607,18 +607,52 @@ Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
break;
}
case AV_PIX_FMT_YUV420P10:
+ {
+ shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
+ dcp::Size const ts = size();
+ dcp::Size const os = yuv->size();
+ for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
+ int const hty = ty / 2;
+ int const hoy = oy / 2;
+ uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
+ uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
+ uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
+ uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
+ uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
+ uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
+ uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
+ for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
+ float const a = float(alpha[3]) / 255;
+ *tY = *oY * a + *tY * (1 - a);
+ *tU = *oU * a + *tU * (1 - a);
+ *tV = *oV * a + *tV * (1 - a);
+ ++tY;
+ ++oY;
+ if (tx % 2) {
+ ++tU;
+ ++tV;
+ }
+ if (ox % 2) {
+ ++oU;
+ ++oV;
+ }
+ alpha += 4;
+ }
+ }
+ break;
+ }
case AV_PIX_FMT_YUV422P10LE:
{
shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
dcp::Size const ts = size();
dcp::Size const os = yuv->size();
for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
- uint16_t* tY = (uint16_t *) (data()[0] + (ty * stride()[0])) + start_tx;
- uint8_t* tU = data()[1] + (ty * stride()[1]) + start_tx;
- uint8_t* tV = data()[2] + (ty * stride()[2]) + start_tx;
- uint16_t* oY = (uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0])) + start_ox;
- uint8_t* oU = yuv->data()[1] + (oy * yuv->stride()[1]) + start_ox;
- uint8_t* oV = yuv->data()[2] + (oy * yuv->stride()[2]) + start_ox;
+ uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
+ uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
+ uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
+ uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
+ uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
+ uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
float const a = float(alpha[3]) / 255;
@@ -626,11 +660,15 @@ Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
*tU = *oU * a + *tU * (1 - a);
*tV = *oV * a + *tV * (1 - a);
++tY;
- ++tU;
- ++tV;
++oY;
- ++oU;
- ++oV;
+ if (tx % 2) {
+ ++tU;
+ ++tV;
+ }
+ if (ox % 2) {
+ ++oU;
+ ++oV;
+ }
alpha += 4;
}
}