From 3409c7f2c9328386f225d49bfe65fc7b7b9a8c68 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 11 Jan 2018 00:45:23 +0000 Subject: [PATCH] Harden alpha blend tests and fix alpha_blend again. --- src/lib/image.cc | 58 ++++++++++++++++++++++++++++++++++++++-------- test/image_test.cc | 9 +++---- 2 files changed, 53 insertions(+), 14 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 other, Position position) break; } case AV_PIX_FMT_YUV420P10: + { + shared_ptr 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 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 other, Position 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; } } diff --git a/test/image_test.cc b/test/image_test.cc index b0bbe2594..299ef2e51 100644 --- a/test/image_test.cc +++ b/test/image_test.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2017 Carl Hetherington + Copyright (C) 2012-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -142,7 +142,7 @@ alpha_blend_test_one (AVPixelFormat format, string suffix) shared_ptr raw = proxy->image(); shared_ptr background = raw->convert_pixel_format (dcp::YUV_TO_RGB_REC709, format, true, false); - shared_ptr overlay (new Image (AV_PIX_FMT_BGRA, raw->size(), true)); + shared_ptr overlay (new Image (AV_PIX_FMT_BGRA, dcp::Size(431, 891), true)); overlay->make_transparent (); for (int y = 0; y < 128; ++y) { @@ -169,7 +169,7 @@ alpha_blend_test_one (AVPixelFormat format, string suffix) } } - background->alpha_blend (overlay, Position (0, 0)); + background->alpha_blend (overlay, Position (13, 17)); shared_ptr save = background->convert_pixel_format (dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, false, false); @@ -185,7 +185,8 @@ BOOST_AUTO_TEST_CASE (alpha_blend_test) alpha_blend_test_one (AV_PIX_FMT_RGBA, "rgba"); alpha_blend_test_one (AV_PIX_FMT_RGB48LE, "rgb48le"); alpha_blend_test_one (AV_PIX_FMT_YUV420P, "yuv420p"); - alpha_blend_test_one (AV_PIX_FMT_YUV420P10LE, "yuv420p10le"); + alpha_blend_test_one (AV_PIX_FMT_YUV420P10, "yuv420p10"); + alpha_blend_test_one (AV_PIX_FMT_YUV422P10LE, "yuv422p10le"); } /** Test merge (list) with a single image */ -- 2.30.2