Add DecodeImageCallbacks::OnImageFormat def impl
diff --git a/example/imageviewer/imageviewer.cc b/example/imageviewer/imageviewer.cc
index 73a07c1..4a8fc07 100644
--- a/example/imageviewer/imageviewer.cc
+++ b/example/imageviewer/imageviewer.cc
@@ -90,26 +90,6 @@
uint32_t g_background_color_index = 0;
class Callbacks : public wuffs_aux::DecodeImageCallbacks {
- wuffs_base__image_decoder::unique_ptr //
- OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix) override {
- switch (fourcc) {
- case WUFFS_BASE__FOURCC__BMP:
- return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
- case WUFFS_BASE__FOURCC__GIF:
- return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
- case WUFFS_BASE__FOURCC__NIE:
- return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
- case WUFFS_BASE__FOURCC__PNG: {
- auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
- dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
- return dec;
- }
- case WUFFS_BASE__FOURCC__WBMP:
- return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
- }
- return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
- }
-
DecodeImageCallbacks::AllocResult //
OnImageConfig(const wuffs_base__image_config& image_config) override {
uint32_t w = image_config.pixcfg.width();
diff --git a/internal/cgen/auxiliary/image.cc b/internal/cgen/auxiliary/image.cc
index 558ccfa..bbc133b 100644
--- a/internal/cgen/auxiliary/image.cc
+++ b/internal/cgen/auxiliary/image.cc
@@ -48,6 +48,43 @@
mem_slice(wuffs_base__empty_slice_u8()),
error_message(std::move(error_message0)) {}
+wuffs_base__image_decoder::unique_ptr //
+DecodeImageCallbacks::OnImageFormat(uint32_t fourcc,
+ wuffs_base__slice_u8 prefix) {
+ switch (fourcc) {
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
+ case WUFFS_BASE__FOURCC__BMP:
+ return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
+ case WUFFS_BASE__FOURCC__GIF:
+ return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
+ case WUFFS_BASE__FOURCC__NIE:
+ return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
+ case WUFFS_BASE__FOURCC__PNG: {
+ auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
+ // Favor faster decodes over rejecting invalid checksums.
+ dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
+ return dec;
+ }
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
+ case WUFFS_BASE__FOURCC__WBMP:
+ return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+ }
+
+ return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
+}
+
DecodeImageCallbacks::AllocResult //
DecodeImageCallbacks::OnImageConfig(
const wuffs_base__image_config& image_config) {
diff --git a/internal/cgen/auxiliary/image.hh b/internal/cgen/auxiliary/image.hh
index 47702dc..35f5b63 100644
--- a/internal/cgen/auxiliary/image.hh
+++ b/internal/cgen/auxiliary/image.hh
@@ -58,19 +58,27 @@
// OnImageFormat returns the image decoder for the input data's file format.
// Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
//
- // Common formats will have a non-zero FourCC value, such as
- // WUFFS_BASE__FOURCC__JPEG. A zero FourCC code means that the caller is
- // responsible for examining the opening bytes (a prefix) of the input data.
- // OnImageFormat implementations should not modify those bytes.
+ // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
+ // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that the
+ // caller is responsible for examining the opening bytes (a prefix) of the
+ // input data. OnImageFormat implementations should not modify those bytes.
//
// OnImageFormat might be called more than once, since some image file
// formats can wrap others. For example, a nominal BMP file can actually
// contain a JPEG or a PNG.
//
- // There is no default implementation, as modular Wuffs builds (those that
- // define WUFFS_CONFIG__MODULES) may enable or disable particular codecs.
+ // The default OnImageFormat accepts the FOURCC codes listed below. For
+ // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
+ // of the ETC file format is optional (for each value of ETC) and depends on
+ // the corresponding module to be enabled at compile time (i.e. #define'ing
+ // WUFFS_CONFIG__MODULE__ETC).
+ // - WUFFS_BASE__FOURCC__BMP
+ // - WUFFS_BASE__FOURCC__GIF
+ // - WUFFS_BASE__FOURCC__NIE
+ // - WUFFS_BASE__FOURCC__PNG
+ // - WUFFS_BASE__FOURCC__WBMP
virtual wuffs_base__image_decoder::unique_ptr //
- OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix) = 0;
+ OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix);
// OnImageConfig allocates the pixel buffer.
//
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 46fb8a9..1bfb326 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -736,9 +736,10 @@
const AuxImageCc = "" +
"// ---------------- Auxiliary - Image\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n wuffs_base__slice_u8 pixbuf_mem_slice0,\n wuffs_base__pixel_buffer pixbuf0,\n std::string&& error_message0)\n : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),\n pixbuf_mem_slice(pixbuf_mem_slice0),\n pixbuf(pixbuf0),\n error_message(std::move(error_message0)) {}\n\nDecodeImageResult::DecodeImageResult(std::string&& error_message0)\n : pixbuf_mem_owner(nullptr, &free),\n pixbuf_mem_slice(wuffs_base__empty_slice_u8()),\n pixbuf(wuffs_base__null_pixel_buffer()),\n error_message(std::move(error_message0)) {}\n\nDecodeImageCallbacks::AllocResult::AllocResult(MemOwner&& mem_owner0,\n wuffs_base__slice_u8 mem_slice0" +
- ")\n : mem_owner(std::move(mem_owner0)),\n mem_slice(mem_slice0),\n error_message(\"\") {}\n\nDecodeImageCallbacks::AllocResult::AllocResult(std::string&& error_message0)\n : mem_owner(nullptr, &free),\n mem_slice(wuffs_base__empty_slice_u8()),\n error_message(std::move(error_message0)) {}\n\nDecodeImageCallbacks::AllocResult //\nDecodeImageCallbacks::OnImageConfig(\n const wuffs_base__image_config& image_config) {\n uint32_t w = image_config.pixcfg.width();\n uint32_t h = image_config.pixcfg.height();\n if ((w == 0) || (h == 0)) {\n return AllocResult(\"\");\n }\n uint64_t len = image_config.pixcfg.pixbuf_len();\n if ((len == 0) || (SIZE_MAX < len)) {\n return AllocResult(DecodeImage_UnsupportedPixelConfiguration);\n }\n void* ptr = calloc((size_t)len, 1);\n if (!ptr) {\n return AllocResult(DecodeImage_OutOfMemory);\n }\n return AllocResult(MemOwner(ptr, &free),\n wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));\n}\n\nDecodeImageCallbacks::AllocResult //\nDecodeImage" +
- "Callbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len) {\n if (len.max_incl == 0) {\n return DecodeImageCallbacks::AllocResult(\"\");\n } else if (SIZE_MAX < len.max_incl) {\n return DecodeImageCallbacks::AllocResult(DecodeImage_OutOfMemory);\n }\n void* p = calloc((size_t)len.max_incl, 1);\n if (!p) {\n return DecodeImageCallbacks::AllocResult(DecodeImage_OutOfMemory);\n }\n return DecodeImageCallbacks::AllocResult(\n MemOwner(p, &free),\n wuffs_base__make_slice_u8((uint8_t*)p, (size_t)len.max_incl));\n}\n\nvoid //\nDecodeImageCallbacks::Done(\n DecodeImageResult& result,\n sync_io::Input& input,\n IOBuffer& buffer,\n wuffs_base__image_decoder::unique_ptr image_decoder) {}\n\nconst char DecodeImage_BufferIsTooShort[] = //\n \"wuffs_aux::DecodeImage: buffer is too short\";\nconst char DecodeImage_MaxInclDimensionExceeded[] = //\n \"wuffs_aux::DecodeImage: max_incl_dimension exceeded\";\nconst char DecodeImage_OutOfMemory[] = //\n \"wuffs_aux::DecodeImage: out of memory\";\nconst char DecodeImage" +
- "_UnexpectedEndOfFile[] = //\n \"wuffs_aux::DecodeImage: unexpected end of file\";\nconst char DecodeImage_UnsupportedImageFormat[] = //\n \"wuffs_aux::DecodeImage: unsupported image format\";\nconst char DecodeImage_UnsupportedPixelBlend[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel blend\";\nconst char DecodeImage_UnsupportedPixelConfiguration[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel configuration\";\nconst char DecodeImage_UnsupportedPixelFormat[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel format\";\n\n" +
+ ")\n : mem_owner(std::move(mem_owner0)),\n mem_slice(mem_slice0),\n error_message(\"\") {}\n\nDecodeImageCallbacks::AllocResult::AllocResult(std::string&& error_message0)\n : mem_owner(nullptr, &free),\n mem_slice(wuffs_base__empty_slice_u8()),\n error_message(std::move(error_message0)) {}\n\nwuffs_base__image_decoder::unique_ptr //\nDecodeImageCallbacks::OnImageFormat(uint32_t fourcc,\n wuffs_base__slice_u8 prefix) {\n switch (fourcc) {\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)\n case WUFFS_BASE__FOURCC__BMP:\n return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)\n case WUFFS_BASE__FOURCC__GIF:\n return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)\n case WUFFS_BASE__FOURCC__NIE:\n return wuffs_nie__decoder::alloc_as__wuffs_ba" +
+ "se__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)\n case WUFFS_BASE__FOURCC__PNG: {\n auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();\n // Favor faster decodes over rejecting invalid checksums.\n dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);\n return dec;\n }\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)\n case WUFFS_BASE__FOURCC__WBMP:\n return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n }\n\n return wuffs_base__image_decoder::unique_ptr(nullptr, &free);\n}\n\nDecodeImageCallbacks::AllocResult //\nDecodeImageCallbacks::OnImageConfig(\n const wuffs_base__image_config& image_config) {\n uint32_t w = image_config.pixcfg.width();\n uint32_t h = image_config.pixcfg.height();\n if ((w == 0) || (h == 0)) {\n return AllocResult(\"\");\n }\n uint64_t len = image_config.pixcfg.pixbuf_len();\n if ((len == 0) || (SIZE_MAX < len)) {\n return " +
+ "AllocResult(DecodeImage_UnsupportedPixelConfiguration);\n }\n void* ptr = calloc((size_t)len, 1);\n if (!ptr) {\n return AllocResult(DecodeImage_OutOfMemory);\n }\n return AllocResult(MemOwner(ptr, &free),\n wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));\n}\n\nDecodeImageCallbacks::AllocResult //\nDecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len) {\n if (len.max_incl == 0) {\n return DecodeImageCallbacks::AllocResult(\"\");\n } else if (SIZE_MAX < len.max_incl) {\n return DecodeImageCallbacks::AllocResult(DecodeImage_OutOfMemory);\n }\n void* p = calloc((size_t)len.max_incl, 1);\n if (!p) {\n return DecodeImageCallbacks::AllocResult(DecodeImage_OutOfMemory);\n }\n return DecodeImageCallbacks::AllocResult(\n MemOwner(p, &free),\n wuffs_base__make_slice_u8((uint8_t*)p, (size_t)len.max_incl));\n}\n\nvoid //\nDecodeImageCallbacks::Done(\n DecodeImageResult& result,\n sync_io::Input& input,\n IOBuffer& buffer,\n wuffs_base__image_decoder::unique_ptr image_" +
+ "decoder) {}\n\nconst char DecodeImage_BufferIsTooShort[] = //\n \"wuffs_aux::DecodeImage: buffer is too short\";\nconst char DecodeImage_MaxInclDimensionExceeded[] = //\n \"wuffs_aux::DecodeImage: max_incl_dimension exceeded\";\nconst char DecodeImage_OutOfMemory[] = //\n \"wuffs_aux::DecodeImage: out of memory\";\nconst char DecodeImage_UnexpectedEndOfFile[] = //\n \"wuffs_aux::DecodeImage: unexpected end of file\";\nconst char DecodeImage_UnsupportedImageFormat[] = //\n \"wuffs_aux::DecodeImage: unsupported image format\";\nconst char DecodeImage_UnsupportedPixelBlend[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel blend\";\nconst char DecodeImage_UnsupportedPixelConfiguration[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel configuration\";\nconst char DecodeImage_UnsupportedPixelFormat[] = //\n \"wuffs_aux::DecodeImage: unsupported pixel format\";\n\n" +
"" +
"// --------\n\nnamespace {\n\nstd::string //\nDecodeImageAdvanceIOBuf(sync_io::Input& input,\n wuffs_base__io_buffer& io_buf,\n bool compactable,\n uint64_t min_excl_pos,\n uint64_t pos) {\n if ((pos <= min_excl_pos) || (pos < io_buf.reader_position())) {\n // Redirects must go forward.\n return DecodeImage_UnsupportedImageFormat;\n }\n while (true) {\n uint64_t relative_pos = pos - io_buf.reader_position();\n if (relative_pos <= io_buf.reader_length()) {\n io_buf.meta.ri += (size_t)relative_pos;\n break;\n } else if (io_buf.meta.closed) {\n return DecodeImage_UnexpectedEndOfFile;\n }\n io_buf.meta.ri = io_buf.meta.wi;\n if (compactable) {\n io_buf.compact();\n }\n std::string error_message = input.CopyIn(&io_buf);\n if (!error_message.empty()) {\n return error_message;\n }\n }\n return \"\";\n}\n\nDecodeImageResult //\nDecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,\n " +
" DecodeImageCallbacks& callbacks,\n sync_io::Input& input,\n wuffs_base__io_buffer& io_buf,\n uint32_t override_pixel_format_repr,\n wuffs_base__pixel_blend pixel_blend,\n uint32_t max_incl_dimension) {\n // Check args.\n switch (override_pixel_format_repr) {\n case 0:\n case WUFFS_BASE__PIXEL_FORMAT__BGR_565:\n case WUFFS_BASE__PIXEL_FORMAT__BGR:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n break;\n default:\n return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);\n }\n switch (pixel_blend) {\n case WUFFS_BASE__PIXEL_BLEND__SRC:\n case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:\n break;\n default:\n return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);\n }\n\n wuffs_base__image_config image_config = wuffs_base__null_image_config();\n uint64_t start_pos = io_buf.reader_position();\n bool redirected = false;\n int32_t fourcc = 0;\nredirect:\n do {\n // Det" +
@@ -754,12 +755,13 @@
const AuxImageHh = "" +
"// ---------------- Auxiliary - Image\n\nnamespace wuffs_aux {\n\nstruct DecodeImageResult {\n DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n wuffs_base__slice_u8 pixbuf_mem_slice0,\n wuffs_base__pixel_buffer pixbuf0,\n std::string&& error_message0);\n DecodeImageResult(std::string&& error_message0);\n\n MemOwner pixbuf_mem_owner;\n wuffs_base__slice_u8 pixbuf_mem_slice;\n wuffs_base__pixel_buffer pixbuf;\n std::string error_message;\n};\n\n// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always\n// called in this order:\n// 1. OnImageFormat\n// 2. OnImageConfig\n// 3. AllocWorkbuf\n// 4. Done\n//\n// It may return early - the third callback might not be invoked if the second\n// one fails (returns a non-empty error message) - but the final callback\n// (Done) is always invoked.\nclass DecodeImageCallbacks {\n public:\n // AllocResult holds a memory allocation (the result of malloc or new, a\n // statically allocated pointer, etc), or an error " +
- "message. The memory is\n // de-allocated when mem_owner goes out of scope and is destroyed.\n struct AllocResult {\n AllocResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 mem_slice0);\n AllocResult(std::string&& error_message0);\n\n MemOwner mem_owner;\n wuffs_base__slice_u8 mem_slice;\n std::string error_message;\n };\n\n // OnImageFormat returns the image decoder for the input data's file format.\n // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).\n //\n // Common formats will have a non-zero FourCC value, such as\n // WUFFS_BASE__FOURCC__JPEG. A zero FourCC code means that the caller is\n // responsible for examining the opening bytes (a prefix) of the input data.\n // OnImageFormat implementations should not modify those bytes.\n //\n // OnImageFormat might be called more than once, since some image file\n // formats can wrap others. For example, a nominal BMP file can actually\n // contain a JPEG or a PNG.\n //\n // There is no default implementation, as modular Wuffs b" +
- "uilds (those that\n // define WUFFS_CONFIG__MODULES) may enable or disable particular codecs.\n virtual wuffs_base__image_decoder::unique_ptr //\n OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix) = 0;\n\n // OnImageConfig allocates the pixel buffer.\n //\n // The default OnImageConfig implementation allocates zeroed memory.\n virtual AllocResult //\n OnImageConfig(const wuffs_base__image_config& image_config);\n\n // AllocWorkbuf allocates the work buffer. The allocated buffer's length\n // should be at least len.min_incl, but larger allocations (up to\n // len.max_incl) may have better performance (by using more memory).\n //\n // The default AllocWorkbuf implementation allocates len.max_incl bytes of\n // zeroed memory.\n virtual AllocResult //\n AllocWorkbuf(wuffs_base__range_ii_u64 len);\n\n // Done is always the last Callback method called by DecodeImage, whether or\n // not parsing the input encountered an error. Even when successful, trailing\n // data may remain in input and buffer.\n //\n " +
- "// The image_decoder is the one returned by OnImageFormat (if OnImageFormat\n // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,\n // ownership moves to the Done implementation.\n //\n // Do not keep a reference to buffer or buffer.data.ptr after Done returns,\n // as DecodeImage may then de-allocate the backing array.\n //\n // The default Done implementation is a no-op, other than running the\n // image_decoder unique_ptr destructor.\n virtual void //\n Done(DecodeImageResult& result,\n sync_io::Input& input,\n IOBuffer& buffer,\n wuffs_base__image_decoder::unique_ptr image_decoder);\n};\n\nextern const char DecodeImage_BufferIsTooShort[];\nextern const char DecodeImage_MaxInclDimensionExceeded[];\nextern const char DecodeImage_OutOfMemory[];\nextern const char DecodeImage_UnexpectedEndOfFile[];\nextern const char DecodeImage_UnsupportedImageFormat[];\nextern const char DecodeImage_UnsupportedPixelBlend[];\nextern const char DecodeImage_UnsupportedPixelConfiguration[];\nextern c" +
- "onst char DecodeImage_UnsupportedPixelFormat[];\n\n// DecodeImage decodes the image data in input. A variety of image file formats\n// can be decoded, depending on what callbacks.OnImageFormat returns.\n//\n// For animated formats, only the first frame is returned, since the API is\n// simpler for synchronous I/O and having DecodeImage only return when\n// completely done, but rendering animation often involves handling other\n// events in between animation frames. To decode multiple frames of animated\n// images, or for asynchronous I/O (e.g. when decoding an image streamed over\n// the network), use Wuffs' lower level C API instead of its higher level,\n// simplified C++ API (the wuffs_aux API).\n//\n// The DecodeImageResult's fields depend on whether decoding succeeded:\n// - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()\n// is true.\n// - On partial success (e.g. the input file was truncated but we are still\n// able to decode some of the pixels), error_message is non-empty but\n// pi" +
- "xbuf.pixcfg.is_valid() is still true. It is up to the caller whether to\n// accept or reject partial success.\n// - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()\n// is false.\n//\n// The callbacks allocate the pixel buffer memory and work buffer memory. On\n// success, pixel buffer memory ownership is passed to the DecodeImage caller\n// as the returned pixbuf_mem_owner. Regardless of success or failure, the work\n// buffer memory is deleted.\n//\n// If override_pixel_format_repr is zero then the pixel buffer will have the\n// image file's natural pixel format. For example, GIF images' natural pixel\n// format is an indexed one.\n//\n// If override_pixel_format_repr is non-zero (and one of the constants listed\n// below) then the image will be decoded to that particular pixel format:\n// - WUFFS_BASE__PIXEL_FORMAT__BGR_565\n// - WUFFS_BASE__PIXEL_FORMAT__BGR\n// - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL\n// - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL\n//\n// The pixel_blend (one of the constants" +
- " listed below) determines how to\n// composite the decoded image over the pixel buffer's original pixels (as\n// returned by callbacks.OnImageConfig):\n// - WUFFS_BASE__PIXEL_BLEND__SRC\n// - WUFFS_BASE__PIXEL_BLEND__SRC_OVER\n//\n// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's\n// width or height is greater than max_incl_dimension.\nDecodeImageResult //\nDecodeImage(DecodeImageCallbacks& callbacks,\n sync_io::Input& input,\n uint32_t override_pixel_format_repr,\n wuffs_base__pixel_blend pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC,\n uint32_t max_incl_dimension = 1048575); // 0x000F_FFFF\n\n} // namespace wuffs_aux\n" +
+ "message. The memory is\n // de-allocated when mem_owner goes out of scope and is destroyed.\n struct AllocResult {\n AllocResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 mem_slice0);\n AllocResult(std::string&& error_message0);\n\n MemOwner mem_owner;\n wuffs_base__slice_u8 mem_slice;\n std::string error_message;\n };\n\n // OnImageFormat returns the image decoder for the input data's file format.\n // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).\n //\n // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],\n // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that the\n // caller is responsible for examining the opening bytes (a prefix) of the\n // input data. OnImageFormat implementations should not modify those bytes.\n //\n // OnImageFormat might be called more than once, since some image file\n // formats can wrap others. For example, a nominal BMP file can actually\n // contain a JPEG or a PNG.\n //\n // The default OnImageFormat acc" +
+ "epts the FOURCC codes listed below. For\n // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance\n // of the ETC file format is optional (for each value of ETC) and depends on\n // the corresponding module to be enabled at compile time (i.e. #define'ing\n // WUFFS_CONFIG__MODULE__ETC).\n // - WUFFS_BASE__FOURCC__BMP\n // - WUFFS_BASE__FOURCC__GIF\n // - WUFFS_BASE__FOURCC__NIE\n // - WUFFS_BASE__FOURCC__PNG\n // - WUFFS_BASE__FOURCC__WBMP\n virtual wuffs_base__image_decoder::unique_ptr //\n OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix);\n\n // OnImageConfig allocates the pixel buffer.\n //\n // The default OnImageConfig implementation allocates zeroed memory.\n virtual AllocResult //\n OnImageConfig(const wuffs_base__image_config& image_config);\n\n // AllocWorkbuf allocates the work buffer. The allocated buffer's length\n // should be at least len.min_incl, but larger allocations (up to\n // len.max_incl) may have better performance (by using more memory).\n //\n // Th" +
+ "e default AllocWorkbuf implementation allocates len.max_incl bytes of\n // zeroed memory.\n virtual AllocResult //\n AllocWorkbuf(wuffs_base__range_ii_u64 len);\n\n // Done is always the last Callback method called by DecodeImage, whether or\n // not parsing the input encountered an error. Even when successful, trailing\n // data may remain in input and buffer.\n //\n // The image_decoder is the one returned by OnImageFormat (if OnImageFormat\n // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,\n // ownership moves to the Done implementation.\n //\n // Do not keep a reference to buffer or buffer.data.ptr after Done returns,\n // as DecodeImage may then de-allocate the backing array.\n //\n // The default Done implementation is a no-op, other than running the\n // image_decoder unique_ptr destructor.\n virtual void //\n Done(DecodeImageResult& result,\n sync_io::Input& input,\n IOBuffer& buffer,\n wuffs_base__image_decoder::unique_ptr image_decoder);\n};\n\nextern const char" +
+ " DecodeImage_BufferIsTooShort[];\nextern const char DecodeImage_MaxInclDimensionExceeded[];\nextern const char DecodeImage_OutOfMemory[];\nextern const char DecodeImage_UnexpectedEndOfFile[];\nextern const char DecodeImage_UnsupportedImageFormat[];\nextern const char DecodeImage_UnsupportedPixelBlend[];\nextern const char DecodeImage_UnsupportedPixelConfiguration[];\nextern const char DecodeImage_UnsupportedPixelFormat[];\n\n// DecodeImage decodes the image data in input. A variety of image file formats\n// can be decoded, depending on what callbacks.OnImageFormat returns.\n//\n// For animated formats, only the first frame is returned, since the API is\n// simpler for synchronous I/O and having DecodeImage only return when\n// completely done, but rendering animation often involves handling other\n// events in between animation frames. To decode multiple frames of animated\n// images, or for asynchronous I/O (e.g. when decoding an image streamed over\n// the network), use Wuffs' lower level C API instead of its higher level,\n" +
+ "// simplified C++ API (the wuffs_aux API).\n//\n// The DecodeImageResult's fields depend on whether decoding succeeded:\n// - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()\n// is true.\n// - On partial success (e.g. the input file was truncated but we are still\n// able to decode some of the pixels), error_message is non-empty but\n// pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to\n// accept or reject partial success.\n// - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()\n// is false.\n//\n// The callbacks allocate the pixel buffer memory and work buffer memory. On\n// success, pixel buffer memory ownership is passed to the DecodeImage caller\n// as the returned pixbuf_mem_owner. Regardless of success or failure, the work\n// buffer memory is deleted.\n//\n// If override_pixel_format_repr is zero then the pixel buffer will have the\n// image file's natural pixel format. For example, GIF images' natural pixel\n// format is an indexed" +
+ " one.\n//\n// If override_pixel_format_repr is non-zero (and one of the constants listed\n// below) then the image will be decoded to that particular pixel format:\n// - WUFFS_BASE__PIXEL_FORMAT__BGR_565\n// - WUFFS_BASE__PIXEL_FORMAT__BGR\n// - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL\n// - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL\n//\n// The pixel_blend (one of the constants listed below) determines how to\n// composite the decoded image over the pixel buffer's original pixels (as\n// returned by callbacks.OnImageConfig):\n// - WUFFS_BASE__PIXEL_BLEND__SRC\n// - WUFFS_BASE__PIXEL_BLEND__SRC_OVER\n//\n// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's\n// width or height is greater than max_incl_dimension.\nDecodeImageResult //\nDecodeImage(DecodeImageCallbacks& callbacks,\n sync_io::Input& input,\n uint32_t override_pixel_format_repr,\n wuffs_base__pixel_blend pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC,\n uint32_t max_incl_dimension = 1048575); // 0x000F_" +
+ "FFFF\n\n} // namespace wuffs_aux\n" +
""
const AuxJsonCc = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index c55cd6d..728a550 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -9458,19 +9458,27 @@
// OnImageFormat returns the image decoder for the input data's file format.
// Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
//
- // Common formats will have a non-zero FourCC value, such as
- // WUFFS_BASE__FOURCC__JPEG. A zero FourCC code means that the caller is
- // responsible for examining the opening bytes (a prefix) of the input data.
- // OnImageFormat implementations should not modify those bytes.
+ // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
+ // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that the
+ // caller is responsible for examining the opening bytes (a prefix) of the
+ // input data. OnImageFormat implementations should not modify those bytes.
//
// OnImageFormat might be called more than once, since some image file
// formats can wrap others. For example, a nominal BMP file can actually
// contain a JPEG or a PNG.
//
- // There is no default implementation, as modular Wuffs builds (those that
- // define WUFFS_CONFIG__MODULES) may enable or disable particular codecs.
+ // The default OnImageFormat accepts the FOURCC codes listed below. For
+ // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
+ // of the ETC file format is optional (for each value of ETC) and depends on
+ // the corresponding module to be enabled at compile time (i.e. #define'ing
+ // WUFFS_CONFIG__MODULE__ETC).
+ // - WUFFS_BASE__FOURCC__BMP
+ // - WUFFS_BASE__FOURCC__GIF
+ // - WUFFS_BASE__FOURCC__NIE
+ // - WUFFS_BASE__FOURCC__PNG
+ // - WUFFS_BASE__FOURCC__WBMP
virtual wuffs_base__image_decoder::unique_ptr //
- OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix) = 0;
+ OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix);
// OnImageConfig allocates the pixel buffer.
//
@@ -36766,6 +36774,43 @@
mem_slice(wuffs_base__empty_slice_u8()),
error_message(std::move(error_message0)) {}
+wuffs_base__image_decoder::unique_ptr //
+DecodeImageCallbacks::OnImageFormat(uint32_t fourcc,
+ wuffs_base__slice_u8 prefix) {
+ switch (fourcc) {
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
+ case WUFFS_BASE__FOURCC__BMP:
+ return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
+ case WUFFS_BASE__FOURCC__GIF:
+ return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
+ case WUFFS_BASE__FOURCC__NIE:
+ return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
+ case WUFFS_BASE__FOURCC__PNG: {
+ auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
+ // Favor faster decodes over rejecting invalid checksums.
+ dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
+ return dec;
+ }
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
+ case WUFFS_BASE__FOURCC__WBMP:
+ return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+ }
+
+ return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
+}
+
DecodeImageCallbacks::AllocResult //
DecodeImageCallbacks::OnImageConfig(
const wuffs_base__image_config& image_config) {