Add wuffs_base__table__flattened_length
diff --git a/example/imageviewer/imageviewer.cc b/example/imageviewer/imageviewer.cc
index 717711c..37eb73d 100644
--- a/example/imageviewer/imageviewer.cc
+++ b/example/imageviewer/imageviewer.cc
@@ -120,6 +120,25 @@
fclose(file);
}
+ // wuffs_aux::DecodeImageCallbacks's default implementation should give us an
+ // interleaved (not multi-planar) pixel buffer, so that all of the pixel data
+ // is in a single 2-dimensional table (plane 0). Later on, we re-interpret
+ // that table as XCB image data, which isn't something we could do if we had
+ // e.g. multi-planar YCbCr.
+ if (!res.pixbuf.pixcfg.pixel_format().is_interleaved()) {
+ printf("%s: non-interleaved pixbuf\n", adj_filename);
+ return false;
+ }
+ wuffs_base__table_u8 tab = res.pixbuf.plane(0);
+ if (tab.width != tab.stride) {
+ // The xcb_image_create_native call, later on, assumes that (tab.height *
+ // tab.stride) bytes are readable, which isn't quite the same as what
+ // wuffs_base__table__flattened_length(tab.width, tab.height, tab.stride)
+ // returns unless the table is tight (its width equals its stride).
+ printf("%s: could not allocate tight pixbuf\n", adj_filename);
+ return false;
+ }
+
g_width = res.pixbuf.pixcfg.width();
g_height = res.pixbuf.pixcfg.height();
g_pixbuf_mem_owner = std::move(res.pixbuf_mem_owner);
diff --git a/internal/cgen/base/fundamental-public.h b/internal/cgen/base/fundamental-public.h
index 1087ec8..14c0911 100644
--- a/internal/cgen/base/fundamental-public.h
+++ b/internal/cgen/base/fundamental-public.h
@@ -1208,6 +1208,45 @@
return wuffs_base__make_slice_u8(NULL, 0);
}
+// wuffs_base__table__flattened_length returns the number of elements covered
+// by the 1-dimensional span that backs a 2-dimensional table. This counts the
+// elements inside the table and, when width != stride, the elements outside
+// the table but between its rows.
+//
+// For example, consider a width 10, height 4, stride 10 table. Mark its first
+// and last (inclusive) elements with 'a' and 'z'. This function returns 40.
+//
+// a123456789
+// 0123456789
+// 0123456789
+// 012345678z
+//
+// Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
+//
+// a123456789
+// 01iiiiiioo
+// ooiiiiiioo
+// ooiiiiii8z
+//
+// This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
+// inside elements plus 8 'o' outside elements. Note that 26 is less than a
+// naive (height * stride = 30) computation. Indeed, advancing 29 elements from
+// the first 'i' would venture past 'z', out of bounds of the original table.
+//
+// It does not check for overflow, but if the arguments come from a table that
+// exists in memory and each element occupies a positive number of bytes then
+// the result should be bounded by the amount of allocatable memory (which
+// shouldn't overflow SIZE_MAX).
+static inline size_t //
+wuffs_base__table__flattened_length(size_t width,
+ size_t height,
+ size_t stride) {
+ if (height == 0) {
+ return 0;
+ }
+ return ((height - 1) * stride) + width;
+}
+
// ---------------- Magic Numbers
// wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 40bfc69..7d9423e 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -115,7 +115,9 @@
" ret.len = 0;\n return ret;\n}\n\nstatic inline wuffs_base__slice_u16 //\nwuffs_base__empty_slice_u16() {\n wuffs_base__slice_u16 ret;\n ret.ptr = NULL;\n ret.len = 0;\n return ret;\n}\n\nstatic inline wuffs_base__slice_u32 //\nwuffs_base__empty_slice_u32() {\n wuffs_base__slice_u32 ret;\n ret.ptr = NULL;\n ret.len = 0;\n return ret;\n}\n\nstatic inline wuffs_base__slice_u64 //\nwuffs_base__empty_slice_u64() {\n wuffs_base__slice_u64 ret;\n ret.ptr = NULL;\n ret.len = 0;\n return ret;\n}\n\nstatic inline wuffs_base__table_u8 //\nwuffs_base__make_table_u8(uint8_t* ptr,\n size_t width,\n size_t height,\n size_t stride) {\n wuffs_base__table_u8 ret;\n ret.ptr = ptr;\n ret.width = width;\n ret.height = height;\n ret.stride = stride;\n return ret;\n}\n\nstatic inline wuffs_base__table_u16 //\nwuffs_base__make_table_u16(uint16_t* ptr,\n size_t width,\n size_t height,\n size_t stride) " +
"{\n wuffs_base__table_u16 ret;\n ret.ptr = ptr;\n ret.width = width;\n ret.height = height;\n ret.stride = stride;\n return ret;\n}\n\nstatic inline wuffs_base__table_u32 //\nwuffs_base__make_table_u32(uint32_t* ptr,\n size_t width,\n size_t height,\n size_t stride) {\n wuffs_base__table_u32 ret;\n ret.ptr = ptr;\n ret.width = width;\n ret.height = height;\n ret.stride = stride;\n return ret;\n}\n\nstatic inline wuffs_base__table_u64 //\nwuffs_base__make_table_u64(uint64_t* ptr,\n size_t width,\n size_t height,\n size_t stride) {\n wuffs_base__table_u64 ret;\n ret.ptr = ptr;\n ret.width = width;\n ret.height = height;\n ret.stride = stride;\n return ret;\n}\n\nstatic inline wuffs_base__table_u8 //\nwuffs_base__empty_table_u8() {\n wuffs_base__table_u8 ret;\n ret.ptr = NULL;\n ret.width = 0;\n ret.height = 0;\n ret.stride = 0;\n return ret;\n}\n\nstatic inline wuffs_base__ta" +
"ble_u16 //\nwuffs_base__empty_table_u16() {\n wuffs_base__table_u16 ret;\n ret.ptr = NULL;\n ret.width = 0;\n ret.height = 0;\n ret.stride = 0;\n return ret;\n}\n\nstatic inline wuffs_base__table_u32 //\nwuffs_base__empty_table_u32() {\n wuffs_base__table_u32 ret;\n ret.ptr = NULL;\n ret.width = 0;\n ret.height = 0;\n ret.stride = 0;\n return ret;\n}\n\nstatic inline wuffs_base__table_u64 //\nwuffs_base__empty_table_u64() {\n wuffs_base__table_u64 ret;\n ret.ptr = NULL;\n ret.width = 0;\n ret.height = 0;\n ret.stride = 0;\n return ret;\n}\n\nstatic inline bool //\nwuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {\n return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||\n ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));\n}\n\n// wuffs_base__slice_u8__subslice_i returns s[i:].\n//\n// It returns an empty slice if i is out of bounds.\nstatic inline wuffs_base__slice_u8 //\nwuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {\n if ((i <= SIZE_MAX) && (i <= s.len)) {\n " +
- " return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_j returns s[:j].\n//\n// It returns an empty slice if j is out of bounds.\nstatic inline wuffs_base__slice_u8 //\nwuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {\n if ((j <= SIZE_MAX) && (j <= s.len)) {\n return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_ij returns s[i:j].\n//\n// It returns an empty slice if i or j is out of bounds.\nstatic inline wuffs_base__slice_u8 //\nwuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,\n uint64_t i,\n uint64_t j) {\n if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {\n return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n" +
+ " return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_j returns s[:j].\n//\n// It returns an empty slice if j is out of bounds.\nstatic inline wuffs_base__slice_u8 //\nwuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {\n if ((j <= SIZE_MAX) && (j <= s.len)) {\n return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_ij returns s[i:j].\n//\n// It returns an empty slice if i or j is out of bounds.\nstatic inline wuffs_base__slice_u8 //\nwuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,\n uint64_t i,\n uint64_t j) {\n if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {\n return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));\n }\n return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__table__flattened_length returns the number o" +
+ "f elements covered\n// by the 1-dimensional span that backs a 2-dimensional table. This counts the\n// elements inside the table and, when width != stride, the elements outside\n// the table but between its rows.\n//\n// For example, consider a width 10, height 4, stride 10 table. Mark its first\n// and last (inclusive) elements with 'a' and 'z'. This function returns 40.\n//\n// a123456789\n// 0123456789\n// 0123456789\n// 012345678z\n//\n// Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.\n//\n// a123456789\n// 01iiiiiioo\n// ooiiiiiioo\n// ooiiiiii8z\n//\n// This function (called with width 6, height 3, stride 10) returns 26: 18 'i'\n// inside elements plus 8 'o' outside elements. Note that 26 is less than a\n// naive (height * stride = 30) computation. Indeed, advancing 29 elements from\n// the first 'i' would venture past 'z', out of bounds of the original table.\n//\n// It does not check for overflow, but if the arguments come from a table that\n// exists in memory and each el" +
+ "ement occupies a positive number of bytes then\n// the result should be bounded by the amount of allocatable memory (which\n// shouldn't overflow SIZE_MAX).\nstatic inline size_t //\nwuffs_base__table__flattened_length(size_t width,\n size_t height,\n size_t stride) {\n if (height == 0) {\n return 0;\n }\n return ((height - 1) * stride) + width;\n}\n\n" +
"" +
"// ---------------- Magic Numbers\n\n// wuffs_base__magic_number_guess_fourcc guesses the file format of some data,\n// given its opening bytes. It returns a positive FourCC value on success.\n//\n// It returns zero if nothing matches its hard-coded list of 'magic numbers'.\n//\n// It returns a negative value if a longer prefix is required for a conclusive\n// result. For example, seeing a single 'B' byte is not enough to discriminate\n// the BMP and BPG image file formats.\n//\n// It does not do a full validity check. Like any guess made from a short\n// prefix of the data, it may return false positives. Data that starts with 99\n// bytes of valid JPEG followed by corruption or truncation is an invalid JPEG\n// image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.\n//\n// Another source of false positives is that some 'magic numbers' are valid\n// ASCII data. A file starting with \"GIF87a and GIF89a are the two versions of\n// GIF\" will match GIF's 'magic number' even if it's plain text, not an image.\n//" +
"\n// For modular builds that divide the base module into sub-modules, using this\n// function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just\n// WUFFS_CONFIG__MODULE__BASE__CORE.\nWUFFS_BASE__MAYBE_STATIC int32_t //\nwuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix);\n" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 52c326f..cd10956 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1419,6 +1419,45 @@
return wuffs_base__make_slice_u8(NULL, 0);
}
+// wuffs_base__table__flattened_length returns the number of elements covered
+// by the 1-dimensional span that backs a 2-dimensional table. This counts the
+// elements inside the table and, when width != stride, the elements outside
+// the table but between its rows.
+//
+// For example, consider a width 10, height 4, stride 10 table. Mark its first
+// and last (inclusive) elements with 'a' and 'z'. This function returns 40.
+//
+// a123456789
+// 0123456789
+// 0123456789
+// 012345678z
+//
+// Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
+//
+// a123456789
+// 01iiiiiioo
+// ooiiiiiioo
+// ooiiiiii8z
+//
+// This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
+// inside elements plus 8 'o' outside elements. Note that 26 is less than a
+// naive (height * stride = 30) computation. Indeed, advancing 29 elements from
+// the first 'i' would venture past 'z', out of bounds of the original table.
+//
+// It does not check for overflow, but if the arguments come from a table that
+// exists in memory and each element occupies a positive number of bytes then
+// the result should be bounded by the amount of allocatable memory (which
+// shouldn't overflow SIZE_MAX).
+static inline size_t //
+wuffs_base__table__flattened_length(size_t width,
+ size_t height,
+ size_t stride) {
+ if (height == 0) {
+ return 0;
+ }
+ return ((height - 1) * stride) + width;
+}
+
// ---------------- Magic Numbers
// wuffs_base__magic_number_guess_fourcc guesses the file format of some data,