1 #include <algorithm>
2 #include <cstdio>
3 #include <string>
4 #include <vector>
5 #include "colorspace/colorspace.h"
6 #include "common/pixel.h"
7 #include "depth/depth.h"
8 #include "graph/filtergraph.h"
9 #include "graph/graphbuilder.h"
10 #include "resize/resize.h"
11 #include "unresize/unresize.h"
12
13 #include "gtest/gtest.h"
14
15 namespace {
16
17 using zimg::colorspace::MatrixCoefficients;
18 using zimg::colorspace::TransferCharacteristics;
19 using zimg::colorspace::ColorPrimaries;
20 using zimg::graph::GraphBuilder;
21
22 typedef std::vector<std::string> TraceList;
23
24 class TracingObserver : public zimg::graph::FilterObserver {
25 TraceList m_trace;
26 public:
trace() const27 const TraceList &trace() const { return m_trace; }
28
yuv_to_grey()29 void yuv_to_grey() override { m_trace.push_back("yuv_to_grey"); }
30
grey_to_yuv()31 void grey_to_yuv() override { m_trace.push_back("grey_to_yuv"); }
grey_to_rgb()32 void grey_to_rgb() override { m_trace.push_back("grey_to_rgb"); }
33
premultiply()34 void premultiply() override { m_trace.push_back("premultiply"); }
unpremultiply()35 void unpremultiply() override { m_trace.push_back("unpremultiply"); }
add_opaque()36 void add_opaque() override { m_trace.push_back("add_opaque"); }
discard_alpha()37 void discard_alpha() override { m_trace.push_back("discard_alpha"); }
38
colorspace(const zimg::colorspace::ColorspaceConversion & conv)39 void colorspace(const zimg::colorspace::ColorspaceConversion &conv) override
40 {
41 char buffer[128];
42 sprintf(buffer, "colorspace: [%d, %d, %d] => [%d, %d, %d] (%f)\n",
43 static_cast<int>(conv.csp_in.matrix),
44 static_cast<int>(conv.csp_in.transfer),
45 static_cast<int>(conv.csp_in.primaries),
46 static_cast<int>(conv.csp_out.matrix),
47 static_cast<int>(conv.csp_out.transfer),
48 static_cast<int>(conv.csp_out.primaries),
49 conv.peak_luminance);
50 m_trace.push_back(buffer);
51 }
52
depth(const zimg::depth::DepthConversion & conv,int plane)53 void depth(const zimg::depth::DepthConversion &conv, int plane) override
54 {
55 char buffer[128];
56 sprintf(buffer, "depth[%d]: [%d/%u %c:%c%s] => [%d/%u %c:%c%s]\n",
57 plane,
58 static_cast<int>(conv.pixel_in.type),
59 conv.pixel_in.depth,
60 conv.pixel_in.fullrange ? 'f' : 'l',
61 conv.pixel_in.chroma ? 'c' : 'l',
62 conv.pixel_in.ycgco ? " ycgco" : "",
63 static_cast<int>(conv.pixel_out.type),
64 conv.pixel_out.depth,
65 conv.pixel_out.fullrange ? 'f' : 'l',
66 conv.pixel_out.chroma ? 'c' : 'l',
67 conv.pixel_out.ycgco ? " ycgco" : "");
68 m_trace.push_back(buffer);
69 }
70
resize(const zimg::resize::ResizeConversion & conv,int plane)71 void resize(const zimg::resize::ResizeConversion &conv, int plane) override
72 {
73 char buffer[128];
74 sprintf(buffer, "resize[%d]: [%u, %u] => [%u, %u] (%f, %f, %f, %f)\n",
75 plane,
76 conv.src_width,
77 conv.src_height,
78 conv.dst_width,
79 conv.dst_height,
80 conv.shift_w,
81 conv.shift_h,
82 conv.subwidth,
83 conv.subheight);
84 m_trace.push_back(buffer);
85 }
86
unresize(const zimg::unresize::UnresizeConversion & conv,int plane)87 void unresize(const zimg::unresize::UnresizeConversion &conv, int plane) override
88 {
89 char buffer[128];
90 sprintf(buffer, "unresize: [%u, %u] => [%u, %u] (%f, %f)\n",
91 conv.up_width,
92 conv.up_height,
93 conv.orig_width,
94 conv.orig_height,
95 conv.shift_w,
96 conv.shift_h);
97 m_trace.push_back(buffer);
98 }
99 };
100
101
make_basic_rgb_state()102 GraphBuilder::state make_basic_rgb_state()
103 {
104 GraphBuilder::state state{};
105 state.width = 64;
106 state.height = 48;
107 state.type = zimg::PixelType::FLOAT;
108 state.subsample_w = 0;
109 state.subsample_h = 0;
110 state.color = GraphBuilder::ColorFamily::RGB;
111 state.colorspace = { MatrixCoefficients::RGB, TransferCharacteristics::REC_709, ColorPrimaries::REC_709 };
112 state.depth = zimg::pixel_depth(zimg::PixelType::FLOAT);
113 state.fullrange = false;
114 state.parity = GraphBuilder::FieldParity::PROGRESSIVE;
115 state.chroma_location_w = GraphBuilder::ChromaLocationW::CENTER;
116 state.chroma_location_h = GraphBuilder::ChromaLocationH::CENTER;
117 state.active_left = 0.0;
118 state.active_top = 0.0;
119 state.active_width = 64.0;
120 state.active_height = 48.0;
121 state.alpha = GraphBuilder::AlphaType::NONE;
122 return state;
123 }
124
make_basic_yuv_state()125 GraphBuilder::state make_basic_yuv_state()
126 {
127 GraphBuilder::state state = make_basic_rgb_state();
128 state.color = GraphBuilder::ColorFamily::YUV;
129 state.colorspace = { MatrixCoefficients::REC_709, TransferCharacteristics::REC_709, ColorPrimaries::REC_709 };
130 return state;
131 }
132
set_resolution(GraphBuilder::state & state,unsigned width,unsigned height)133 void set_resolution(GraphBuilder::state &state, unsigned width, unsigned height)
134 {
135 state.width = width;
136 state.height = height;
137 state.active_left = 0;
138 state.active_top = 0;
139 state.active_width = width;
140 state.active_height = height;
141 }
142
test_case(const GraphBuilder::state & source,const GraphBuilder::state & target,const TraceList & trace)143 void test_case(const GraphBuilder::state &source, const GraphBuilder::state &target, const TraceList &trace)
144 {
145 GraphBuilder builder;
146 TracingObserver observer;
147 builder.set_source(source).connect(target, nullptr, &observer).complete();
148
149 EXPECT_EQ(trace.size(), observer.trace().size());
150 for (size_t i = 0; i < std::min(trace.size(), observer.trace().size()); ++i) {
151 EXPECT_TRUE(observer.trace()[i].rfind(trace[i]) == 0)
152 << "Expected: " << trace[i] << "\nActual: " << observer.trace()[i];
153 }
154 for (size_t i = std::min(trace.size(), observer.trace().size()); i < observer.trace().size(); ++i) {
155 ADD_FAILURE() << "Unexpected[" << i << "]: " << observer.trace()[i];
156 }
157 }
158
159 } // namespace
160
161
TEST(GraphBuilderTest,test_noop)162 TEST(GraphBuilderTest, test_noop)
163 {
164 auto source = make_basic_rgb_state();
165 auto target = source;
166 test_case(source, target, {});
167 }
168
TEST(GraphBuilderTest,test_resize_only_rgb)169 TEST(GraphBuilderTest, test_resize_only_rgb)
170 {
171 auto source = make_basic_rgb_state();
172 set_resolution(source, 64, 48);
173
174 auto target = source;
175 set_resolution(target, 128, 96);
176
177 test_case(source, target, { "resize[0]: [64, 48] => [128, 96]" });
178 }
179
TEST(GraphBuilderTest,test_resize_only_444)180 TEST(GraphBuilderTest, test_resize_only_444)
181 {
182 auto source = make_basic_yuv_state();
183 set_resolution(source, 64, 48);
184
185 auto target = source;
186 set_resolution(target, 128, 96);
187
188 test_case(source, target, {
189 "resize[0]: [64, 48] => [128, 96]",
190 "resize[1]: [64, 48] => [128, 96]",
191 });
192 }
193
TEST(GraphBuilderTest,test_resize_only_420)194 TEST(GraphBuilderTest, test_resize_only_420)
195 {
196 auto source = make_basic_yuv_state();
197 set_resolution(source, 64, 48);
198 source.subsample_w = 1;
199 source.subsample_h = 1;
200
201 auto target = source;
202 set_resolution(target, 128, 96);
203
204 test_case(source, target, {
205 "resize[0]: [64, 48] => [128, 96]",
206 "resize[1]: [32, 24] => [64, 48]"
207 });
208 }
209
TEST(GraphBuilderTest,test_resize_420_to_444)210 TEST(GraphBuilderTest, test_resize_420_to_444)
211 {
212 auto source = make_basic_yuv_state();
213 source.subsample_w = 1;
214 source.subsample_h = 1;
215
216 auto target = make_basic_yuv_state();
217
218 test_case(source, target, { "resize[1]" });
219 }
220
TEST(GraphBuilderTest,test_resize_444_to_420)221 TEST(GraphBuilderTest, test_resize_444_to_420)
222 {
223 auto source = make_basic_yuv_state();
224
225 auto target = make_basic_yuv_state();
226 target.subsample_w = 1;
227 target.subsample_h = 1;
228
229 test_case(source, target, { "resize[1]" });
230 }
231
TEST(GraphBuilderTest,test_resize_chromaloc_upsample)232 TEST(GraphBuilderTest, test_resize_chromaloc_upsample)
233 {
234 auto source = make_basic_yuv_state();
235 set_resolution(source, 64, 48);
236 source.subsample_w = 1;
237 source.subsample_h = 1;
238 source.chroma_location_w = GraphBuilder::ChromaLocationW::LEFT;
239 source.chroma_location_h = GraphBuilder::ChromaLocationH::BOTTOM;
240
241 auto target = make_basic_yuv_state();
242 set_resolution(target, 64, 48);
243
244 test_case(source, target, { "resize[1]: [32, 24] => [64, 48] (0.250000, -0.250000, 32.000000, 24.000000)" });
245 }
246
TEST(GraphBuilderTest,test_resize_chromaloc_downsample)247 TEST(GraphBuilderTest, test_resize_chromaloc_downsample)
248 {
249 auto source = make_basic_yuv_state();
250 set_resolution(source, 64, 48);
251
252 auto target = make_basic_yuv_state();
253 set_resolution(target, 64, 48);
254 target.subsample_w = 1;
255 target.subsample_h = 1;
256 target.chroma_location_w = GraphBuilder::ChromaLocationW::LEFT;
257 target.chroma_location_h = GraphBuilder::ChromaLocationH::BOTTOM;
258
259 test_case(source, target, { "resize[1]: [64, 48] => [32, 24] (-0.500000, 0.500000, 64.000000, 48.000000)" });
260 }
261
TEST(GraphBuilderTest,test_resize_deinterlace)262 TEST(GraphBuilderTest, test_resize_deinterlace)
263 {
264 auto source = make_basic_yuv_state();
265 set_resolution(source, 64, 48);
266 source.subsample_h = 1;
267
268 auto target = make_basic_yuv_state();
269 set_resolution(target, 64, 48);
270 target.subsample_h = 1;
271 target.parity = GraphBuilder::FieldParity::PROGRESSIVE;
272
273 source.parity = GraphBuilder::FieldParity::TOP;
274 test_case(source, target, {
275 "resize[0]: [64, 48] => [64, 48] (0.000000, 0.250000, 64.000000, 48.000000)",
276 "resize[1]: [64, 24] => [64, 24] (0.000000, 0.250000, 64.000000, 24.000000)",
277 });
278
279 source.parity = GraphBuilder::FieldParity::BOTTOM;
280 test_case(source, target, {
281 "resize[0]: [64, 48] => [64, 48] (0.000000, -0.250000, 64.000000, 48.000000)",
282 "resize[1]: [64, 24] => [64, 24] (0.000000, -0.250000, 64.000000, 24.000000)",
283 });
284 }
285
TEST(GraphBuilderTest,test_resize_interlace_to_interlace)286 TEST(GraphBuilderTest, test_resize_interlace_to_interlace)
287 {
288 auto source = make_basic_yuv_state();
289 set_resolution(source, 64, 48);
290 source.subsample_w = 1;
291 source.subsample_h = 1;
292 source.parity = GraphBuilder::FieldParity::TOP;
293 source.chroma_location_w = GraphBuilder::ChromaLocationW::LEFT;
294 source.chroma_location_h = GraphBuilder::ChromaLocationH::BOTTOM;
295
296 auto target = make_basic_yuv_state();
297 set_resolution(target, 64, 96);
298 target.subsample_w = 1;
299 target.subsample_h = 1;
300 target.parity = GraphBuilder::FieldParity::TOP;
301 target.chroma_location_w = GraphBuilder::ChromaLocationW::LEFT;
302 target.chroma_location_h = GraphBuilder::ChromaLocationH::BOTTOM;
303
304 test_case(source, target, {
305 "resize[0]: [64, 48] => [64, 96] (0.000000, 0.125000, 64.000000, 48.000000)",
306 "resize[1]: [32, 24] => [32, 48] (0.000000, 0.062500, 32.000000, 24.000000)",
307 });
308 }
309
TEST(GraphBuilderTest,test_resize_byte_fast_path)310 TEST(GraphBuilderTest, test_resize_byte_fast_path)
311 {
312 auto source = make_basic_rgb_state();
313 source.type = zimg::PixelType::BYTE;
314 source.depth = 8;
315 source.fullrange = true;
316 set_resolution(source, 64, 48);
317
318 auto target = source;
319 set_resolution(target, 128, 96);
320
321 test_case(source, target, {
322 "depth[0]: [0/8 l:l] => [1/16 l:l]",
323 "resize",
324 "depth[0]: [1/16 l:l] => [0/8 l:l]",
325 });
326 }
327
TEST(GraphBuilderTest,test_resize_byte_slow_path)328 TEST(GraphBuilderTest, test_resize_byte_slow_path)
329 {
330 auto source = make_basic_rgb_state();
331 source.type = zimg::PixelType::BYTE;
332 source.depth = 8;
333 source.fullrange = true;
334 set_resolution(source, 64, 48);
335
336 auto target = source;
337 target.fullrange = false;
338 set_resolution(target, 128, 96);
339
340 test_case(source, target, {
341 "depth[0]: [0/8 f:l] => [3/32 l:l]",
342 "resize",
343 "depth[0]: [3/32 l:l] => [0/8 l:l]",
344 });
345 }
346
TEST(GraphBuilderTest,test_resize_byte_word)347 TEST(GraphBuilderTest, test_resize_byte_word)
348 {
349 auto source = make_basic_yuv_state();
350 source.type = zimg::PixelType::BYTE;
351 source.depth = 8;
352 source.fullrange = true;
353 source.colorspace.matrix = MatrixCoefficients::YCGCO;
354 set_resolution(source, 64, 48);
355
356 auto target = source;
357 target.type = zimg::PixelType::WORD;
358 target.depth = 10;
359 target.fullrange = false;
360 set_resolution(target, 128, 96);
361
362 test_case(source, target, {
363 "depth[0]: [0/8 f:l ycgco] => [1/10 l:l ycgco]",
364 "resize[0]",
365 "depth[1]: [0/8 f:c ycgco] => [1/10 l:c ycgco]",
366 "resize[1]",
367 });
368 }
369
TEST(GraphBuilderTest,test_resize_word_byte)370 TEST(GraphBuilderTest, test_resize_word_byte)
371 {
372 auto source = make_basic_yuv_state();
373 source.type = zimg::PixelType::WORD;
374 source.depth = 10;
375 source.fullrange = false;
376 source.colorspace.matrix = MatrixCoefficients::YCGCO;
377 set_resolution(source, 64, 48);
378
379 auto target = source;
380 target.type = zimg::PixelType::BYTE;
381 target.depth = 8;
382 target.fullrange = true;
383 set_resolution(target, 128, 96);
384
385 test_case(source, target, {
386 "resize[0]",
387 "depth[0]: [1/10 l:l ycgco] => [0/8 f:l ycgco]",
388 "resize[1]",
389 "depth[1]: [1/10 l:c ycgco] => [0/8 f:c ycgco]",
390 });
391 }
392
TEST(GraphBuilderTest,test_colorspace_only)393 TEST(GraphBuilderTest, test_colorspace_only)
394 {
395 auto source = make_basic_rgb_state();
396 auto target = make_basic_yuv_state();
397 test_case(source, target, { "colorspace" });
398 }
399
TEST(GraphBuilderTest,test_upscale_colorspace)400 TEST(GraphBuilderTest, test_upscale_colorspace)
401 {
402 auto source = make_basic_yuv_state();
403 set_resolution(source, 64, 48);
404 source.subsample_w = 1;
405 source.subsample_h = 1;
406
407 auto target = source;
408 set_resolution(target, 96, 72);
409 target.colorspace = { MatrixCoefficients::REC_2020_NCL, TransferCharacteristics::REC_709, ColorPrimaries::REC_2020 };
410
411 test_case(source, target, {
412 "resize[1]: [32, 24] => [64, 48]",
413 "colorspace",
414 "resize[0]: [64, 48] => [96, 72]",
415 "resize[1]: [64, 48] => [48, 36]",
416 });
417 }
418
TEST(GraphBuilderTest,test_downscale_colorspace)419 TEST(GraphBuilderTest, test_downscale_colorspace)
420 {
421 auto source = make_basic_yuv_state();
422 set_resolution(source, 96, 72);
423 source.subsample_w = 1;
424 source.subsample_h = 1;
425
426 auto target = source;
427 set_resolution(target, 64, 48);
428 target.colorspace = { MatrixCoefficients::REC_2020_NCL, TransferCharacteristics::REC_709, ColorPrimaries::REC_2020 };
429
430 test_case(source, target, {
431 "resize[0]: [96, 72] => [64, 48]",
432 "resize[1]: [48, 36] => [64, 48]",
433 "colorspace",
434 "resize[1]: [64, 48] => [32, 24]",
435 });
436 }
437
TEST(GraphBuilderTest,test_upscale_colorspace_tile)438 TEST(GraphBuilderTest, test_upscale_colorspace_tile)
439 {
440 auto source = make_basic_yuv_state();
441 set_resolution(source, 64, 48);
442 source.subsample_w = 1;
443 source.subsample_h = 1;
444 source.active_left = 32;
445 source.active_top = 24;
446 source.active_width = 32;
447 source.active_height = 24;
448
449 auto target = make_basic_rgb_state();
450 set_resolution(target, 48, 36);
451
452 test_case(source, target, {
453 "resize[0]: [64, 48] => [48, 36] (32.000000, 24.000000, 32.000000, 24.000000)",
454 "resize[1]: [32, 24] => [48, 36] (16.000000, 12.000000, 16.000000, 12.000000)",
455 "colorspace",
456 });
457 }
458
TEST(GraphBuilderTest,test_downscale_colorspace_tile)459 TEST(GraphBuilderTest, test_downscale_colorspace_tile)
460 {
461 auto source = make_basic_rgb_state();
462 set_resolution(source, 96, 72);
463 source.active_left = 48;
464 source.active_top = 36;
465 source.active_width = 48;
466 source.active_height = 36;
467
468 auto target = make_basic_yuv_state();
469 set_resolution(target, 32, 24);
470 target.subsample_w = 1;
471 target.subsample_h = 1;
472
473 test_case(source, target, {
474 "resize[0]: [96, 72] => [32, 24] (48.000000, 36.000000, 48.000000, 36.000000)",
475 "colorspace",
476 "resize[1]: [32, 24] => [16, 12] (0.000000, 0.000000, 32.000000, 24.000000)",
477 });
478 }
479
TEST(GraphBuilderTest,test_grey_to_grey_noop)480 TEST(GraphBuilderTest, test_grey_to_grey_noop)
481 {
482 auto source = make_basic_yuv_state();
483 source.color = GraphBuilder::ColorFamily::GREY;
484 source.colorspace = { MatrixCoefficients::REC_709, TransferCharacteristics::REC_709, ColorPrimaries::REC_709 };
485
486 auto target = source;
487 target.colorspace = { MatrixCoefficients::REC_601, TransferCharacteristics::REC_709, ColorPrimaries::REC_709 };
488
489 test_case(source, target, {});
490 }
491
TEST(GraphBuilderTest,test_grey_to_rgb_noop)492 TEST(GraphBuilderTest, test_grey_to_rgb_noop)
493 {
494 auto source = make_basic_yuv_state();
495 source.color = GraphBuilder::ColorFamily::GREY;
496 source.colorspace.matrix = MatrixCoefficients::REC_2020_CL;
497
498 auto target = make_basic_rgb_state();
499 target.colorspace.matrix = MatrixCoefficients::UNSPECIFIED;
500
501 test_case(source, target, { "grey_to_rgb" });
502 }
503
TEST(GraphBuilderTest,test_grey_to_yuv_noop)504 TEST(GraphBuilderTest, test_grey_to_yuv_noop)
505 {
506 auto source = make_basic_yuv_state();
507 source.color = GraphBuilder::ColorFamily::GREY;
508 source.colorspace.matrix = MatrixCoefficients::UNSPECIFIED;
509
510 auto target = make_basic_yuv_state();
511 target.colorspace.matrix = MatrixCoefficients::REC_2020_CL;
512
513 test_case(source, target, { "grey_to_yuv" });
514 }
515
TEST(GraphBuilderTest,test_grey_to_grey_colorspace)516 TEST(GraphBuilderTest, test_grey_to_grey_colorspace)
517 {
518 auto source = make_basic_yuv_state();
519 source.color = GraphBuilder::ColorFamily::GREY;
520 source.colorspace = { MatrixCoefficients::REC_709, TransferCharacteristics::REC_709, ColorPrimaries::DCI_P3 };
521
522 auto target = source;
523 target.colorspace = { MatrixCoefficients::REC_601, TransferCharacteristics::REC_709, ColorPrimaries::SMPTE_C };
524
525 test_case(source, target, {
526 "grey_to_rgb",
527 "colorspace",
528 "yuv_to_grey",
529 });
530 }
531
TEST(GraphBuilderTest,test_yuv_to_grey_colorspace)532 TEST(GraphBuilderTest, test_yuv_to_grey_colorspace)
533 {
534 auto source = make_basic_yuv_state();
535 source.colorspace = { MatrixCoefficients::REC_709, TransferCharacteristics::REC_709, ColorPrimaries::DCI_P3 };
536
537 auto target = source;
538 target.color = GraphBuilder::ColorFamily::GREY;
539 target.colorspace = { MatrixCoefficients::REC_601, TransferCharacteristics::REC_709, ColorPrimaries::SMPTE_C };
540
541 test_case(source, target, {
542 "colorspace",
543 "yuv_to_grey",
544 });
545 }
546
TEST(GraphBuilderTest,test_straight_to_premul)547 TEST(GraphBuilderTest, test_straight_to_premul)
548 {
549 auto source = make_basic_yuv_state();
550 source.subsample_w = 1;
551 source.subsample_h = 1;
552 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
553
554 auto target = source;
555 target.alpha = GraphBuilder::AlphaType::PREMULTIPLIED;
556
557 test_case(source, target, {
558 "resize[1]",
559 "premultiply",
560 "resize[1]",
561 });
562 }
563
TEST(GraphBuilderTest,test_premul_to_straight)564 TEST(GraphBuilderTest, test_premul_to_straight)
565 {
566 auto source = make_basic_yuv_state();
567 source.subsample_w = 1;
568 source.subsample_h = 1;
569 source.alpha = GraphBuilder::AlphaType::PREMULTIPLIED;
570
571 auto target = source;
572 target.alpha = GraphBuilder::AlphaType::STRAIGHT;
573
574 test_case(source, target, {
575 "resize[1]",
576 "unpremultiply",
577 "resize[1]",
578 });
579 }
580
TEST(GraphBuilderTest,test_straight_to_opaque)581 TEST(GraphBuilderTest, test_straight_to_opaque)
582 {
583 auto source = make_basic_rgb_state();
584 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
585
586 auto target = source;
587 target.alpha = GraphBuilder::AlphaType::NONE;
588
589 test_case(source, target, { "premultiply", "discard_alpha" });
590 }
591
TEST(GraphBuilderTest,test_opaque_to_straight)592 TEST(GraphBuilderTest, test_opaque_to_straight)
593 {
594 auto source = make_basic_rgb_state();
595 source.alpha = GraphBuilder::AlphaType::NONE;
596
597 auto target = make_basic_yuv_state();
598 target.alpha = GraphBuilder::AlphaType::STRAIGHT;
599
600 test_case(source, target, { "colorspace", "add_opaque" });
601 }
602
TEST(GraphBuilderTest,test_colorspace_straight_alpha)603 TEST(GraphBuilderTest, test_colorspace_straight_alpha)
604 {
605 auto source = make_basic_yuv_state();
606 source.subsample_w = 1;
607 source.subsample_h = 1;
608 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
609
610 auto target = make_basic_rgb_state();
611 target.alpha = GraphBuilder::AlphaType::STRAIGHT;
612
613 test_case(source, target, {
614 "resize[1]",
615 "premultiply",
616 "colorspace",
617 "unpremultiply",
618 });
619 }
620
TEST(GraphBuilderTest,test_resize_straight_alpha)621 TEST(GraphBuilderTest, test_resize_straight_alpha)
622 {
623 auto source = make_basic_rgb_state();
624 set_resolution(source, 64, 48);
625 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
626
627 auto target = source;
628 set_resolution(target, 128, 96);
629
630 test_case(source, target, {
631 "premultiply",
632 "resize[0]: [64, 48] => [128, 96]",
633 "resize[3]: [64, 48] => [128, 96]",
634 "unpremultiply",
635 });
636 }
637
TEST(GraphBuilderTest,test_resize_premul_alpha)638 TEST(GraphBuilderTest, test_resize_premul_alpha)
639 {
640 auto source = make_basic_rgb_state();
641 set_resolution(source, 64, 48);
642 source.alpha = GraphBuilder::AlphaType::PREMULTIPLIED;
643
644 auto target = source;
645 set_resolution(target, 128, 96);
646
647 test_case(source, target, {
648 "resize[0]: [64, 48] => [128, 96]",
649 "resize[3]: [64, 48] => [128, 96]",
650 });
651 }
652
TEST(GraphBuilderTest,test_straight_depth)653 TEST(GraphBuilderTest, test_straight_depth)
654 {
655 auto source = make_basic_yuv_state();
656 set_resolution(source, 64, 48);
657 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
658
659 auto target = source;
660 target.type = zimg::PixelType::WORD;
661 target.depth = 16;
662
663 test_case(source, target, {
664 "depth[0]: [3/32 l:l] => [1/16 l:l]",
665 "depth[1]: [3/32 l:c] => [1/16 l:c]",
666 "depth[3]: [3/32 l:l] => [1/16 f:l]",
667 });
668 }
669
TEST(GraphBuilderTest,test_straight_depth_tile)670 TEST(GraphBuilderTest, test_straight_depth_tile)
671 {
672 auto source = make_basic_yuv_state();
673 set_resolution(source, 64, 48);
674 source.alpha = GraphBuilder::AlphaType::STRAIGHT;
675 source.active_width = 32;
676 source.active_height = 24;
677
678 auto target = source;
679 set_resolution(target, 32, 24);
680 target.type = zimg::PixelType::WORD;
681 target.depth = 16;
682
683 test_case(source, target, {
684 "resize[0]: [64, 48] => [32, 24] (0.000000, 0.000000, 32.000000, 24.000000)",
685 "depth[0]: [3/32 l:l] => [1/16 l:l]",
686 "resize[1]: [64, 48] => [32, 24] (0.000000, 0.000000, 32.000000, 24.000000)",
687 "depth[1]: [3/32 l:c] => [1/16 l:c]",
688 "resize[3]: [64, 48] => [32, 24] (0.000000, 0.000000, 32.000000, 24.000000)",
689 "depth[3]: [3/32 l:l] => [1/16 f:l]",
690 });
691 }
692