Skip to content

Commit

Permalink
Core (Tests): Add test for LV::VideoBlit::blit_overlay_alphasrc().
Browse files Browse the repository at this point in the history
  • Loading branch information
kaixiong committed Feb 5, 2023
1 parent a36b1de commit 61bdede
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 2 deletions.
2 changes: 1 addition & 1 deletion libvisual/cmake/LVBuildTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FUNCTION(LV_BUILD_TEST TEST_NAME)

TARGET_LINK_LIBRARIES(${TEST_NAME}
PRIVATE
libvisual
test_common
Threads::Threads
${PARSED_ARGS_LINK_LIBS}
)
Expand Down
8 changes: 7 additions & 1 deletion libvisual/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
INCLUDE(LVBuildTest)

INCLUDE_DIRECTORIES(
ADD_LIBRARY(test_common STATIC
random.cpp
)

TARGET_INCLUDE_DIRECTORIES(test_common PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

TARGET_LINK_LIBRARIES(test_common PUBLIC libvisual)

ADD_SUBDIRECTORY(audio_test)
ADD_SUBDIRECTORY(video_test)
ADD_SUBDIRECTORY(time_test)
32 changes: 32 additions & 0 deletions libvisual/tests/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "random.hpp"
#include <random>

namespace LV::Tests
{
LV::VideoPtr create_random_video (int width, int height, VisVideoDepth depth)
{
std::random_device device {};
std::uniform_int_distribution<uint8_t> distrib {0, 255};

auto video {LV::Video::create (width, height, depth)};

auto bytes_per_pixel = video->get_bpp ();
auto pitch = video->get_pitch ();

auto content_bytes_per_row = bytes_per_pixel * video->get_width ();

auto pixel_row_ptr = static_cast<uint8_t *>(video->get_pixels ());

for (int y = 0; y < video->get_height (); y++) {
auto pixel = pixel_row_ptr;
for (int c = 0; c < content_bytes_per_row; c++) {
*pixel = distrib (device);
pixel++;
}

pixel_row_ptr += pitch;
}

return video;
}
} // LV::Tests namespace
12 changes: 12 additions & 0 deletions libvisual/tests/random.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _LV_TESTS_VIDEO_RANDOM_HPP
#define _LV_TESTS_VIDEO_RANDOM_HPP

#include <libvisual/libvisual.h>

namespace LV::Tests
{
LV::VideoPtr create_random_video (int width, int height, VisVideoDepth depth);

} // LV::Tests namespace

#endif // defined(_LV_TESTS_VIDEO_COMMON_HPP)
4 changes: 4 additions & 0 deletions libvisual/tests/video_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ LV_BUILD_TEST(video_check_test
SOURCES video_check_test.cpp
)

LV_BUILD_TEST(video_blit_test
SOURCES video_blit_test.cpp
)

IF(HAVE_SDL)
LV_BUILD_TEST(video_scale_test
SOURCES video_scale_test.cpp
Expand Down
66 changes: 66 additions & 0 deletions libvisual/tests/video_test/video_blit_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "test.h"
#include "random.hpp"
#include <libvisual/libvisual.h>
#include <cassert>

namespace
{
LV::VideoPtr clone_video (LV::VideoPtr const& source)
{
auto clone {LV::Video::create (source->get_width (), source->get_height (), source->get_depth ())};

assert (clone->get_pitch () == source->get_pitch ());
std::size_t buffer_size = static_cast<std::size_t> (clone->get_pitch () * clone->get_width ());

visual_mem_copy (clone->get_pixels (), source->get_pixels (), buffer_size);

return clone;
}

void test_blit_overlay_alphasrc ()
{
// Check that blit_overlay_alphasrc results are within +/- 1 of exact computation for each colour channel. The
// errors largely arise from the use of 256 instead of 255 as divisor for performance reasons.

int const test_width = 31;
int const test_height = 31;

auto source = LV::Tests::create_random_video (test_width, test_height, VISUAL_VIDEO_DEPTH_32BIT);
source->set_compose_type (VISUAL_VIDEO_COMPOSE_TYPE_SRC);

auto target = LV::Tests::create_random_video (test_width, test_height, VISUAL_VIDEO_DEPTH_32BIT);

auto actual {clone_video (target)};
actual->blit (source, 0, 0, true);

for (int y = 0; y < test_height; y++) {
auto source_pixel = static_cast<uint8_t const*> (source->get_pixel_ptr (y, 0));
auto target_pixel = static_cast<uint8_t const*> (target->get_pixel_ptr (y, 0));
auto actual_pixel = static_cast<uint8_t const*> (actual->get_pixel_ptr (y, 0));

for (int x = 0; x < test_width; x++) {
LV_TEST_ASSERT (actual_pixel[3] == target_pixel[3]);

float source_alpha = static_cast<float> (source_pixel[3]) / 255.0f;
uint8_t b = source_alpha * source_pixel[0] + (1.0f - source_alpha) * target_pixel[0];
uint8_t g = source_alpha * source_pixel[1] + (1.0f - source_alpha) * target_pixel[1];
uint8_t r = source_alpha * source_pixel[2] + (1.0f - source_alpha) * target_pixel[2];

LV_TEST_ASSERT (std::abs (static_cast<int16_t> (actual_pixel[0]) - static_cast<int16_t> (b)) <= 1);
LV_TEST_ASSERT (std::abs (static_cast<int16_t> (actual_pixel[1]) - static_cast<int16_t> (g)) <= 1);
LV_TEST_ASSERT (std::abs (static_cast<int16_t> (actual_pixel[2]) - static_cast<int16_t> (r)) <= 1);

source_pixel += 4;
target_pixel += 4;
actual_pixel += 4;
}
}
}
} // anonymous namespace

int main(int argc, char *argv[])
{
LV::System::init (argc, argv);
test_blit_overlay_alphasrc ();
LV::System::destroy ();
}

0 comments on commit 61bdede

Please sign in to comment.