1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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;
}
|