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.bmp b/libvisual/tests/images/additive-colors-indexed8.bmp
new file mode 100644
index 000000000..f24468963
Binary files /dev/null and b/libvisual/tests/images/additive-colors-indexed8.bmp 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.bmp b/libvisual/tests/images/additive-colors-rgb24.bmp
new file mode 100644
index 000000000..72be071d9
Binary files /dev/null and b/libvisual/tests/images/additive-colors-rgb24.bmp 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/images/license.txt b/libvisual/tests/images/license.txt
index 6960e6ade..c5c55a28d 100644
--- a/libvisual/tests/images/license.txt
+++ b/libvisual/tests/images/license.txt
@@ -5,3 +5,11 @@ Description: Geological wonder "The Painted Desert" in Arizona
Author : katsrcool
URL : http://www.flickr.com/photos/katsrcool/7275923984/
License : CC BY 2.0
+
+additive_color.svg
+------------------
+Name : AdditiveColor.svg
+Description: This image demonstrates the principle of additive color mixing, and is not meant as an exhibition of any particular color space. Original by Mike Horvath.
+Author : SharkD at English Wikipedia
+URL : https://commons.wikimedia.org/wiki/File:AdditiveColor.svg
+License : CC0
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..85995334d
--- /dev/null
+++ b/libvisual/tests/video_test/video_load_test.cpp
@@ -0,0 +1,152 @@
+#include "test.h"
+#include
+#include
+#include
+#include
+#include
+
+namespace
+{
+ namespace fs = std::filesystem;
+
+ LV::VideoPtr load_raw_image (fs::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 (fs::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 std::nullopt;
+ }
+ }
+
+ 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 (fs::path const& image_path,
+ fs::path const& palette_path,
+ int width,
+ int height)
+ {
+ 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 ());
+
+ return image;
+ }
+
+ void test_load_indexed8 ()
+ {
+ auto bmp_image {LV::Video::create_from_file ("../images/additive-colors-indexed8.bmp")};
+ LV_TEST_ASSERT (bmp_image);
+
+ 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 ())};
+
+ auto raw_image_rgb24 {LV::Video::create (raw_image->get_width (), raw_image->get_height (), VISUAL_VIDEO_DEPTH_24BIT)};
+ raw_image_rgb24->convert_depth (raw_image);
+
+ LV_TEST_ASSERT (bmp_image->has_same_content (raw_image));
+ LV_TEST_ASSERT (png_image->has_same_content (raw_image_rgb24));
+ }
+
+ void test_load_rgb24 ()
+ {
+ auto bmp_image {LV::Video::create_from_file ("../images/additive-colors-rgb24.bmp")};
+ LV_TEST_ASSERT (bmp_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 (bmp_image->has_same_content (raw_image));
+ LV_TEST_ASSERT (png_image->has_same_content (raw_image));
+ }
+
+ void test_load_argb32 ()
+ {
+ 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_load_indexed8 ();
+ test_load_rgb24 ();
+ test_load_argb32 ();
+
+ LV::System::destroy ();
+}