Add a GifTest for the Haeberli hack
Bug: skia:8766
Change-Id: I5e6ad0a613a3454bf17fd492f1ab4d7831e59092
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/240736
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/tests/GifTest.cpp b/tests/GifTest.cpp
index a3eb0ea..ab4b005 100644
--- a/tests/GifTest.cpp
+++ b/tests/GifTest.cpp
@@ -238,6 +238,53 @@
// "libgif warning [interlace DGifGetLine]"
}
+#ifndef SK_HAS_WUFFS_LIBRARY
+DEF_TEST(Codec_GifInterlacedTruncated, r) {
+ // Check that gInterlacedGIF is exactly 102 bytes long, and that the final
+ // 30 bytes, in the half-open range [72, 102), consists of 0x1b (indicating
+ // a block of 27 bytes), then those 27 bytes, then 0x00 (end of the blocks)
+ // then 0x3b (end of the GIF).
+ if ((sizeof(gInterlacedGIF) != 102) ||
+ (gInterlacedGIF[72] != 0x1b) ||
+ (gInterlacedGIF[100] != 0x00) ||
+ (gInterlacedGIF[101] != 0x3b)) {
+ ERRORF(r, "Invalid gInterlacedGIF data");
+ return;
+ }
+
+ // We want to test the GIF codec's output on some (but not all) of the
+ // LZW-compressed data. As is, there is only one block of LZW-compressed
+ // data, 27 bytes long. Some GIF implementations output intermediate rows
+ // only on block boundaries, so truncating to a prefix of gInterlacedGIF
+ // isn't enough. We also have to modify the block size down from 0x1b so
+ // that the edited version still contains a complete block. In this case,
+ // it's a block of 10 bytes.
+ unsigned char data[83];
+ memcpy(data, gInterlacedGIF, sizeof(data));
+ data[72] = sizeof(data) - 73;
+
+ // Just like test_interlaced_gif_data, check that we get a 9x9 image.
+ SkBitmap bm;
+ bool imageDecodeSuccess = decode_memory(data, sizeof(data), &bm);
+ REPORTER_ASSERT(r, imageDecodeSuccess);
+ REPORTER_ASSERT(r, bm.width() == 9);
+ REPORTER_ASSERT(r, bm.height() == 9);
+
+ // For an interlaced, non-transparent image, we thicken or replicate the
+ // rows of earlier interlace passes so that, when e.g. decoding a GIF
+ // sourced from a slow network connection, we show a richer intermediate
+ // image while waiting for the complete image. This replication is
+ // sometimes described as a "Haeberli inspired technique".
+ //
+ // For a 9 pixel high image, interlacing shuffles the row order to be: 0,
+ // 8, 4, 2, 6, 1, 3, 5, 7. Even though truncating to 10 bytes of
+ // LZW-compressed data only explicitly contains completed rows 0 and 8, we
+ // still expect row 7 to be set, due to replication, and therefore not
+ // transparent black (zero).
+ REPORTER_ASSERT(r, bm.getColor(0, 7) != 0);
+}
+#endif
+
// Regression test for decoding a gif image with sampleSize of 4, which was
// previously crashing.
DEF_TEST(Gif_Sampled, r) {