summaryrefslogtreecommitdiff
path: root/subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2026-05-08 17:22:58 +0300
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2026-05-08 17:22:58 +0300
commit4e2b291a4acdc2cbd39f005c88bda363bc06bd34 (patch)
treee90048d5973ad1164b109d575cf577af7daf50be /subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp
parent8f94b39040e79eccd9312ed1e467fe8ebfab8860 (diff)
parente0b7d30fd437292c88141fb08d60681870b86c6e (diff)
Merge commit 'e0b7d30fd437292c88141fb08d60681870b86c6e' as 'subprojects/pixpat'
Diffstat (limited to 'subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp')
-rw-r--r--subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp b/subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp
new file mode 100644
index 0000000..8319968
--- /dev/null
+++ b/subprojects/pixpat/pixpat-native/tests/test_pixpat.cpp
@@ -0,0 +1,107 @@
+/*
+ * Native C++ smoke test for libpixpat.
+ *
+ * Scope is narrow: prove that the public header, the shared library,
+ * and the C ABI surface are wired up correctly when consumed from C++.
+ * Behavioral coverage (formats, patterns, error paths, threading,
+ * conversion matrix) lives in the Python test suite, which exercises
+ * the same C ABI with much less boilerplate.
+ */
+
+#include <pixpat/pixpat.h>
+
+#include <cstdint>
+#include <cstdio>
+#include <vector>
+
+// CHECK always evaluates its expression so the test still runs in
+// release builds where assert() is compiled out.
+#define CHECK(expr) do { \
+ if (!(expr)) { \
+ std::fprintf(stderr, "%s:%d: CHECK failed: %s\n", \
+ __FILE__, __LINE__, #expr); \
+ return 1; \
+ } \
+} while (0)
+
+int main()
+{
+ // Format introspection.
+ CHECK(pixpat_format_count() > 0);
+ CHECK(pixpat_format_name(0) != nullptr);
+ CHECK(pixpat_format_supported("XRGB8888") == 1);
+ CHECK(pixpat_format_supported("NOT_A_REAL_FORMAT") == 0);
+
+ // Draw a pattern into an RGB buffer.
+ const uint32_t w = 64, h = 32;
+ std::vector<uint8_t> rgb(w * h * 4, 0);
+ pixpat_buffer fb{};
+ fb.format = "XRGB8888";
+ fb.width = w;
+ fb.height = h;
+ fb.num_planes = 1;
+ fb.planes[0] = rgb.data();
+ fb.strides[0] = w * 4;
+
+ pixpat_pattern_opts pat{};
+ pat.rec = PIXPAT_REC_BT709;
+ pat.range = PIXPAT_RANGE_LIMITED;
+ CHECK(pixpat_draw_pattern(&fb, "smpte", &pat) == 0);
+ // Cover the NULL-opts path.
+ CHECK(pixpat_draw_pattern(&fb, nullptr, nullptr) == 0);
+
+ // Plain pattern: hex color via opts->params. BGR888-style byte
+ // order means the first pixel of XRGB8888 stores B at byte 0,
+ // G at byte 1, R at byte 2.
+ pixpat_pattern_opts plain_opts{};
+ plain_opts.params = "color=ff0000";
+ CHECK(pixpat_draw_pattern(&fb, "plain", &plain_opts) == 0);
+ CHECK(rgb[0] == 0x00 && rgb[1] == 0x00 && rgb[2] == 0xFF);
+ // Missing/malformed params for `plain` must fail.
+ plain_opts.params = nullptr;
+ CHECK(pixpat_draw_pattern(&fb, "plain", &plain_opts) == -1);
+ plain_opts.params = "color=zzzzzz";
+ CHECK(pixpat_draw_pattern(&fb, "plain", &plain_opts) == -1);
+ // Top-level params parse failure also fails the call.
+ plain_opts.params = "foo,bar";
+ CHECK(pixpat_draw_pattern(&fb, "plain", &plain_opts) == -1);
+
+ // Cover the rest of the pattern catalog. None of these accept
+ // failure at the C-API entry point with valid inputs.
+ pixpat_pattern_opts po{};
+ CHECK(pixpat_draw_pattern(&fb, "checker", nullptr) == 0); // default cell
+ po.params = "cell=1";
+ CHECK(pixpat_draw_pattern(&fb, "checker", &po) == 0);
+ po.params = "cell=0";
+ CHECK(pixpat_draw_pattern(&fb, "checker", &po) == -1); // non-positive
+ po.params = "cell=oops";
+ CHECK(pixpat_draw_pattern(&fb, "checker", &po) == -1); // non-numeric
+ CHECK(pixpat_draw_pattern(&fb, "hramp", nullptr) == 0);
+ CHECK(pixpat_draw_pattern(&fb, "vramp", nullptr) == 0);
+ CHECK(pixpat_draw_pattern(&fb, "dramp", nullptr) == 0);
+ CHECK(pixpat_draw_pattern(&fb, "zoneplate", nullptr) == 0);
+
+ // Convert into the normalized wide RGB format.
+ std::vector<uint8_t> wide(w * h * 8, 0);
+ pixpat_buffer dst{};
+ dst.format = "ABGR16161616";
+ dst.width = w;
+ dst.height = h;
+ dst.num_planes = 1;
+ dst.planes[0] = wide.data();
+ dst.strides[0] = w * 8;
+ CHECK(pixpat_convert(&dst, &fb, nullptr) == 0);
+
+ // Error path: unknown format must return -1, not crash.
+ uint8_t dummy[4]{};
+ pixpat_buffer bad{};
+ bad.format = "NOT_A_REAL_FORMAT";
+ bad.width = 1;
+ bad.height = 1;
+ bad.num_planes = 1;
+ bad.planes[0] = dummy;
+ bad.strides[0] = 4;
+ CHECK(pixpat_draw_pattern(&bad, "smpte", &pat) == -1);
+
+ return 0;
+}