diff --git a/libvisual/tests/images/additive-colors-argb32.png b/libvisual/tests/images/additive-colors-argb32.png
new file mode 100644
index 000000000..f6543908f
Binary files /dev/null and b/libvisual/tests/images/additive-colors-argb32.png differ
diff --git a/libvisual/tests/images/additive-colors-argb32.raw b/libvisual/tests/images/additive-colors-argb32.raw
new file mode 100644
index 000000000..ed4eec92b
Binary files /dev/null and b/libvisual/tests/images/additive-colors-argb32.raw differ
diff --git a/libvisual/tests/images/additive-colors-indexed8.png b/libvisual/tests/images/additive-colors-indexed8.png
new file mode 100644
index 000000000..b49124436
Binary files /dev/null and b/libvisual/tests/images/additive-colors-indexed8.png differ
diff --git a/libvisual/tests/images/additive-colors-indexed8.raw b/libvisual/tests/images/additive-colors-indexed8.raw
new file mode 100644
index 000000000..23d61d778
Binary files /dev/null and b/libvisual/tests/images/additive-colors-indexed8.raw differ
diff --git a/libvisual/tests/images/additive-colors-indexed8.raw.pal b/libvisual/tests/images/additive-colors-indexed8.raw.pal
new file mode 100644
index 000000000..b4bb4975e
Binary files /dev/null and b/libvisual/tests/images/additive-colors-indexed8.raw.pal differ
diff --git a/libvisual/tests/images/additive-colors-rgb24.png b/libvisual/tests/images/additive-colors-rgb24.png
new file mode 100644
index 000000000..ffb84a7a1
Binary files /dev/null and b/libvisual/tests/images/additive-colors-rgb24.png differ
diff --git a/libvisual/tests/images/additive-colors-rgb24.raw b/libvisual/tests/images/additive-colors-rgb24.raw
new file mode 100644
index 000000000..c065e6bef
Binary files /dev/null and b/libvisual/tests/images/additive-colors-rgb24.raw differ
diff --git a/libvisual/tests/images/additive-colors.svg b/libvisual/tests/images/additive-colors.svg
new file mode 100644
index 000000000..8f37891a3
--- /dev/null
+++ b/libvisual/tests/images/additive-colors.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/libvisual/tests/video_test/CMakeLists.txt b/libvisual/tests/video_test/CMakeLists.txt
index 65cd4341a..4a8bad4c0 100644
--- a/libvisual/tests/video_test/CMakeLists.txt
+++ b/libvisual/tests/video_test/CMakeLists.txt
@@ -6,6 +6,10 @@ LV_BUILD_TEST(video_blit_test
SOURCES video_blit_test.cpp
)
+LV_BUILD_TEST(video_load_test
+ SOURCES video_load_test.cpp
+)
+
IF(HAVE_SDL)
LV_BUILD_TEST(video_scale_test
SOURCES video_scale_test.cpp
diff --git a/libvisual/tests/video_test/video_load_test.cpp b/libvisual/tests/video_test/video_load_test.cpp
new file mode 100644
index 000000000..c9ce7a4cb
--- /dev/null
+++ b/libvisual/tests/video_test/video_load_test.cpp
@@ -0,0 +1,146 @@
+#include "test.h"
+#include
+#include
+#include
+#include
+#include
+
+namespace
+{
+ LV::VideoPtr load_raw_image (std::filesystem::path const& path, int width, int height, VisVideoDepth depth)
+ {
+ auto image {LV::Video::create (width, height, depth)};
+
+ std::size_t const content_bytes_per_row = image->get_width () * image->get_bpp ();
+
+ {
+ std::ifstream input {path, std::ios::binary};
+ if (!input) {
+ return nullptr;
+ }
+
+ for (int y = 0; y < image->get_height (); y++) {
+ auto pixel_row_ptr = static_cast (image->get_pixel_ptr (0, y));
+ if (!input.read (pixel_row_ptr, content_bytes_per_row)) {
+ return nullptr;
+ }
+ }
+ }
+
+ if constexpr (std::endian::native == std::endian::little) {
+ auto byteswapped_image {LV::Video::create (width, height, depth)};
+ byteswapped_image->flip_pixel_bytes (image);
+ return byteswapped_image;
+ } else {
+ return image;
+ }
+ }
+
+ std::optional load_raw_palette(std::filesystem::path const& path)
+ {
+ std::vector palette_buffer (256 * 3);
+ {
+ std::ifstream input {path, std::ios::binary};
+ if (!input.read(reinterpret_cast(palette_buffer.data()), palette_buffer.size())) {
+ return {};
+ }
+ }
+
+ LV::Palette palette;
+ palette.colors.reserve(256);
+ for (unsigned int i = 0; i < 256; i++) {
+ palette.colors.emplace_back(palette_buffer[i*3], palette_buffer[i*3+1], palette_buffer[i*3+2]);
+ }
+
+ return palette;
+ }
+
+ LV::VideoPtr load_raw_indexed_image (std::filesystem::path const& image_path,
+ std::filesystem::path const& palette_path,
+ int width,
+ int height,
+ VisVideoDepth depth)
+ {
+ if (depth != VISUAL_VIDEO_DEPTH_24BIT) {
+ return nullptr;
+ }
+
+ auto image {LV::Video::create (width, height, VISUAL_VIDEO_DEPTH_8BIT)};
+
+ std::size_t const content_bytes_per_row = image->get_width () * image->get_bpp ();
+
+ {
+ std::ifstream input {image_path, std::ios::binary};
+ if (!input) {
+ return nullptr;
+ }
+
+ for (int y = 0; y < image->get_height (); y++) {
+ auto pixel_row_ptr = static_cast (image->get_pixel_ptr (0, y));
+ if (!input.read (pixel_row_ptr, content_bytes_per_row)) {
+ return nullptr;
+ }
+ }
+ }
+
+ auto palette {load_raw_palette(palette_path)};
+ if (!palette.has_value()) {
+ return nullptr;
+ }
+ image->set_palette (palette.value());
+
+ auto final_image {LV::Video::create (image->get_width(), image->get_height(), VISUAL_VIDEO_DEPTH_24BIT)};
+ final_image->convert_depth(image);
+
+ return final_image;
+ }
+
+ void test_png_load ()
+ {
+ {
+ auto png_image {LV::Video::create_from_file ("../images/additive-colors-indexed8.png")};
+ LV_TEST_ASSERT (png_image);
+
+ auto raw_image {load_raw_indexed_image ("../images/additive-colors-indexed8.raw",
+ "../images/additive-colors-indexed8.raw.pal",
+ png_image->get_width (),
+ png_image->get_height (),
+ VISUAL_VIDEO_DEPTH_24BIT)};
+
+ LV_TEST_ASSERT (png_image->has_same_content (raw_image));
+ }
+
+ {
+ auto png_image {LV::Video::create_from_file ("../images/additive-colors-rgb24.png")};
+ LV_TEST_ASSERT (png_image);
+
+ auto raw_image {load_raw_image ("../images/additive-colors-rgb24.raw",
+ png_image->get_width (),
+ png_image->get_height (),
+ VISUAL_VIDEO_DEPTH_24BIT)};
+
+ LV_TEST_ASSERT (png_image->has_same_content (raw_image));
+ }
+
+ {
+ auto png_image {LV::Video::create_from_file ("../images/additive-colors-argb32.png")};
+ LV_TEST_ASSERT (png_image);
+
+ auto raw_image {load_raw_image ("../images/additive-colors-argb32.raw",
+ png_image->get_width (),
+ png_image->get_height (),
+ VISUAL_VIDEO_DEPTH_32BIT)};
+
+ LV_TEST_ASSERT (png_image->has_same_content (raw_image));
+ }
+ }
+}
+
+int main (int argc, char* argv[])
+{
+ LV::System::init (argc, argv);
+
+ test_png_load ();
+
+ LV::System::destroy ();
+}