Files can also contain metadata (e.g. for image files, EXIF information, color profiles and time stamps). By default, Wuffs' decoders skip over metadata, but calling
set_report_metadata will opt in to having
decode_etc methods return early when encountering metadata in the file. Calling
set_report_metadata can be done multiple times, each with a different FourCC code such as
0x49434350 “ICCP” or
0x584D5020 "XMP ", to indicate what sorts of metadata the caller is interested in. Conversely, when the parser encounters metadata (and returns a “@metadata reported” status), call
tell_me_more to see what sort of metadata it is.
Some metadata is short and
tell_me_more will also fill in its
minfo: nptr more_information out parameter with “parsed metadata”. For example, Gamma Correction metadata is a single numerical value and Primary Chromaticities metadata is only eight numbers. From C++ code, call the
metadata_parsed__chrm methods to retrieve these value.
Some metadata is long (or at least variable length) and needs processing by a separate parser. For example, processing XMP metadata usually involves some sort of XML parser, regardless of what particular image format that XMP metadata was embedded in. Wuffs decoders will return “raw metadata” instead of parsing it themselves. Raw metadata is further sub-divided into two categories: “raw passthrough” and “raw transform”. Either way, note that raw metadata might also be arranged in multiple (non-contiguous) chunks of the source data.
“Raw passthrough” means that the bytes in the wire format can be sent “as is” to the separate parser. Call
tell_me_more in a loop (the
dst: io_writer argument will be ignored) and
metadata_raw_passthrough__range to identify a range (a chunk) of the input stream. Divert the bytes in that range to the separate parser (which should advance the
io_buffer to the end of that range) and repeat the loop as long as
tell_me_more returned a “$even more information” status.
“Raw transform” means that the bytes in the wire format have to be further processed (e.g. decompressed) before sending them on to the separate parser. That processing is done by the decoder callee, not the caller. Pass a writable
dst io_buffer to
tell_me_more (where writable means that it has a positive
writer_length) and implementations should fill in that buffer with post-transformed (e.g. decompressed) data to send onwards. Like any
io_transformer-like coroutine, this should be in a loop, as it may suspend with “$short read” and “$short write” statuses.
Either way, break the loop (after handling the
minfo out parameters) when
tell_me_more returns a NULL status, meaning ok, when the metadata is complete. Afterwards, call the original action (e.g.
decode_etc) again to resume after the “@metadata reported” detour.
tell_me_more both returns a status and fills in the
minfo out parameters. Subtly, the caller should process the out parameters before considering the status. It is valid for the callee to fill in the out parameters with partial results when returning an error status or with full results when returning an ok status. ‘No partial results’ is represented by an unchanged
minfo. For example, if
minfo was reset to zero before each
tell_me_more call then
minfo.flavor remaining zero means that the
minfo was unchanged, as valid flavor values are non-zero.