21struct Target { uint32_t pixelFormat;
size_t stride; };
25 ? Target{WUFFS_BASE__PIXEL_FORMAT__RGB, 3}
26 : Target{WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL, 4};
38 wuffs_png__decoder dec;
39 wuffs_base__status st = wuffs_png__decoder__initialize(&dec,
sizeof dec, WUFFS_VERSION, WUFFS_INITIALIZE__DEFAULT_OPTIONS);
41 if (!wuffs_base__status__is_ok(&st)) {
42 HAIO_FAIL(InvalidInput,
"wuffs is not ok");
45 wuffs_base__io_buffer src = wuffs_base__ptr_u8__reader((uint8_t*)blob.data.data(), blob.data.size(),
true);
47 wuffs_base__image_config cfg;
48 memset(&cfg, 0,
sizeof cfg);
49 st = wuffs_base__image_decoder__decode_image_config(wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(&dec), &cfg, &src);
50 if (!wuffs_base__status__is_ok(&st)) {
51 HAIO_FAIL(InvalidInput,
"invalid png config");
54 uint32_t w = wuffs_base__pixel_config__width(&cfg.pixcfg);
55 uint32_t h = wuffs_base__pixel_config__height(&cfg.pixcfg);
57 HAIO_FAIL(InvalidInput,
"invalid png dimensions");
60 constexpr auto target = targetFor(P);
61 wuffs_base__pixel_config__set(&cfg.pixcfg, target.pixelFormat, WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
63 std::vector<uint8_t> buffer(
static_cast<size_t>(w) *
static_cast<size_t>(h) * target.stride);
65 wuffs_base__pixel_buffer pb;
66 st = wuffs_base__pixel_buffer__set_from_slice(&pb, &cfg.pixcfg, wuffs_base__make_slice_u8(buffer.data(), buffer.size()));
67 if (!wuffs_base__status__is_ok(&st)) {
68 HAIO_FAIL(InvalidInput,
"failed to create png pixel buffer");
71 wuffs_base__range_ii_u64 wb = wuffs_base__image_decoder__workbuf_len(wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(&dec));
72 std::vector<uint8_t> work(wb.max_incl ?
static_cast<size_t>(wb.max_incl) : 0);
74 st = wuffs_base__image_decoder__decode_frame(
75 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(&dec),
78 WUFFS_BASE__PIXEL_BLEND__SRC,
79 wuffs_base__make_slice_u8(work.data(), work.size()),
82 if (!wuffs_base__status__is_ok(&st)) {
83 HAIO_FAIL(InvalidInput,
"failed to decode png frame");
87 return Image<P>{
static_cast<int>(w),
static_cast<int>(h), std::move(buffer)};
98 return decodePng<Color::RGBA8888>(blob);
109 return decodePng<Color::RGB888>(blob);