summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/png
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/png
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/png')
-rw-r--r--testing/web-platform/tests/png/META.yml4
-rw-r--r--testing/web-platform/tests/png/apng/acTL-plays-one.html34
-rw-r--r--testing/web-platform/tests/png/apng/acTL-plays-two.html35
-rw-r--r--testing/web-platform/tests/png/apng/apng-blue-rect-checkerboard-ref.html24
-rw-r--r--testing/web-platform/tests/png/apng/apng-blue-rectangle-one-ref.html22
-rw-r--r--testing/web-platform/tests/png/apng/apng-blue-rectangle-ref.html23
-rw-r--r--testing/web-platform/tests/png/apng/apng-checkerboard-ref.html24
-rw-r--r--testing/web-platform/tests/png/apng/apng-darkblue-rectangle-ref.html22
-rw-r--r--testing/web-platform/tests/png/apng/apng-graywhite-rectangle-ref.html8
-rw-r--r--testing/web-platform/tests/png/apng/apng-lime-rectangle-ref.html8
-rw-r--r--testing/web-platform/tests/png/apng/apng-solidgray-rectangle-ref.html8
-rw-r--r--testing/web-platform/tests/png/apng/apng-solidlime-rectangle-ref.html8
-rw-r--r--testing/web-platform/tests/png/apng/fDAT-inherits-cICP.html22
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-acTL-ordering.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-blend-over-repeatedly.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-blend-over-solid.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-blend-source-nearly-transparent.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-blend-source-solid.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-blend-source-transparent.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-background-final.html34
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-background.html34
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-before-region-background.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-in-region-background.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-in-region-none.html36
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-in-region-previous.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-none.html24
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-previous-final.html36
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-previous-first.html35
-rw-r--r--testing/web-platform/tests/png/apng/fcTL-dispose-previous.html35
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-16bit.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-1bit-PLTE-tRNS.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-1bit-PLTE.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-2bit-PLTE-tRNS.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-8bit-gray-alpha.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-8bit-gray.html34
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-split-basic.html20
-rw-r--r--testing/web-platform/tests/png/apng/fdAT-split-zero-length.html20
-rw-r--r--testing/web-platform/tests/png/apng/first-frame-IDAT.html20
-rw-r--r--testing/web-platform/tests/png/apng/first-frame-not-IDAT.html20
-rw-r--r--testing/web-platform/tests/png/apng/manual/acTL-plays-one-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/acTL-plays-two-manual.html26
-rw-r--r--testing/web-platform/tests/png/apng/manual/acTL-plays-zero-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/fcTL-delay-16bit-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/fcTL-delay-basic-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/fcTL-delay-rounding-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-denom-manual.html25
-rw-r--r--testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-num-manual.html26
-rw-r--r--testing/web-platform/tests/png/apng/nearly-transparent-ref.html24
-rw-r--r--testing/web-platform/tests/png/apng/resources/README.md14
-rw-r--r--testing/web-platform/tests/png/apng/resources/generate.pl390
-rw-r--r--testing/web-platform/tests/png/apng/resources/source.html1014
-rw-r--r--testing/web-platform/tests/png/apng/support/001.pngbin0 -> 307 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/002.pngbin0 -> 470 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/005.pngbin0 -> 486 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/006.pngbin0 -> 502 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/007.pngbin0 -> 617 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/008.pngbin0 -> 572 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/009.pngbin0 -> 508 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/010.pngbin0 -> 780 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/011.pngbin0 -> 508 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/012.pngbin0 -> 371 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/013.pngbin0 -> 613 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/014.pngbin0 -> 327 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/015.pngbin0 -> 492 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/016.pngbin0 -> 677 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/017.pngbin0 -> 671 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/018.pngbin0 -> 534 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/019.pngbin0 -> 614 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/020.pngbin0 -> 579 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/021.pngbin0 -> 28791 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/024.pngbin0 -> 508 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/025.pngbin0 -> 1068 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/026.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/027.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/028.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/029.pngbin0 -> 1067 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/030.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/031.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/032.pngbin0 -> 646 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/033.pngbin0 -> 915 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/034.pngbin0 -> 331 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/035.pngbin0 -> 668 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/036.pngbin0 -> 262 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/037.pngbin0 -> 308 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/038.pngbin0 -> 276 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/062.pngbin0 -> 445 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/blue-with-hole.pngbin0 -> 208 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/blue.pngbin0 -> 190 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/darkblue.pngbin0 -> 191 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/gray-white.pngbin0 -> 213 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/lime.pngbin0 -> 179 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/nearly.pngbin0 -> 189 bytes
-rw-r--r--testing/web-platform/tests/png/apng/support/solid-gray.pngbin0 -> 191 bytes
-rw-r--r--testing/web-platform/tests/png/cicp-chunk.html40
-rw-r--r--testing/web-platform/tests/png/exif-chunk.html38
-rw-r--r--testing/web-platform/tests/png/support/cicp-display-p3.pngbin0 -> 143 bytes
-rw-r--r--testing/web-platform/tests/png/support/exif-orientation-bottom-right.pngbin0 -> 329 bytes
-rw-r--r--testing/web-platform/tests/png/support/trns-high-bits-set.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/png/trns-chunk.html37
99 files changed, 2834 insertions, 0 deletions
diff --git a/testing/web-platform/tests/png/META.yml b/testing/web-platform/tests/png/META.yml
new file mode 100644
index 0000000000..da174ac614
--- /dev/null
+++ b/testing/web-platform/tests/png/META.yml
@@ -0,0 +1,4 @@
+spec: https://www.w3.org/TR/png/
+suggested_reviewers:
+ - programmax
+ - svgeesus
diff --git a/testing/web-platform/tests/png/apng/acTL-plays-one.html b/testing/web-platform/tests/png/apng/acTL-plays-one.html
new file mode 100644
index 0000000000..9012e0e56a
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/acTL-plays-one.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-blue-rectangle-one-ref.html">
+<meta name="assert" content="num_plays indicates the number of times that this animation should play. If nonzero, the animation should come to rest on the final frame at the end of the last play.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 3000);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then stays blue forever</p>
+ <div class="test"><img src="support/031.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/acTL-plays-two.html b/testing/web-platform/tests/png/apng/acTL-plays-two.html
new file mode 100644
index 0000000000..147b57957e
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/acTL-plays-two.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-blue-rectangle-ref.html">
+<meta name="assert" content="num_plays indicates the number of times that this animation should play. If nonzero, the animation should come to rest on the final frame at the end of the last play.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 5000);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then
+ blue for one second, then yellow for one second, then blue forever.</p>
+ <div class="test"><img src="support/032.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-blue-rect-checkerboard-ref.html b/testing/web-platform/tests/png/apng/apng-blue-rect-checkerboard-ref.html
new file mode 100644
index 0000000000..3058aa633f
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-blue-rect-checkerboard-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops and regions</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see solid blue rectangle containing a smaller region with a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/blue-with-hole.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/apng-blue-rectangle-one-ref.html b/testing/web-platform/tests/png/apng/apng-blue-rectangle-one-ref.html
new file mode 100644
index 0000000000..f749fc30ea
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-blue-rectangle-one-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then stays blue forever</p>
+ <div class="test"><img src="support/blue.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-blue-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-blue-rectangle-ref.html
new file mode 100644
index 0000000000..51bae3e107
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-blue-rectangle-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then
+ blue for one second, then yellow for one second, then blue forever.</p>
+ <div class="test"><img src="support/blue.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-checkerboard-ref.html b/testing/web-platform/tests/png/apng/apng-checkerboard-ref.html
new file mode 100644
index 0000000000..660a845bba
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-checkerboard-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/apng-darkblue-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-darkblue-rectangle-ref.html
new file mode 100644
index 0000000000..dc781397a8
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-darkblue-rectangle-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a dark blue rectangle, and no red.</p>
+ <div class="test"><img src="support/darkblue.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-graywhite-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-graywhite-rectangle-ref.html
new file mode 100644
index 0000000000..49dfaa37b4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-graywhite-rectangle-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 8bit grayscale</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<body>
+ <p>Test passes if you see a gray rectangle, with a white rectangle in the middle, and no red.</p>
+ <div class="test"><img src="support/gray-white.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-lime-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-lime-rectangle-ref.html
new file mode 100644
index 0000000000..6cc29d40d4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-lime-rectangle-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/lime.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-solidgray-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-solidgray-rectangle-ref.html
new file mode 100644
index 0000000000..edc4230287
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-solidgray-rectangle-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. blended 8bit grayscale with alpha</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<body>
+ <p>Test passes if you see a solid gray rectangle, and no red.</p>
+ <div class="test"><img src="support/solid-gray.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/apng-solidlime-rectangle-ref.html b/testing/web-platform/tests/png/apng/apng-solidlime-rectangle-ref.html
new file mode 100644
index 0000000000..26326caebe
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/apng-solidlime-rectangle-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 1-bit palette</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<body>
+ <p>Test passes if you see a solid lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/lime.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fDAT-inherits-cICP.html b/testing/web-platform/tests/png/apng/fDAT-inherits-cICP.html
new file mode 100644
index 0000000000..14f0e501e7
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fDAT-inherits-cICP.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, fdAT inherits colorspace from cICP</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#structure">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="help" href="https://www.w3.org/TR/png-3/#cICP-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="Each frame inherits every property specified by any critical or ancillary chunks before the first IDAT chunk in the file">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <!-- sRGB lime = color(display-p3 0.4584 0.9853 0.2983) -->
+ <div class="test"><img src="support/062.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fcTL-acTL-ordering.html b/testing/web-platform/tests/png/apng/fcTL-acTL-ordering.html
new file mode 100644
index 0000000000..9d9856d985
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-acTL-ordering.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="acTL must be before PLTE and IDAT. One fcTL may occur before IDAT; all others shall be after IDAT">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2000);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/024.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-blend-over-repeatedly.html b/testing/web-platform/tests/png/apng/fcTL-blend-over-repeatedly.html
new file mode 100644
index 0000000000..cb42a037a9
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-blend-over-repeatedly.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="If blend_op is APNG_BLEND_OP_OVER the frame should be composited onto the output buffer based on its alpha, using a simple OVER operation as described in Alpha Channel Processing.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2500);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/021.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-blend-over-solid.html b/testing/web-platform/tests/png/apng/fcTL-blend-over-solid.html
new file mode 100644
index 0000000000..45d7917376
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-blend-over-solid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="If blend_op is APNG_BLEND_OP_OVER the frame should be composited onto the output buffer based on its alpha, using a simple OVER operation as described in Alpha Channel Processing.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2000);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/020.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-blend-source-nearly-transparent.html b/testing/web-platform/tests/png/apng/fcTL-blend-source-nearly-transparent.html
new file mode 100644
index 0000000000..98205ca69b
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-blend-source-nearly-transparent.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="nearly-transparent-ref.html">
+<meta name="assert" content="If blend_op is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/019.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-blend-source-solid.html b/testing/web-platform/tests/png/apng/fcTL-blend-source-solid.html
new file mode 100644
index 0000000000..c00c478d40
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-blend-source-solid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="If blend_op is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/017.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-blend-source-transparent.html b/testing/web-platform/tests/png/apng/fcTL-blend-source-transparent.html
new file mode 100644
index 0000000000..1eab83d80d
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-blend-source-transparent.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-checkerboard-ref.html">
+<meta name="assert" content="If blend_op is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/018.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-background-final.html b/testing/web-platform/tests/png/apng/fcTL-dispose-background-final.html
new file mode 100644
index 0000000000..d56010eb3d
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-background-final.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, "1200");
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/009.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-background.html b/testing/web-platform/tests/png/apng/fcTL-dispose-background.html
new file mode 100644
index 0000000000..a68ed42b98
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-background.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="match" href="apng-checkerboard-ref.html">
+<meta name="assert" content="the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/008.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-before-region-background.html b/testing/web-platform/tests/png/apng/fcTL-dispose-before-region-background.html
new file mode 100644
index 0000000000..09570513cf
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-before-region-background.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops and regions</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-checkerboard-ref.html">
+<meta name="assert" content="The frame must be rendered within the region defined by x_offset, y_offset, width, and height.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/014.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-background.html b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-background.html
new file mode 100644
index 0000000000..5f61da232d
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-background.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops and regions</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-blue-rect-checkerboard-ref.html">
+<meta name="assert" content="The frame must be rendered within the region defined by x_offset, y_offset, width, and height. The frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see solid blue rectangle containing a smaller region with a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/015.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-none.html b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-none.html
new file mode 100644
index 0000000000..d0bd937e87
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-none.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops and regions</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="The frame must be rendered within the region defined by x_offset, y_offset, width, and height. ">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/013.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-previous.html b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-previous.html
new file mode 100644
index 0000000000..0d15b3c664
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-in-region-previous.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/016.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-none.html b/testing/web-platform/tests/png/apng/fcTL-dispose-none.html
new file mode 100644
index 0000000000..f41f17a7c2
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-none.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="no disposal is done on this frame before rendering the next; the contents of the output buffer are left as is.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/007.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-previous-final.html b/testing/web-platform/tests/png/apng/fcTL-dispose-previous-final.html
new file mode 100644
index 0000000000..1862fcfad4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-previous-final.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/011.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-previous-first.html b/testing/web-platform/tests/png/apng/fcTL-dispose-previous-first.html
new file mode 100644
index 0000000000..c3a3ca9ddf
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-previous-first.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-checkerboard-ref.html">
+<meta name="assert" content="If the first fcTL chunk uses a dispose_op of APNG_DISPOSE_OP_PREVIOUS it should be treated as APNG_DISPOSE_OP_BACKGROUND.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1200);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/012.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fcTL-dispose-previous.html b/testing/web-platform/tests/png/apng/fcTL-dispose-previous.html
new file mode 100644
index 0000000000..cf9c408d8e
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fcTL-dispose-previous.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, dispose ops</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 1300);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/010.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/fdAT-16bit.html b/testing/web-platform/tests/png/apng/fdAT-16bit.html
new file mode 100644
index 0000000000..cc59528642
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-16bit.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-darkblue-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a dark blue rectangle, and no red.</p>
+ <div class="test"><img src="support/033.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE-tRNS.html b/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE-tRNS.html
new file mode 100644
index 0000000000..da10d16f6a
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE-tRNS.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 1-bit palette and transparency</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-darkblue-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a dark blue rectangle, and no red.</p>
+ <div class="test"><img src="support/038.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE.html b/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE.html
new file mode 100644
index 0000000000..6b15b198fb
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-1bit-PLTE.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 1-bit palette</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-solidlime-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a solid lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/036.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-2bit-PLTE-tRNS.html b/testing/web-platform/tests/png/apng/fdAT-2bit-PLTE-tRNS.html
new file mode 100644
index 0000000000..5ab6f8e0d6
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-2bit-PLTE-tRNS.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 2-bit palette and transparency</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-solidlime-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a solid lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/037.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-8bit-gray-alpha.html b/testing/web-platform/tests/png/apng/fdAT-8bit-gray-alpha.html
new file mode 100644
index 0000000000..1719ebd1b5
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-8bit-gray-alpha.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. blended 8bit grayscale with alpha</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-solidgray-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a solid gray rectangle, and no red.</p>
+ <div class="test"><img src="support/035.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-8bit-gray.html b/testing/web-platform/tests/png/apng/fdAT-8bit-gray.html
new file mode 100644
index 0000000000..969a8867a8
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-8bit-gray.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, bit depth. 8bit grayscale</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-graywhite-rectangle-ref.html">
+<meta name="assert" content="It utilizes the same bit depth, colour type, compression method, filter method, interlace method, and palette (if any) as the static image.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a gray rectangle, with a white rectangle in the middle, and no red.</p>
+ <div class="test"><img src="support/034.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-split-basic.html b/testing/web-platform/tests/png/apng/fdAT-split-basic.html
new file mode 100644
index 0000000000..1c718f0ce4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-split-basic.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, split fdAT</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="The compressed datastream is then the concatenation of the contents of the data fields of all the fdAT chunks within a frame. ">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2000);
+</script>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/005.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/fdAT-split-zero-length.html b/testing/web-platform/tests/png/apng/fdAT-split-zero-length.html
new file mode 100644
index 0000000000..68ddec482c
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/fdAT-split-zero-length.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, split fdAT with zero-length chunk</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fdAT-chunk">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="The compressed datastream is then the concatenation of the contents of the data fields of all the fdAT chunks within a frame. ">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2000);
+</script>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/006.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/first-frame-IDAT.html b/testing/web-platform/tests/png/apng/first-frame-IDAT.html
new file mode 100644
index 0000000000..8231f66da7
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/first-frame-IDAT.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#structure">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="The static image may be included as the first frame of the animation by the presence of a single fcTL chunk before IDAT.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2000);
+</script>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/001.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/first-frame-not-IDAT.html b/testing/web-platform/tests/png/apng/first-frame-not-IDAT.html
new file mode 100644
index 0000000000..8abe46d339
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/first-frame-not-IDAT.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG</title>
+<link rel="author" title="Philip Taylor" href="mailto:excors@gmail.com">
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#structure">
+<link rel="match" href="apng-lime-rectangle-ref.html">
+<meta name="assert" content="Otherwise, the static image is not part of the animation.">
+<script>
+ const el = document.querySelector(".reftest-wait");
+ setTimeout(() => {
+ el.classList.remove('reftest-wait');
+ }, 2100);
+</script>
+<body>
+ <p>Test passes if you see a lime green rectangle, and no red.</p>
+ <div class="test"><img src="support/002.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/acTL-plays-one-manual.html b/testing/web-platform/tests/png/apng/manual/acTL-plays-one-manual.html
new file mode 100644
index 0000000000..66c01e8bc3
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/acTL-plays-one-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="num_plays indicates the number of times that this animation should play. If nonzero, the animation should come to rest on the final frame at the end of the last play.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then stays blue forever</p>
+ <div class="test"><img src="../support/031.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/acTL-plays-two-manual.html b/testing/web-platform/tests/png/apng/manual/acTL-plays-two-manual.html
new file mode 100644
index 0000000000..c7d36da3b3
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/acTL-plays-two-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="num_plays indicates the number of times that this animation should play. If nonzero, the animation should come to rest on the final frame at the end of the last play.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then
+ blue for one second, then yellow for one second, then blue forever.</p>
+ <div class="test"><img src="../support/032.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/acTL-plays-zero-manual.html b/testing/web-platform/tests/png/apng/manual/acTL-plays-zero-manual.html
new file mode 100644
index 0000000000..e0e0c95686
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/acTL-plays-zero-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, plays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="num_plays indicates the number of times that this animation should play; if it is 0, the animation should play indefinitely.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes yellow for one second, then blue for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/030.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/fcTL-delay-16bit-manual.html b/testing/web-platform/tests/png/apng/manual/fcTL-delay-16bit-manual.html
new file mode 100644
index 0000000000..8aaefe729e
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/fcTL-delay-16bit-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, delays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="delay_num and delay_den define the numerator and denominator of the delay fraction; indicating the time to display the current frame, in seconds.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes blue for half a second, then yellow for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/027.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/fcTL-delay-basic-manual.html b/testing/web-platform/tests/png/apng/manual/fcTL-delay-basic-manual.html
new file mode 100644
index 0000000000..96ca2eb6e7
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/fcTL-delay-basic-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, delays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="delay_num and delay_den define the numerator and denominator of the delay fraction; indicating the time to display the current frame, in seconds.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes blue for half a second, then yellow for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/025.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/fcTL-delay-rounding-manual.html b/testing/web-platform/tests/png/apng/manual/fcTL-delay-rounding-manual.html
new file mode 100644
index 0000000000..e5e925079b
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/fcTL-delay-rounding-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, delays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="delay_num and delay_den define the numerator and denominator of the delay fraction; indicating the time to display the current frame, in seconds.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes blue for half a second, then yellow for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/026.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-denom-manual.html b/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-denom-manual.html
new file mode 100644
index 0000000000..eeef22d3da
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-denom-manual.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, delays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="If the denominator is 0, it is to be treated as if it were 100 (that is, delay_num then specifies 1/100ths of a second).">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if this flashes blue for half a second, then yellow for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/028.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-num-manual.html b/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-num-manual.html
new file mode 100644
index 0000000000..561d01e4db
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/manual/fcTL-delay-zero-num-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, delays</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<link rel="help" href="https://www.w3.org/TR/png-3/#apng-frame-based-animation">
+<link rel="help" href="https://www.w3.org/TR/png-3/#fcTL-chunk">
+<meta name="assert" content="If the the value of the numerator is 0 the decoder should render the next frame as quickly as possible, though viewers may impose a reasonable lower bound.">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p><i>There may be some brief cyan and magenta flashes; ignore these.</i></p>
+ <p>Test passes if this flashes blue for half a second, then yellow for one second, then repeats forever. </p>
+ <div class="test"><img src="../support/029.png" alt=""></div>
+</body>
diff --git a/testing/web-platform/tests/png/apng/nearly-transparent-ref.html b/testing/web-platform/tests/png/apng/nearly-transparent-ref.html
new file mode 100644
index 0000000000..6cfc7757a8
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/nearly-transparent-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>PNG Third Edition: animated PNG, blend ops</title>
+<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
+<style>
+ .test {
+ width: 128px;
+ height: 64px;
+ background-color: white;
+ background-image:
+ linear-gradient(45deg, #ccc 25%, transparent 25%),
+ linear-gradient(-45deg, #ccc 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #ccc 75%),
+ linear-gradient(-45deg, transparent 75%, #ccc 75%);
+ background-size: 16px 16px;
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
+ }
+</style>
+<body>
+ <p>Test passes if you see a grey checkerboard, and no red.</p>
+ <div class="test"><img src="support/nearly.png" alt=""></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/resources/README.md b/testing/web-platform/tests/png/apng/resources/README.md
new file mode 100644
index 0000000000..ecd61795b1
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/resources/README.md
@@ -0,0 +1,14 @@
+# Regenerating APNG Test Images
+
+## Test images
+
+Most of the APNG tests are a port to WPT of an [earlier testsuite by Philip Taylor](https://philip.html5.org/tests/apng/tests.html). The test images were autogenerated, and this directory contains what is needed to regenerate them:
+
+- ['source.html'](./source.html) which contains a human-readable description of each test file
+- ['generate.pl'](./generate.pl) which uses [Cairo](https://www.cairographics.org/) to create the test images
+
+If this script is used to create additional images, not part of the original test suite, be aware that the generated files are automatically named as sequentially-numbered `nnn.png` so add any new ones _at the end_ to avoid changing the name of existing files.
+
+## Reference images
+
+The reference images were created by decompiling the APNG with [apngasm](https://github.com/apngasm/apngasm) into a series of static PNG representing the displayed state of each frame. The last one therefore represents the end state of the animation. Again this tool produces numbered files like `nn.png` so these were renamed in a more meaningful way (such as `darkblue.png`) to create the reference images.
diff --git a/testing/web-platform/tests/png/apng/resources/generate.pl b/testing/web-platform/tests/png/apng/resources/generate.pl
new file mode 100644
index 0000000000..631356fb7e
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/resources/generate.pl
@@ -0,0 +1,390 @@
+=pod
+Copyright (c) 2007 Philip Taylor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+=cut
+
+use strict;
+use warnings;
+
+use Compress::Zlib();
+use Cairo;
+use PDL qw(float byte);
+
+sub chunk {
+ my ($name, $data) = @_;
+ (pack 'N', length $data) . $name . $data . (pack 'N', Compress::Zlib::crc32($name . $data));
+}
+
+sub IHDR {
+ my ($img) = @_;
+ return chunk 'IHDR', pack 'NNCCCCC',
+ $img->{width}, $img->{height},
+ $img->{bit_depth}, $img->{color_type},
+ $img->{compression_method}, $img->{filter_method}, $img->{interlace_method};
+}
+
+sub gAMA {
+ my ($img) = @_;
+ return chunk 'gAMA', pack 'N', $img->{gamma};
+}
+
+sub sRGB {
+ my ($img) = @_;
+ return chunk 'sRGB', pack 'C', $img->{rendering_intent};
+}
+
+sub PLTE {
+ my ($img) = @_;
+ return chunk 'PLTE', pack 'C*', @{$img->{colours}};
+}
+
+sub tRNS {
+ my ($img) = @_;
+ return chunk 'tRNS', pack 'C*', @{$img->{values}};
+}
+
+sub IDAT {
+ my ($img) = @_;
+ return chunk 'IDAT', xdat_data($img);
+}
+
+sub IDAT_split {
+ my ($img, $blocksize) = @_;
+ my $c = xdat_data($img);
+ my @out;
+ while (length $c) {
+ push @out, chunk 'IDAT', substr $c, 0, $blocksize, '';
+ }
+ return @out;
+}
+
+sub IEND {
+ my ($img) = @_;
+ return chunk 'IEND', '';
+}
+
+sub acTL {
+ my ($img) = @_;
+ return chunk 'acTL', pack 'NN', $img->{num_frames}, $img->{num_plays};
+}
+
+sub fcTL {
+ my ($img) = @_;
+ return chunk 'fcTL', pack 'NNNNNnnCC',
+ $img->{sequence_number},
+ $img->{width}, $img->{height},
+ $img->{x_offset}, $img->{y_offset},
+ $img->{delay_num}, $img->{delay_den},
+ $img->{dispose_op}, $img->{blend_op};
+}
+
+sub fdAT {
+ my ($img) = @_;
+ return chunk 'fdAT', (pack 'N', $img->{sequence_number}) . xdat_data($img);
+}
+
+sub xdat_data {
+ my ($img) = @_;
+ return compress(filter($img->{image_data}, $img->{width}, $img->{height}, $img->{depth}));
+}
+
+use constant DISPOSE_NONE => 0;
+use constant DISPOSE_BACKGROUND => 1;
+use constant DISPOSE_PREVIOUS => 2;
+use constant BLEND_SOURCE => 0;
+use constant BLEND_OVER => 1;
+
+sub filter {
+ my ($imagedata, $width, $height, $depth) = @_;
+ my $out = '';
+ for my $scanline (0..$height-1) {
+ $out .= pack 'C', 0;
+ $out .= substr($imagedata, $scanline*$width*$depth/8, $width*$depth/8);
+ }
+ return $out;
+}
+
+sub compress {
+ my ($filtered) = @_;
+ return Compress::Zlib::compress($filtered);
+}
+
+
+sub fix_bitmap {
+ my ($d) = @_;
+ # Flip BGRA->RGBA, and undo premultiplication
+
+ my $pdl = float unpack 'C*', $d;
+ my $pdl2 = byte $pdl;
+ my $a = 255 / $pdl->mslice([3, -1, 4]);
+ $pdl2->mslice([0, -1, 4]) .= $pdl->mslice([2, -1, 4])*$a;
+ $pdl2->mslice([1, -1, 4]) .= $pdl->mslice([1, -1, 4])*$a;
+ $pdl2->mslice([2, -1, 4]) .= $pdl->mslice([0, -1, 4])*$a;
+ return ${(byte $pdl2)->get_dataref};
+=pod
+ my @d = unpack 'C*', $d;
+ my $a;
+ for (map $_*4, 0..$#d/4) {
+ if ($a = $d[$_+3]) {
+ $a = 255 / $a;
+ @d[$_, $_+1, $_+2] = ($d[$_+2]*$a, $d[$_+1]*$a, $d[$_]*$a);
+ } # else alpha=0 hence r=g=b=0, so nothing to do
+ }
+ return pack 'C*', @d;
+=cut
+}
+
+sub create_surface {
+ my ($w, $h, $type, @data) = @_;
+ my $surface = Cairo::ImageSurface->create('argb32', $w, $h);
+ my $cr = Cairo::Context->create($surface);
+
+ if ($type eq 'red') {
+ ($type, @data) = ('solid', 1, 0, 0, 1);
+ } elsif ($type eq 'green') {
+ ($type, @data) = ('solid', 0, 1, 0, 1);
+ } elsif ($type eq 'blue') {
+ ($type, @data) = ('solid', 0, 0, 1, 1);
+ } elsif ($type eq 'cyan') {
+ ($type, @data) = ('solid', 0, 1, 1, 1);
+ } elsif ($type eq 'magenta') {
+ ($type, @data) = ('solid', 1, 0, 1, 1);
+ } elsif ($type eq 'yellow') {
+ ($type, @data) = ('solid', 1, 1, 0, 1);
+ } elsif ($type eq 'transparent') {
+ ($type, @data) = ('solid', 0, 0, 0, 0);
+ }
+
+ if ($type eq 'solid') {
+ $cr->rectangle(0, 0, $w, $h);
+ $cr->set_source_rgba(@data);
+ $cr->fill;
+ } elsif ($type eq 'doublerect') {
+ $cr->rectangle(0, 0, $w, $h);
+ $cr->set_source_rgba(@data[0..3]);
+ $cr->fill;
+ $cr->rectangle(int($w/4), int($h/4), int($w/2), int($h/2));
+ $cr->set_source_rgba(@data[4..7]);
+ $cr->fill;
+ } else {
+ die "Invalid create_surface type '$type'";
+ }
+ return { width => $w, height => $h, depth => 32, data => fix_bitmap($surface->get_data) };
+}
+
+sub create_raw_surface {
+ my ($w, $h, $d, $data) = @_;
+ return { width => $w, height => $h, depth => $d, data => $data };
+}
+
+sub find_errors {
+ my (@img) = @_;
+ my @chunks;
+ {
+ my @img2 = @img;
+ push @chunks, [ splice @img2, 0, 2 ] while @img2;
+ }
+
+ my $chunknames = join '', map "<$_->[0]>", @chunks;
+
+ my @errors;
+
+ my $has_actl = ($chunknames =~ /<acTL>/);
+
+ if ($has_actl) {
+ # acTL must be before IDAT
+ if ($chunknames =~ /<IDAT>.*<acTL>/) {
+ push @errors, "acTL after IDAT";
+ }
+
+ # Must have only one acTL (TODO: in spec?)
+ if ($chunknames =~ /<acTL>.*<acTL>/) {
+ push @errors, "More than one acTL";
+ }
+
+ my $num_frames = {@img}->{acTL}[0];
+
+ # num_frames > 0
+ if ($num_frames <= 0) {
+ push @errors, "num_frames <= 0";
+ }
+
+ # num_frames = count(fcTL)
+ my $num_fctls = grep $_->[0] eq 'fcTL', @chunks;
+ if ($num_frames != $num_fctls) {
+ push @errors, "num_frames ($num_frames) != number of fcTLs ($num_fctls)";
+ }
+ }
+
+ # Check sequence numbers (start from 0, no duplicates or gaps)
+ my @seqnos;
+ for (grep { $_->[0] =~ /^(fcTL|fdAT|fdAT_split)$/ } @chunks) {
+ push @seqnos, $_->[1][0];
+ }
+ if (@seqnos and (join ',', @seqnos) ne (join ',', 0..$#seqnos)) {
+ push @errors, "Incorrect sequence numbers";
+ }
+
+ return @errors;
+}
+
+sub create_image {
+ my ($filename, @img) = @_;
+ my @chunks;
+ while (@img) {
+ my ($chunk, $data) = splice @img, 0, 2;
+ if ($chunk eq 'IHDR') {
+ push @chunks, IHDR {
+ width => $data->[0],
+ height => $data->[1],
+ bit_depth => defined $data->[2] ? $data->[2] : 8,
+ color_type => defined $data->[3] ? $data->[3] : 6,
+ compression_method => 0,
+ filter_method => 0,
+ interlace_method => 0,
+ };
+ } elsif ($chunk eq 'IEND') {
+ push @chunks, IEND { }
+ } elsif ($chunk eq 'gAMA') {
+ push @chunks, gAMA {
+ gamma => int(100_000*$data->[0]),
+ };
+ } elsif ($chunk eq 'sRGB') {
+ push @chunks, sRGB {
+ rendering_intent => $data->[0],
+ };
+ } elsif ($chunk eq 'PLTE') {
+ push @chunks, PLTE {
+ colours => $data,
+ };
+ } elsif ($chunk eq 'tRNS') {
+ push @chunks, tRNS {
+ values => $data,
+ };
+ } elsif ($chunk eq 'acTL') {
+ push @chunks, acTL {
+ num_frames => $data->[0],
+ num_plays => $data->[1],
+ };
+ } elsif ($chunk eq 'fcTL') {
+ push @chunks, fcTL {
+ sequence_number => $data->[0],
+ width => $data->[1],
+ height => $data->[2],
+ x_offset => $data->[3],
+ y_offset => $data->[4],
+ delay_num => $data->[5],
+ delay_den => $data->[6],
+ dispose_op => $data->[7],
+ blend_op => $data->[8],
+ };
+ } elsif ($chunk eq 'IDAT') {
+ push @chunks, IDAT {
+ depth => $data->[0]{depth},
+ width => $data->[0]{width},
+ height => $data->[0]{height},
+ image_data => $data->[0]{data},
+ }
+ } elsif ($chunk eq 'IDAT_split') {
+ my $c = xdat_data {
+ depth => $data->[2]{depth},
+ width => $data->[2]{width},
+ height => $data->[2]{height},
+ image_data => $data->[2]{data},
+ };
+ if ($data->[1] == -1) {
+ $c = substr $c, $data->[0];
+ } else {
+ $c = substr $c, $data->[0], $data->[1] - $data->[0];
+ }
+ push @chunks, chunk 'IDAT', $c;
+ } elsif ($chunk eq 'fdAT') {
+ push @chunks, fdAT {
+ sequence_number => $data->[0],
+ depth => $data->[1]{depth},
+ width => $data->[1]{width},
+ height => $data->[1]{height},
+ image_data => $data->[1]{data},
+ }
+ } elsif ($chunk eq 'fdAT_split') {
+ my $c = xdat_data {
+ depth => $data->[3]{depth},
+ width => $data->[3]{width},
+ height => $data->[3]{height},
+ image_data => $data->[3]{data},
+ };
+ if ($data->[2] == -1) {
+ $c = substr $c, $data->[1];
+ } else {
+ $c = substr $c, $data->[1], $data->[2] - $data->[1];
+ }
+ push @chunks, chunk 'fdAT', (pack 'N', $data->[0]) . $c;
+ } else {
+ die "Invalid create_image chunk '$chunk'";
+ }
+ }
+ open my $fh, '>', "images/$filename.png" or die $!;
+ binmode $fh;
+ print $fh "\211PNG\r\n\032\n", @chunks;
+}
+
+use constant W => 128;
+use constant H => 64;
+
+sub escape_html {
+ my ($t) = @_;
+ $t =~ s/&/&amp;/g;
+ $t =~ s/</&lt;/g;
+ return $t;
+}
+
+my $img_id = '000';
+sub handle_html_png {
+ my ($code) = @_;
+ my $name = $img_id++;
+ my @img = eval '(' . $code . ')';
+ die $@ if $@;
+ create_image($name, @img);
+ my $data = $code;
+ $data =~ s/^\s*(.*?)\s*$/$1/sg;
+ $data =~ s/([^a-zA-Z0-9])/sprintf('%%%02X', ord $1)/eg;
+ my $errors = (join '; ', map escape_html($_), find_errors(@img)) || 'None';
+ return qq{<p>}
+ #. qq{<object data="$name.png" class="testimage"><strong>Did not load image.</strong></object>} # IE doesn't like this
+ . qq{<img src="$name.png" alt="Did not load image" class="testimage">\n}
+ . qq{<p><a href="data:text/plain,$data">(source)</a>\n}
+ #. qq{<p>Expected errors: $errors\n}
+ ;
+}
+# TODO: regexping HTML is nasty - should use a better input data format instead
+sub handle_html_case {
+ my ($title) = @_;
+ my $id = lc $title;
+ $id =~ s/[^a-z0-9]+/-/g;
+ $id =~ s/^-*(.*?)-*$/$1/g;
+ return qq{<div class="case" id="$id">\n<p><a href="#$id">#</a> $title\n};
+}
+
+open my $in, 'source.html' or die $!;
+my $html = do { local $/; <$in> };
+$html =~ s/<png>(.*?)<\/png>/handle_html_png($1)/seg;
+$html =~ s/<div class="case">\n<p>(.*?)\n/handle_html_case($1)/eg;
+open my $out, '>', 'images/tests.html' or die $!;
+print $out $html; \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/resources/source.html b/testing/web-platform/tests/png/apng/resources/source.html
new file mode 100644
index 0000000000..cca7063cff
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/resources/source.html
@@ -0,0 +1,1014 @@
+<!DOCTYPE HTML>
+<title>APNG tests</title>
+<style>
+html {
+ background-color: white;
+ color: black;
+}
+body {
+ font-family: sans-serif;
+}
+.testimage {
+ border: 1px black solid;
+ background: #ffa;
+}
+blockquote {
+ font-style: italic;
+}
+blockquote[cite]:after {
+ font-style: normal;
+ font-size: x-small;
+ padding-left: 2em;
+ content: "(" attr(cite) ")";
+}
+blockquote[cite="#apng"]:after {
+ content: "(APNG Specification)";
+}
+blockquote[cite="#png"]:after {
+ content: "(PNG Specification)";
+}
+blockquote p {
+ margin: 0;
+}
+div.case {
+ border: 1px #888 solid;
+ padding: 0.3em;
+ margin: 0.3em;
+}
+div.case:target {
+ border: 2px #000 solid;
+}
+div.case > p {
+ margin: 0;
+}
+</style>
+
+<p><em>This page is somewhat incomplete and quite possibly incorrect &ndash; use with caution. <img src="underconstruction.png" style="vertical-align: middle" alt=""></em>
+
+<h1>APNG tests</h1>
+
+<p>For all these tests, wait at least a second after all the images have downloaded, before checking that the rendered output is correct.
+
+<p>Test output conventions:
+A solid green 128&times;64 rectangle means success.
+Any red means failure.
+Anything else means you need to read the instructions.
+"Transparent" is indicated by a <span style="background: #ffa">light yellow background</span>.
+
+<p>Sections of the relevant specifications are sometimes quoted when they clarify the expected behaviour.
+
+<p>Please don't link directly to the images in this page, since they may get renamed and will break any such links.
+
+<p>You can download <a href="generate.pl">the script</a> and <a href="source.html">the source data</a> for this page.
+
+
+<h2>Valid images</h2>
+
+
+<h3>Basic cases</h3>
+
+<div class="case">
+<p>Trivial static image.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+IDAT => [create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Trivial animated image - one frame; using default image.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Trivial animated image - one frame; ignoring default image.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>IDAT, fdAT splitting</h3>
+<blockquote cite="#png"><p>There may be multiple IDAT chunks; if so, they shall appear consecutively with no other intervening chunks. The compressed datastream is then the concatenation of the contents of the data fields of all the IDAT chunks.</blockquote>
+<blockquote cite="#apng"><p>The compressed datastream is then the concatenation of the contents of the data fields of all the `fdAT` chunks within a frame.</blockquote>
+
+<div class="case">
+<p>Basic split IDAT.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+IDAT_split => [0,32, create_surface(W, H, 'green')],
+IDAT_split => [32,-1, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Split IDAT with zero-length chunk.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+IDAT_split => [0,32, create_surface(W, H, 'green')],
+IDAT_split => [32,32, create_surface(W, H, 'green')],
+IDAT_split => [32,-1, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Basic split fdAT.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT_split => [1, 0,32, create_surface(W, H, 'green')],
+fdAT_split => [2, 32,-1, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Split fdAT with zero-length chunk.
+<p>This should be solid green.
+<!-- Opera bug 286566 -->
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT_split => [1, 0,32, create_surface(W, H, 'green')],
+fdAT_split => [2, 32,32, create_surface(W, H, 'green')],
+fdAT_split => [3, 32,-1, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Dispose ops</h3>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_NONE - basic.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'green')],
+fcTL => [3, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_BACKGROUND - basic.
+<p>This should be transparent.
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 10, 100, DISPOSE_BACKGROUND, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'red')],
+fcTL => [3, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_BACKGROUND - final frame.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 10, 100, DISPOSE_BACKGROUND, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_PREVIOUS - basic.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'green')],
+fcTL => [2, W, H, 0, 0, 10, 100, DISPOSE_PREVIOUS, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'red')],
+fcTL => [4, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [5, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_PREVIOUS - final frame.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 10, 100, DISPOSE_PREVIOUS, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_PREVIOUS - first frame.
+<p>This should be transparent.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_PREVIOUS, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Dispose ops and regions</h3>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_NONE in region.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'doublerect', 0,1,0,1, 1,0,0,1)],
+fcTL => [1, W/2, H/2, W/4, H/4, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W/2, H/2, 'green')],
+fcTL => [3, 1, 1, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(1, 1, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_BACKGROUND before region.
+<p>This should be transparent.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_BACKGROUND, BLEND_OVER],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, 1, 1, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(1, 1, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_BACKGROUND in region.
+<p>This should be a solid blue rectangle containing a smaller transparent rectangle.
+<!-- Opera bug 286565 -->
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H, 'doublerect', 0,0,1,1, 1,0,0,1)],
+fcTL => [1, W/2, H/2, W/4, H/4, 10, 100, DISPOSE_BACKGROUND, BLEND_OVER],
+fdAT => [2, create_surface(W/2, H/2, 'red')],
+fcTL => [3, 1, 1, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(1, 1, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_DISPOSE_OP_PREVIOUS in region.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [3, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'green')],
+fcTL => [2, W/2, H/2, W/4, H/4, 10, 100, DISPOSE_PREVIOUS, BLEND_OVER],
+fdAT => [3, create_surface(W/2, H/2, 'red')],
+fcTL => [4, 1, 1, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [5, create_surface(1, 1, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Blend ops</h3>
+
+<div class="case">
+<p>APNG_BLEND_OP_SOURCE on solid colour.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_SOURCE],
+fdAT => [3, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_BLEND_OP_SOURCE on transparent colour.
+<p>This should be transparent.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_SOURCE],
+fdAT => [3, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_BLEND_OP_SOURCE on nearly-transparent colour.
+<p>This should be very nearly transparent.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_SOURCE],
+fdAT => [3, create_surface(W, H, 'solid', 0, 1, 0, 0.01)],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_BLEND_OP_OVER on solid and transparent colours.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'green')],
+fcTL => [2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'transparent')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_BLEND_OP_OVER repeatedly with nearly-transparent colours.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+acTL => [128, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'solid', 0, 1, 0, 1)],
+(map {
+ (fcTL => [2+$_*2, W/2, H, 0, 0, 1, 100, DISPOSE_NONE, BLEND_OVER],
+ fdAT => [3+$_*2, create_surface(W/2, H, 'solid', 0, 1, 0, 0.01)])
+} 0..126),
+IEND => [],
+</png>
+</div>
+
+
+<h3>Blending and gamma</h3>
+
+<div class="case">
+<p>APNG_BLEND_OP_OVER
+<p>This should be solid slightly-dark green.
+<png>
+IHDR => [W, H],
+gAMA => [1],
+acTL => [16, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'solid', 0, 1, 0, 1)],
+(map {
+ (fcTL => [2+$_*2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+ fdAT => [3+$_*2, create_surface(W, H, 'solid', 0, 0.9, 0, 0.5)])
+} 0..14),
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>APNG_BLEND_OP_OVER
+<p>This should be solid nearly-black.
+<png>
+IHDR => [W, H],
+gAMA => [1/2200],
+acTL => [16, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+(map {
+ (fcTL => [2+$_*2, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+ fdAT => [3+$_*2, create_surface(W, H, 'solid', 0.9, 0, 0, 0.5)])
+} 0..14),
+IEND => [],
+</png>
+</div>
+
+
+<h3>Chunk ordering</h3>
+
+<div class="case">
+<p>fcTL before acTL.
+<p>This should be solid green.
+<png>
+IHDR => [W, H],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Delays</h3>
+
+<div class="case">
+<p>Basic delays.
+<p>This should flash blue for half a second, then yellow for one second, then repeat.
+<png>
+IHDR => [W, H],
+acTL => [4, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 50, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'blue')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'yellow')],
+fcTL => [4, W, H, 0, 0, 10000, 20000, DISPOSE_NONE, BLEND_OVER],
+fdAT => [5, create_surface(W, H, 'blue')],
+fcTL => [6, W, H, 0, 0, 1, 1, DISPOSE_NONE, BLEND_OVER],
+fdAT => [7, create_surface(W, H, 'yellow')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Rounding of division.
+<p>This should flash blue for half a second, then yellow for one second, then repeat.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 1, 2, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'blue')],
+fcTL => [2, W, H, 0, 0, 1, 1, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'yellow')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>16-bit numerator/denominator.
+<p>This should flash blue for half a second, then yellow for one second, then repeat.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 32767, 65534, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'blue')],
+fcTL => [2, W, H, 0, 0, 65535, 65535, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'yellow')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Zero denominator.
+<blockquote cite="#apng"><p>If the denominator is 0, it is to be treated as if it were 100</blockquote>
+<p>This should flash blue for half a second, then yellow for one second, then repeat.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 50, 0, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'blue')],
+fcTL => [2, W, H, 0, 0, 1000, 1000, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'yellow')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Zero numerator.
+<blockquote cite="#apng"><p>If the the value of the numerator is 0 the decoder should render the next frame as quickly as possible, though viewers may impose a reasonable lower bound.</blockquote>
+<p>This should flash cyan for a short period of time (perhaps zero), then magenta for the same short period of time, then blue for half a second, then yellow for one second, then repeat.
+<png>
+IHDR => [W, H],
+acTL => [4, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 0, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'cyan')],
+fcTL => [2, W, H, 0, 0, 0, 0, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'magenta')],
+fcTL => [4, W, H, 0, 0, 500, 1000, DISPOSE_NONE, BLEND_OVER],
+fdAT => [5, create_surface(W, H, 'blue')],
+fcTL => [6, W, H, 0, 0, 1000, 1000, DISPOSE_NONE, BLEND_OVER],
+fdAT => [7, create_surface(W, H, 'yellow')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>num_plays</h3>
+
+<div class="case">
+<p>num_plays = 0
+<p>This should flash yellow for one second, then blue for one second, then repeat forever.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'yellow')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'blue')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_plays = 1
+<p>When first loaded, this should flash yellow for one second, then stay blue forever.
+<png>
+IHDR => [W, H],
+acTL => [2, 1],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'yellow')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'blue')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_plays = 2
+<p>When first loaded, this should flash yellow for one second, then blue for one second, then yellow for one second, then blue forever.
+<png>
+IHDR => [W, H],
+acTL => [2, 2],
+IDAT => [create_surface(W, H, 'red')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'yellow')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'blue')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Other depths and colour types</h3>
+
+<div class="case">
+<p>16-bit colour.
+<p>This should be dark blue.
+<png>
+IHDR => [W, H, 16, 6],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 64, "\xFF\x00\x00\x00\x00\x00\xFF\xFF" x (W*H))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 64, "\x00\x00\x00\x00\x00\x00\xFF\xFF" x (W*H))],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W, H, 64, "\x00\x00\x00\x00\xFF\xFF\x80\x00" x (W*H))],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>8-bit greyscale.
+<p>This should be a solid grey rectangle containing a solid white rectangle.
+<png>
+IHDR => [W, H, 8, 0],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 8, "\x00\xFF" x (W*H/2))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 8, "\x80" x (W*H))],
+fcTL => [2, W/2, H/2, W/4, H/4, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W/2, H/2, 8, "\xFF" x (W*H/4))],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>8-bit greyscale and alpha, with blending.
+<p>This should be solid grey.
+<png>
+IHDR => [W, H, 8, 4],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 16, "\x00\xFF\xFF\xFF" x (W*H/2))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 16, "\x00\xFF" x (W*H))],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W, H, 16, "\xFF\x80" x (W*H))],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>2-color palette.
+<p>This should be solid green.
+<png>
+IHDR => [W, H, 1, 3],
+PLTE => [255,0,0, 0,255,0],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 1, "\x00" x (W*H/8))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 1, "\x00" x (W*H/8))],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W, H, 1, "\xFF" x (W*H/8))],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>2-bit palette and alpha.
+<p>This should be solid green.
+<png>
+IHDR => [W, H, 2, 3],
+PLTE => [255,0,0, 255,0,0, 0,255,0],
+tRNS => [255, 0, 255],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 2, "\x00" x (W*H/4))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 2, "\xAA" x (W*H/4))],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W, H, 2, "\x55" x (W*H/4))],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>1-bit palette and alpha, with blending.
+<p>This should be solid dark blue.
+<png>
+IHDR => [W, H, 1, 3],
+PLTE => [0,0,0, 0,0,255],
+tRNS => [255, 128],
+acTL => [2, 1],
+IDAT => [create_raw_surface(W, H, 1, "\x00" x (W*H/8))],
+fcTL => [0, W, H, 0, 0, 10, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_raw_surface(W, H, 1, "\x00" x (W*H/8))],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_raw_surface(W, H, 1, "\xFF" x (W*H/8))],
+IEND => [],
+</png>
+</div>
+
+
+<h2>Invalid images</h2>
+
+<blockquote cite="#apng">
+<p>It is strongly recommended that when any error is encountered decoders should discard all subsequent frames, stop the animation, and revert to displaying the default image. A decoder which detects an error before the animation has started should display the default image. An error message may be displayed to the user if appropriate.
+</blockquote>
+<p>(If some decoders accept broken images, it seems quite possible that people will create and distribute broken images, and then the error-handling would have to be reverse-engineered by other implementations; hence all these tests to ensure errors get detected properly.)
+<p>For the following images, the default image (solid green) or an error should be displayed.
+
+
+<h3>Incorrect chunks</h3>
+
+<div class="case">
+<p>Missing acTL.
+<png>
+IHDR => [W, H],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Repeated acTL.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>acTL after IDAT.
+<png>
+IHDR => [W, H],
+IDAT => [create_surface(W, H, 'green')],
+acTL => [1, 0],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Missing fcTL.
+<p><em>Disabled for now, since it crashes Opera 9.5 alpha 1589 (bug 287173).</em>
+<!--
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fdAT => [0, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+-->
+</div>
+
+<div class="case">
+<p>Repeated fcTL.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Missing fdAT.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fcTL => [1, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>num_frames</h3>
+
+<div class="case">
+<p>num_frames = 0; no default image.
+<blockquote cite="#apng"><p>0 is not a valid value.</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [0, 0],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_frames = 0; ignoring default image.
+<blockquote cite="#apng"><p>0 is not a valid value.</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [0, 0],
+IDAT => [create_surface(W, H, 'green')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_frames too low.
+<blockquote cite="#apng"><p>This must equal the number of `fcTL` chunks. ... If this value does not equal the actual number of frames it should be treated as an error.</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_frames too high by 1.
+<blockquote cite="#apng"><p>This must equal the number of `fcTL` chunks. ... If this value does not equal the actual number of frames it should be treated as an error.</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [3, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_frames too high by 2.
+<blockquote cite="#apng"><p>This must equal the number of `fcTL` chunks. ... If this value does not equal the actual number of frames it should be treated as an error.</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [4, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>num_frames outside valid range.
+<blockquote cite="#apng"><p>an "unsigned int" shall be a 32-bit unsigned integer in network byte order limited to the range 0 to (2^31)-1</blockquote>
+<png>
+IHDR => [W, H],
+acTL => [0x80000001, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Sequence numbers</h3>
+
+<div class="case">
+<p>Not starting from 0.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [1, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'red')],
+fcTL => [3, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Gap in sequence.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [4, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Duplicated sequence number.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Duplicated chunk.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [3, create_surface(W, H, 'red')],
+fdAT => [3, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Reordered fdAT chunks.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT_split => [4, 32,-1, create_surface(W, H, 'red')],
+fdAT_split => [3, 0,32, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Reordered sequence numbers.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+fcTL => [2, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT_split => [4, 0,32, create_surface(W, H, 'red')],
+fdAT_split => [3, 32,-1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>Separated fdAT and fcTL sequences.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [0, create_surface(W, H, 'red')],
+fcTL => [1, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+
+<h3>Invalid image-data sizes</h3>
+
+<div class="case">
+<p>Default image's fcTL size not matching IHDR.
+<png>
+IHDR => [W, H],
+acTL => [2, 0],
+fcTL => [0, W, H/2, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+IDAT => [create_surface(W, H/2, 'red')],
+fcTL => [1, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [2, create_surface(W, H, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>fdAT too small.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H/2, 'red')],
+IEND => [],
+</png>
+</div>
+
+<div class="case">
+<p>fdAT too large.
+<png>
+IHDR => [W, H],
+acTL => [1, 0],
+IDAT => [create_surface(W, H, 'green')],
+fcTL => [0, W, H, 0, 0, 100, 100, DISPOSE_NONE, BLEND_OVER],
+fdAT => [1, create_surface(W, H*2, 'red')],
+IEND => [],
+</png>
+</div>
+
+<!-- TODO: invalid fcTL (negative offset, etc) -->
+
+<h2>References</h2>
+<ul>
+<li id="apng"><a href="http://wiki.mozilla.org/index.php?title=APNG_Specification&amp;oldid=64503">APNG Specification 1.0</a>
+<li id="png"><a href="http://www.w3.org/TR/PNG/">PNG Specification (Second Edition)</a>
+</ul> \ No newline at end of file
diff --git a/testing/web-platform/tests/png/apng/support/001.png b/testing/web-platform/tests/png/apng/support/001.png
new file mode 100644
index 0000000000..0cd5bea856
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/001.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/002.png b/testing/web-platform/tests/png/apng/support/002.png
new file mode 100644
index 0000000000..db7581fbdf
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/002.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/005.png b/testing/web-platform/tests/png/apng/support/005.png
new file mode 100644
index 0000000000..2dc58b929a
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/005.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/006.png b/testing/web-platform/tests/png/apng/support/006.png
new file mode 100644
index 0000000000..14a76d9d61
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/006.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/007.png b/testing/web-platform/tests/png/apng/support/007.png
new file mode 100644
index 0000000000..3094c1d23d
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/007.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/008.png b/testing/web-platform/tests/png/apng/support/008.png
new file mode 100644
index 0000000000..b63ebc0b35
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/008.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/009.png b/testing/web-platform/tests/png/apng/support/009.png
new file mode 100644
index 0000000000..77694ff1d1
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/009.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/010.png b/testing/web-platform/tests/png/apng/support/010.png
new file mode 100644
index 0000000000..1c15f132fe
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/010.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/011.png b/testing/web-platform/tests/png/apng/support/011.png
new file mode 100644
index 0000000000..858f6f0382
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/011.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/012.png b/testing/web-platform/tests/png/apng/support/012.png
new file mode 100644
index 0000000000..3f9b3cfae7
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/012.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/013.png b/testing/web-platform/tests/png/apng/support/013.png
new file mode 100644
index 0000000000..4e1dbf77e4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/013.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/014.png b/testing/web-platform/tests/png/apng/support/014.png
new file mode 100644
index 0000000000..427b829a02
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/014.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/015.png b/testing/web-platform/tests/png/apng/support/015.png
new file mode 100644
index 0000000000..05948d44ae
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/015.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/016.png b/testing/web-platform/tests/png/apng/support/016.png
new file mode 100644
index 0000000000..f326afa5c2
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/016.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/017.png b/testing/web-platform/tests/png/apng/support/017.png
new file mode 100644
index 0000000000..d90c54967b
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/017.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/018.png b/testing/web-platform/tests/png/apng/support/018.png
new file mode 100644
index 0000000000..0f290fd7fd
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/018.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/019.png b/testing/web-platform/tests/png/apng/support/019.png
new file mode 100644
index 0000000000..1af30f81f7
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/019.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/020.png b/testing/web-platform/tests/png/apng/support/020.png
new file mode 100644
index 0000000000..3fe0f4ca78
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/020.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/021.png b/testing/web-platform/tests/png/apng/support/021.png
new file mode 100644
index 0000000000..3ee5fe3bf2
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/021.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/024.png b/testing/web-platform/tests/png/apng/support/024.png
new file mode 100644
index 0000000000..d0418ddd75
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/024.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/025.png b/testing/web-platform/tests/png/apng/support/025.png
new file mode 100644
index 0000000000..64cceaae83
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/025.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/026.png b/testing/web-platform/tests/png/apng/support/026.png
new file mode 100644
index 0000000000..3f082665c9
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/026.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/027.png b/testing/web-platform/tests/png/apng/support/027.png
new file mode 100644
index 0000000000..99d53b7181
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/027.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/028.png b/testing/web-platform/tests/png/apng/support/028.png
new file mode 100644
index 0000000000..bad60c767f
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/028.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/029.png b/testing/web-platform/tests/png/apng/support/029.png
new file mode 100644
index 0000000000..a029a959b5
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/029.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/030.png b/testing/web-platform/tests/png/apng/support/030.png
new file mode 100644
index 0000000000..4d76802e4c
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/030.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/031.png b/testing/web-platform/tests/png/apng/support/031.png
new file mode 100644
index 0000000000..fb25394305
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/031.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/032.png b/testing/web-platform/tests/png/apng/support/032.png
new file mode 100644
index 0000000000..b8e06d1736
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/032.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/033.png b/testing/web-platform/tests/png/apng/support/033.png
new file mode 100644
index 0000000000..1210e37379
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/033.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/034.png b/testing/web-platform/tests/png/apng/support/034.png
new file mode 100644
index 0000000000..29ed7d1ea1
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/034.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/035.png b/testing/web-platform/tests/png/apng/support/035.png
new file mode 100644
index 0000000000..f9307f6350
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/035.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/036.png b/testing/web-platform/tests/png/apng/support/036.png
new file mode 100644
index 0000000000..11ccfb6cba
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/036.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/037.png b/testing/web-platform/tests/png/apng/support/037.png
new file mode 100644
index 0000000000..f3c4c9f9e6
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/037.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/038.png b/testing/web-platform/tests/png/apng/support/038.png
new file mode 100644
index 0000000000..e95425ac19
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/038.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/062.png b/testing/web-platform/tests/png/apng/support/062.png
new file mode 100644
index 0000000000..e50902adb9
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/062.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/blue-with-hole.png b/testing/web-platform/tests/png/apng/support/blue-with-hole.png
new file mode 100644
index 0000000000..175c5ddfd8
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/blue-with-hole.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/blue.png b/testing/web-platform/tests/png/apng/support/blue.png
new file mode 100644
index 0000000000..fe2a8a9bd5
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/blue.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/darkblue.png b/testing/web-platform/tests/png/apng/support/darkblue.png
new file mode 100644
index 0000000000..dabaae2e20
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/darkblue.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/gray-white.png b/testing/web-platform/tests/png/apng/support/gray-white.png
new file mode 100644
index 0000000000..7f3cb44d05
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/gray-white.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/lime.png b/testing/web-platform/tests/png/apng/support/lime.png
new file mode 100644
index 0000000000..9bd3632811
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/lime.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/nearly.png b/testing/web-platform/tests/png/apng/support/nearly.png
new file mode 100644
index 0000000000..b8e43f93f4
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/nearly.png
Binary files differ
diff --git a/testing/web-platform/tests/png/apng/support/solid-gray.png b/testing/web-platform/tests/png/apng/support/solid-gray.png
new file mode 100644
index 0000000000..8d29b4db62
--- /dev/null
+++ b/testing/web-platform/tests/png/apng/support/solid-gray.png
Binary files differ
diff --git a/testing/web-platform/tests/png/cicp-chunk.html b/testing/web-platform/tests/png/cicp-chunk.html
new file mode 100644
index 0000000000..8add5d602e
--- /dev/null
+++ b/testing/web-platform/tests/png/cicp-chunk.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<title>PNG test: cICP chunk</title>
+<link rel="help" href="https://w3c.github.io/PNG-spec/#cICP-chunk">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<body>
+
+<h1>cICP chunk</h1>
+<p class="desc">test pixel values of a display-p3 PNG</p>
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test pixel values of a display-p3 PNG");
+const img = new Image();
+img.onload = () => {
+ _addTest(function(canvas, ctx) {
+ ctx.drawImage(img, 0, 0);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+
+ // The pixel values stored are (51 red, 102 green, 153 blue).
+ // These numbers are chosen because 0.2 * 255 = 51.
+ // The image has a cICP chunk indicating the Display P3 color space.
+ // This results in decoded pixel values of (27 red, 104 green, 157 blue).
+ const pixel_expected = [27, 104, 157, 255];
+ const epsilon = 2;
+
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], epsilon);
+ assert_approx_equals(pixel[1], pixel_expected[1], epsilon);
+ assert_approx_equals(pixel[2], pixel_expected[2], epsilon);
+ assert_approx_equals(pixel[3], pixel_expected[3], epsilon);
+ }, {colorSpace: "display-p3"});
+};
+img.src = "support/cicp-display-p3.png";
+</script>
diff --git a/testing/web-platform/tests/png/exif-chunk.html b/testing/web-platform/tests/png/exif-chunk.html
new file mode 100644
index 0000000000..1cb0e2755e
--- /dev/null
+++ b/testing/web-platform/tests/png/exif-chunk.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>PNG test: eXIf chunk</title>
+<link rel="help" href="https://w3c.github.io/PNG-spec/#eXIf">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<body>
+
+<h1>eXIf chunk</h1>
+<p class="desc">test pixel values of a rotated PNG</p>
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test pixel values of a rotated PNG");
+const img = new Image();
+img.onload = () => {
+ _addTest(function(canvas, ctx) {
+ ctx.drawImage(img, 0, 0);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1).data;
+
+ // The image data stores a 100x100 red block above a 100x100 green block.
+ // By rotating the image, we can put the green block on top.
+ const pixel_expected = [0, 255, 0, 255];
+ const epsilon = 2;
+
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], epsilon);
+ assert_approx_equals(pixel[1], pixel_expected[1], epsilon);
+ assert_approx_equals(pixel[2], pixel_expected[2], epsilon);
+ assert_approx_equals(pixel[3], pixel_expected[3], epsilon);
+ });
+};
+img.src = "support/exif-orientation-bottom-right.png";
+</script>
diff --git a/testing/web-platform/tests/png/support/cicp-display-p3.png b/testing/web-platform/tests/png/support/cicp-display-p3.png
new file mode 100644
index 0000000000..8fa0ce2123
--- /dev/null
+++ b/testing/web-platform/tests/png/support/cicp-display-p3.png
Binary files differ
diff --git a/testing/web-platform/tests/png/support/exif-orientation-bottom-right.png b/testing/web-platform/tests/png/support/exif-orientation-bottom-right.png
new file mode 100644
index 0000000000..261d5f4c12
--- /dev/null
+++ b/testing/web-platform/tests/png/support/exif-orientation-bottom-right.png
Binary files differ
diff --git a/testing/web-platform/tests/png/support/trns-high-bits-set.png b/testing/web-platform/tests/png/support/trns-high-bits-set.png
new file mode 100644
index 0000000000..4e309a89a8
--- /dev/null
+++ b/testing/web-platform/tests/png/support/trns-high-bits-set.png
Binary files differ
diff --git a/testing/web-platform/tests/png/trns-chunk.html b/testing/web-platform/tests/png/trns-chunk.html
new file mode 100644
index 0000000000..3a24753382
--- /dev/null
+++ b/testing/web-platform/tests/png/trns-chunk.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>PNG test: tRNS chunk</title>
+<link rel="help" href="https://w3c.github.io/PNG-spec/#11tRNS">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<body>
+
+<h1>tRNS chunk handling</h1>
+<p class="desc">test ignored high bits on lower bit depth tRNS</p>
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test ignored high bits on lower bit depth tRNS");
+const img = new Image();
+img.onload = () => {
+ _addTest(function(canvas, ctx) {
+ ctx.drawImage(img, 0, 0);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+
+ const pixel_expected = [255, 0, 0, 0];
+ const epsilon = 2;
+
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ // Ignore the color channel comparisons.
+ // The image itself stores 255 red, 0 green, 0 blue.
+ // But there may not be a requirement that this be preserved
+ // while decoding or through canvas processing.
+ assert_approx_equals(pixel[3], pixel_expected[3], epsilon);
+ });
+};
+img.src = "support/trns-high-bits-set.png";
+</script>