Be able to test and bench the libspng library

That's libspng with an 's', instead of libpng without an 's'.

Wuffs' std/png and std/zlib implementations have not been fully
optimized yet, but as a snapshot, here's how it compares with these
"mimic" libraries, libspng and libpng.

On a mid-range x86_64 laptop:

Wuffs/clang9:
wuffs_png_decode_image_19k_8bpp/clang9                    91.9MB/s ± 0%
wuffs_png_decode_image_40k_24bpp/clang9                    128MB/s ± 0%
wuffs_png_decode_image_77k_8bpp/clang9                     342MB/s ± 0%
wuffs_png_decode_image_552k_32bpp_ignore_checksum/clang9   324MB/s ± 0%
wuffs_png_decode_image_552k_32bpp_verify_checksum/clang9   258MB/s ± 0%
wuffs_png_decode_image_4002k_24bpp/clang9                  127MB/s ± 0%

Wuffs/gcc10:
wuffs_png_decode_image_19k_8bpp/gcc10                     94.3MB/s ± 0%
wuffs_png_decode_image_40k_24bpp/gcc10                     131MB/s ± 0%
wuffs_png_decode_image_77k_8bpp/gcc10                      348MB/s ± 1%
wuffs_png_decode_image_552k_32bpp_ignore_checksum/gcc10    319MB/s ± 0%
wuffs_png_decode_image_552k_32bpp_verify_checksum/gcc10    269MB/s ± 0%
wuffs_png_decode_image_4002k_24bpp/gcc10                   131MB/s ± 0%

libspng/clang9:
mimic_png_decode_image_19k_8bpp/clang9                    59.3MB/s ± 1%
mimic_png_decode_image_40k_24bpp/clang9                   78.4MB/s ± 0%
mimic_png_decode_image_77k_8bpp/clang9                     189MB/s ± 0%
mimic_png_decode_image_552k_32bpp_ignore_checksum/clang9   235MB/s ± 0%
mimic_png_decode_image_552k_32bpp_verify_checksum/clang9   203MB/s ± 0%
mimic_png_decode_image_4002k_24bpp/clang9                  110MB/s ± 0%

libspng/gcc10:
mimic_png_decode_image_19k_8bpp/gcc10                     59.5MB/s ± 0%
mimic_png_decode_image_40k_24bpp/gcc10                    77.6MB/s ± 0%
mimic_png_decode_image_77k_8bpp/gcc10                      188MB/s ± 0%
mimic_png_decode_image_552k_32bpp_ignore_checksum/gcc10    223MB/s ± 0%
mimic_png_decode_image_552k_32bpp_verify_checksum/gcc10    193MB/s ± 0%
mimic_png_decode_image_4002k_24bpp/gcc10                   109MB/s ± 0%

libpng (Debian_Testing_Bullseye /usr/lib/x86_64-linux-gnu/libpng.so):
mimic_png_decode_image_19k_8bpp                           58.3MB/s ± 0%
mimic_png_decode_image_40k_24bpp                          73.1MB/s ± 0%
mimic_png_decode_image_77k_8bpp                            177MB/s ± 0%
mimic_png_decode_image_552k_32bpp_ignore_checksum               skipped
mimic_png_decode_image_552k_32bpp_verify_checksum          146MB/s ± 0%
mimic_png_decode_image_4002k_24bpp                         104MB/s ± 0%
diff --git a/test/c/mimiclib/png.c b/test/c/mimiclib/png.c
index 3efa68b..32acd63 100644
--- a/test/c/mimiclib/png.c
+++ b/test/c/mimiclib/png.c
@@ -12,10 +12,119 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// ----------------
+
+// Uncomment this line to test and bench libspng instead of libpng.
+// #define WUFFS_MIMICLIB_USE_LIBSPNG_INSTEAD_OF_LIBPNG 1
+
+#ifdef WUFFS_MIMICLIB_USE_LIBSPNG_INSTEAD_OF_LIBPNG
+
+// We #include a foo.c file, not a foo.h file, as libspng is a "single file C
+// library".
+#include "/path/to/your/copy/of/github.com/randy408/libspng/spng/spng.c"
+
+// We deliberately do not define the
+// WUFFS_MIMICLIB_PNG_DOES_NOT_SUPPORT_QUIRK_IGNORE_CHECKSUM macro.
+
+// libspng (version 0.6.2, released November 2020) calculates but does not
+// verify the CRC-32 checksum on the final IDAT chunk. It also does not verify
+// the Adler-32 checksum. After calling spng_decode_image, it ends in
+// SPNG_STATE_EOI but not a later state such as SPNG_STATE_AFTER_IDAT.
+//
+// libspng commit 9c35dc3 "fix handling of SPNG_CTX_IGNORE_ADLER32", submitted
+// December 2020, fixed Adler-32 but not CRC-32.
+#define WUFFS_MIMICLIB_PNG_DOES_NOT_VERIFY_FINAL_IDAT_CHECKSUMS 1
+
+const char*  //
+mimic_png_decode(uint64_t* n_bytes_out,
+                 wuffs_base__io_buffer* dst,
+                 uint32_t wuffs_initialize_flags,
+                 wuffs_base__pixel_format pixfmt,
+                 uint32_t* quirks_ptr,
+                 size_t quirks_len,
+                 wuffs_base__io_buffer* src) {
+  wuffs_base__io_buffer dst_fallback =
+      wuffs_base__slice_u8__writer(g_mimiclib_scratch_slice_u8);
+  if (!dst) {
+    dst = &dst_fallback;
+  }
+
+  const char* ret = NULL;
+
+  spng_ctx* ctx = spng_ctx_new(0);
+
+  size_t i;
+  for (i = 0; i < quirks_len; i++) {
+    uint32_t q = quirks_ptr[i];
+    if (q == WUFFS_BASE__QUIRK_IGNORE_CHECKSUM) {
+      spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
+    }
+  }
+
+  if (spng_set_png_buffer(ctx, wuffs_base__io_buffer__reader_pointer(src),
+                          wuffs_base__io_buffer__reader_length(src))) {
+    ret = "mimic_png_decode: spng_set_png_buffer failed";
+    goto cleanup0;
+  }
+
+  int fmt = 0;
+  switch (pixfmt.repr) {
+    case WUFFS_BASE__PIXEL_FORMAT__Y:
+      fmt = SPNG_FMT_G8;
+      break;
+    case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+      // libspng doesn't do BGRA8. RGBA8 is the closest approximation. We'll
+      // fix it up later.
+      fmt = SPNG_FMT_RGBA8;
+      break;
+    default:
+      ret = "mimic_png_decode: unsupported pixfmt";
+      goto cleanup0;
+  }
+
+  size_t n = 0;
+  if (spng_decoded_image_size(ctx, fmt, &n)) {
+    ret = "mimic_png_decode: spng_decoded_image_size failed";
+    goto cleanup0;
+  }
+  if (n > wuffs_base__io_buffer__writer_length(dst)) {
+    ret = "mimic_png_decode: image is too large";
+    goto cleanup0;
+  }
+
+  uint8_t* dst_ptr = wuffs_base__io_buffer__writer_pointer(dst);
+  if (spng_decode_image(ctx, dst_ptr, n, fmt, 0)) {
+    ret = "mimic_png_decode: spng_decode_image failed";
+    goto cleanup0;
+  }
+  dst->meta.wi += n;
+  if (n_bytes_out) {
+    *n_bytes_out += n;
+  }
+
+  // Fix up BGRA8 vs RGBA8.
+  if (fmt == SPNG_FMT_RGBA8) {
+    for (; n >= 4; n -= 4) {
+      uint8_t swap = dst_ptr[0];
+      dst_ptr[0] = dst_ptr[2];
+      dst_ptr[2] = swap;
+      dst_ptr += 4;
+    }
+  }
+
+cleanup0:;
+  spng_ctx_free(ctx);
+  return ret;
+}
+
+#else  // WUFFS_MIMICLIB_USE_LIBSPNG_INSTEAD_OF_LIBPNG
 #include "png.h"
 
 #define WUFFS_MIMICLIB_PNG_DOES_NOT_SUPPORT_QUIRK_IGNORE_CHECKSUM 1
 
+// We deliberately do not define the
+// WUFFS_MIMICLIB_PNG_DOES_NOT_VERIFY_FINAL_IDAT_CHECKSUMS macro.
+
 const char*  //
 mimic_png_decode(uint64_t* n_bytes_out,
                  wuffs_base__io_buffer* dst,
@@ -92,3 +201,4 @@
   png_image_free(&pi);
   return ret;
 }
+#endif  // WUFFS_MIMICLIB_USE_LIBSPNG_INSTEAD_OF_LIBPNG
diff --git a/test/c/std/png.c b/test/c/std/png.c
index d6a03a2..7d3e7b3 100644
--- a/test/c/std/png.c
+++ b/test/c/std/png.c
@@ -37,7 +37,11 @@
 "wuffs mimic cflags" to run the mimic benchmarks.
 */
 
-// !! wuffs mimic cflags: -DWUFFS_MIMIC -lpng
+// Libpng requires -lpng (and nothing else). Libspng (note the 's') requires
+// -lm and -lz (and nothing else). It's easiest to just link with the union of
+// all of these libraries.
+//
+// !! wuffs mimic cflags: -DWUFFS_MIMIC -lm -lpng -lz
 
 // Wuffs ships as a "single file C library" or "header file library" as per
 // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
@@ -104,12 +108,14 @@
       "@001F=8A=00;test/data/hippopotamus.regular.png",
       // Change a byte in a PLTE CRC-32 checksum.
       "@0372=52=00;test/data/bricks-dither.png",
+      // Change a byte in a non-final IDAT CRC-32 checksum.
+      "@2029=B7=00;test/data/bricks-color.png",
+#ifndef WUFFS_MIMICLIB_PNG_DOES_NOT_VERIFY_FINAL_IDAT_CHECKSUMS
       // Change a byte in a final IDAT Adler-32 checksum.
       "@084E=26=00;test/data/hippopotamus.regular.png",
       // Change a byte in a final IDAT CRC-32 checksum.
       "@084F=F4=00;test/data/hippopotamus.regular.png",
-      // Change a byte in a non-final IDAT CRC-32 checksum.
-      "@2029=B7=00;test/data/bricks-color.png",
+#endif
   };
 
   int tc;