Skip to content

Commit 7b3067d

Browse files
committed
Core (Tests): Add LV::Video::validate() and LV::Video::has_same_content() for testing videos.
1 parent 052fb0a commit 7b3067d

File tree

5 files changed

+145
-0
lines changed

5 files changed

+145
-0
lines changed

libvisual/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ ENDIF()
224224
# Tests
225225
OPTION(ENABLE_TESTS "Build tests" no)
226226
IF(ENABLE_TESTS)
227+
ADD_COMPILE_DEFINITIONS(LV_ENABLE_TESTS)
228+
227229
ENABLE_TESTING()
228230
ADD_SUBDIRECTORY(tests)
229231
ENDIF()

libvisual/libvisual/lv_video.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "private/lv_video_transform.hpp"
3737
#include "private/lv_video_bmp.hpp"
3838
#include "private/lv_video_png.hpp"
39+
#include <cstring>
3940
#include <fstream>
4041

4142
namespace LV {
@@ -292,6 +293,110 @@ namespace LV {
292293
return true;
293294
}
294295

296+
#ifdef LV_ENABLE_TESTS
297+
bool Video::validate() const
298+
{
299+
// Validate dimensions.
300+
301+
if (m_impl->width <= 0) {
302+
visual_log (VISUAL_LOG_ERROR, "Video has a zero or negative width (%d).", m_impl->width);
303+
return false;
304+
}
305+
306+
if (m_impl->height <= 0) {
307+
visual_log (VISUAL_LOG_ERROR, "Video has a zero of negative height (%d).", m_impl->height);
308+
return false;
309+
}
310+
311+
if (m_impl->pitch <= 0) {
312+
visual_log (VISUAL_LOG_ERROR, "Video has a zero of negative pitch (%d).", m_impl->pitch);
313+
return false;
314+
}
315+
316+
// Validate extents.
317+
318+
if (m_impl->width != m_impl->extents.width) {
319+
visual_log (VISUAL_LOG_ERROR, "Width (%d) and width of extents (%d) do not agree.",
320+
m_impl->width, m_impl->extents.width);
321+
return false;
322+
}
323+
324+
if (m_impl->height != m_impl->extents.height) {
325+
visual_log (VISUAL_LOG_ERROR, "Height (%d) and height of extents (%d) do not agree.",
326+
m_impl->height, m_impl->extents.height);
327+
return false;
328+
}
329+
330+
// Validate parent-child relations.
331+
332+
if (m_impl->parent) {
333+
auto parent_impl = m_impl->parent->m_impl.get ();
334+
if (!parent_impl->extents.contains (m_impl->extents)) {
335+
visual_log (VISUAL_LOG_ERROR, "Sub-video is not fully contained by parent.");
336+
return false;
337+
}
338+
}
339+
340+
if (m_impl->depth != VISUAL_VIDEO_DEPTH_GL) {
341+
// Validate depth and bytes per pixel consisteency.
342+
343+
if (m_impl->bpp != visual_video_depth_bpp (m_impl->depth) / 8) {
344+
visual_log (VISUAL_LOG_ERROR, "Depth (%s) is not consistent with BPP (%d).",
345+
visual_video_depth_name (m_impl->depth), m_impl->bpp);
346+
return false;
347+
}
348+
349+
// Validate pixel row table
350+
351+
auto pixel_row_ptr = static_cast<uint8_t const*> (get_pixels ());
352+
353+
for (int y = 0; y < m_impl->height; y++) {
354+
if (m_impl->pixel_rows[y] != pixel_row_ptr) {
355+
visual_log (VISUAL_LOG_ERROR, "Pixel row pointer table is wrong at y=%d.", y);
356+
return false;
357+
}
358+
359+
pixel_row_ptr += m_impl->pitch;
360+
}
361+
}
362+
363+
return true;
364+
}
365+
#endif // defined(LV_ENABLE_TESTS)
366+
367+
bool Video::has_same_content (VideoConstPtr const& video) const
368+
{
369+
// Comparison of GL LV::Video is not supported.
370+
if (m_impl->depth == VISUAL_VIDEO_DEPTH_GL || video->m_impl->depth == VISUAL_VIDEO_DEPTH_GL) {
371+
return false;
372+
}
373+
374+
// Videos must have the same dimensions and pixel format.
375+
376+
if (m_impl->width != video->m_impl->width)
377+
return false;
378+
379+
if (m_impl->height != video->m_impl->height)
380+
return false;
381+
382+
if (m_impl->depth != video->m_impl->depth)
383+
return false;
384+
385+
// Videos must have the same colours at every pixel.
386+
387+
// Determine the block size in bytes in each row to compare. This must exclude padding. It must also exclude
388+
// pixels outside of a subvideo's extents.
389+
std::size_t const content_bytes_per_row = m_impl->width * m_impl->bpp;
390+
391+
for (int y = 0; y < m_impl->height; y++) {
392+
if (std::memcmp (m_impl->pixel_rows[y], video->m_impl->pixel_rows[y], content_bytes_per_row)) {
393+
return false;
394+
}
395+
}
396+
397+
return true;
398+
}
399+
295400
void Video::set_palette (Palette const& palette)
296401
{
297402
m_impl->palette = palette;

libvisual/libvisual/lv_video.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,26 @@ namespace LV {
294294
*/
295295
bool compare_attrs_ignore_pitch (VideoConstPtr const& src) const;
296296

297+
#ifdef LV_ENABLE_TESTS
298+
/**
299+
* Validates the state of this Video.
300+
*
301+
* @remark For debugging and testing purposes.
302+
*
303+
* @return true if video has consistent state, false otherwise.
304+
*/
305+
bool validate() const;
306+
#endif // defined(LV_ENABLE_TESTS)
307+
308+
/**
309+
* Checks if this Video has the same (pixel) content as another Video.
310+
*
311+
* @param src Video to compare against
312+
*
313+
* @return true if both videos have the same content, false otherwise
314+
*/
315+
bool has_same_content (VideoConstPtr const& video) const;
316+
297317
/**
298318
* Returns the size of the pixel buffer
299319
*

libvisual/tests/video_test/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
LV_BUILD_TEST(video_check_test
2+
SOURCES video_check_test.cpp
3+
)
4+
15
IF(HAVE_SDL)
26
LV_BUILD_TEST(video_scale_test
37
SOURCES video_scale_test.cpp
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "test.h"
2+
#include <libvisual/libvisual.h>
3+
4+
int main (int argc, char* argv[])
5+
{
6+
LV::System::init (argc, argv);
7+
8+
auto video = LV::Video::create(640, 480, VISUAL_VIDEO_DEPTH_16BIT);
9+
10+
LV_TEST_ASSERT (video->validate ());
11+
LV_TEST_ASSERT (video->has_same_content (video));
12+
13+
LV::System::destroy ();
14+
}

0 commit comments

Comments
 (0)