Import Cobalt 24.lts.3.1032501
diff --git a/base/sys_info_starboard.cc b/base/sys_info_starboard.cc
index b5aae9c..138a14c 100644
--- a/base/sys_info_starboard.cc
+++ b/base/sys_info_starboard.cc
@@ -15,9 +15,11 @@
 #include "base/sys_info.h"
 
 #include "base/logging.h"
+#include "starboard/common/system_property.h"
 #include "starboard/system.h"
 
 namespace base {
+ using starboard::kSystemPropertyMaxLength;
 
 // static
 int SysInfo::NumberOfProcessors() {
@@ -56,4 +58,17 @@
   return AmountOfPhysicalMemoryImpl();
 }
 
+// static
+std::string SysInfo::OperatingSystemName() {
+  char value[kSystemPropertyMaxLength];
+  SbSystemGetProperty(kSbSystemPropertyPlatformName, value,
+                      kSystemPropertyMaxLength);
+  return value;
+}
+
+// static
+std::string SysInfo::OperatingSystemVersion() {
+  return SysInfo::OperatingSystemName();
+}
+
 }  // namespace base
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index df72296..89b26d3 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -457,14 +457,7 @@
       # .TOC file, overwrite it, otherwise, don't change it.
       tocfile = sofile + ".TOC"
 
-      # TODO(b/206642994): see if we can remove this condition. It's needed for
-      # now because we use the ld.lld linker for evergreen platforms and need to
-      # pass options as `option` instead of `-Wl,option`.
-      if (is_starboard && sb_is_evergreen && !is_starboard_toolchain) {
-        link_command = "$ld -shared -soname=\"$soname\" {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\""
-      } else {
-        link_command = "$ld -shared -Wl,-soname=\"$soname\" {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\""
-      }
+      link_command = "$ld -shared -Wl,-soname=\"$soname\" {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\""
 
       # Generate a map file to be used for binary size analysis.
       # Map file adds ~10% to the link time on a z620.
@@ -491,11 +484,6 @@
 
       if (target_cpu == "mipsel" && is_component_build && is_android) {
         rspfile_content = "-Wl,--start-group -Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}} -Wl,--end-group$tail_lib_dependencies"
-        # TODO(b/206642994): see if we can remove this condition. It's needed for
-        # now because we use the ld.lld linker for evergreen platforms and need
-        # to pass options as `option` instead of `-Wl,option`.
-      } else if (is_starboard && sb_is_evergreen && !is_starboard_toolchain) {
-        rspfile_content = "--whole-archive {{inputs}} {{solibs}} --no-whole-archive {{libs}}$tail_lib_dependencies"
       } else {
         rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}$tail_lib_dependencies"
       }
diff --git a/cobalt/browser/application.cc b/cobalt/browser/application.cc
index 9f81b5f..e6febfe 100644
--- a/cobalt/browser/application.cc
+++ b/cobalt/browser/application.cc
@@ -1512,9 +1512,9 @@
   // it's enabled or upload interval.
   bool is_metrics_enabled = persistent_settings_->GetPersistentSettingAsBool(
       metrics::kMetricEnabledSettingName, false);
-  metrics_services_manager_->SetUploadInterval(
-      persistent_settings_->GetPersistentSettingAsInt(
-          metrics::kMetricEventIntervalSettingName, 300));
+  auto metric_event_interval = persistent_settings_->GetPersistentSettingAsInt(
+      metrics::kMetricEventIntervalSettingName, 300);
+  metrics_services_manager_->SetUploadInterval(metric_event_interval);
   metrics_services_manager_->ToggleMetricsEnabled(is_metrics_enabled);
   // Metric recording state initialization _must_ happen before we bootstrap
   // otherwise we crash.
@@ -1523,6 +1523,10 @@
   // UpdateUploadPermissions bootstraps the whole metric reporting, scheduling,
   // and uploading cycle.
   metrics_services_manager_->UpdateUploadPermissions(is_metrics_enabled);
+  LOG(INFO)
+      << "Cobalt Telemetry initialized with settings: is_metrics_enabled: "
+      << is_metrics_enabled
+      << ", metric_event_interval: " << metric_event_interval;
 }
 
 }  // namespace browser
diff --git a/cobalt/browser/metrics/cobalt_metrics_log_uploader.cc b/cobalt/browser/metrics/cobalt_metrics_log_uploader.cc
index 1d3050d..49f1c81 100644
--- a/cobalt/browser/metrics/cobalt_metrics_log_uploader.cc
+++ b/cobalt/browser/metrics/cobalt_metrics_log_uploader.cc
@@ -14,6 +14,7 @@
 
 #include "cobalt/browser/metrics/cobalt_metrics_log_uploader.h"
 
+#include "base/base64url.h"
 #include "base/logging.h"
 #include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
 #include "cobalt/h5vcc/h5vcc_metric_type.h"
@@ -59,9 +60,15 @@
       PopulateCobaltUmaEvent(uma_event, reporting_info, cobalt_uma_event);
       LOG(INFO) << "Publishing Cobalt metrics upload event. Type: "
                 << h5vcc::H5vccMetricType::kH5vccMetricTypeCobaltUma;
-      // Publish the trimmed Cobalt UMA proto.
+      std::string base64_encoded_proto;
+      // Base64 encode the payload as web client's can't consume it without
+      // corrupting the data (see b/293431381). Also, use a URL/web safe
+      // encoding so it can be safely included in any web network request.
+      base::Base64UrlEncode(cobalt_uma_event.SerializeAsString(),
+                            base::Base64UrlEncodePolicy::INCLUDE_PADDING,
+                            &base64_encoded_proto);
       upload_handler_->Run(h5vcc::H5vccMetricType::kH5vccMetricTypeCobaltUma,
-                           cobalt_uma_event.SerializeAsString());
+                           base64_encoded_proto);
     }
   }
 
diff --git a/cobalt/browser/metrics/cobalt_metrics_log_uploader_test.cc b/cobalt/browser/metrics/cobalt_metrics_log_uploader_test.cc
index 5adb841..78e7d18 100644
--- a/cobalt/browser/metrics/cobalt_metrics_log_uploader_test.cc
+++ b/cobalt/browser/metrics/cobalt_metrics_log_uploader_test.cc
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "base/base64url.h"
 #include "base/test/mock_callback.h"
 #include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
 #include "cobalt/h5vcc/h5vcc_metrics.h"
@@ -82,9 +83,13 @@
 
   std::string compressed_message;
   compression::GzipCompress(uma_log.SerializeAsString(), &compressed_message);
+  std::string base64_encoded_proto;
+  base::Base64UrlEncode(cobalt_event.SerializeAsString(),
+                        base::Base64UrlEncodePolicy::INCLUDE_PADDING,
+                        &base64_encoded_proto);
   EXPECT_CALL(mock_upload_handler,
               Run(Eq(h5vcc::H5vccMetricType::kH5vccMetricTypeCobaltUma),
-                  StrEq(cobalt_event.SerializeAsString())))
+                  StrEq(base64_encoded_proto)))
       .Times(1);
   uploader_->UploadLog(compressed_message, "fake_hash", dummy_reporting_info);
   ASSERT_EQ(callback_count_, 1);
@@ -99,9 +104,13 @@
   cobalt_event2.mutable_reporting_info()->CopyFrom(dummy_reporting_info);
   std::string compressed_message2;
   compression::GzipCompress(uma_log2.SerializeAsString(), &compressed_message2);
+  std::string base64_encoded_proto2;
+  base::Base64UrlEncode(cobalt_event2.SerializeAsString(),
+                        base::Base64UrlEncodePolicy::INCLUDE_PADDING,
+                        &base64_encoded_proto2);
   EXPECT_CALL(mock_upload_handler,
               Run(Eq(h5vcc::H5vccMetricType::kH5vccMetricTypeCobaltUma),
-                  StrEq(cobalt_event2.SerializeAsString())))
+                  StrEq(base64_encoded_proto2)))
       .Times(1);
   uploader_->UploadLog(compressed_message2, "fake_hash", dummy_reporting_info);
   ASSERT_EQ(callback_count_, 2);
diff --git a/cobalt/browser/metrics/cobalt_metrics_services_manager.cc b/cobalt/browser/metrics/cobalt_metrics_services_manager.cc
index 3874d08..acb5d8b 100644
--- a/cobalt/browser/metrics/cobalt_metrics_services_manager.cc
+++ b/cobalt/browser/metrics/cobalt_metrics_services_manager.cc
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "base/logging.h"
 #include "cobalt/browser/metrics/cobalt_metrics_service_client.h"
 #include "cobalt/browser/metrics/cobalt_metrics_services_manager_client.h"
 #include "components/metrics_services_manager/metrics_services_manager.h"
@@ -56,6 +57,7 @@
       static_cast<CobaltMetricsServiceClient*>(GetMetricsServiceClient());
   DCHECK(client);
   client->SetOnUploadHandler(uploader_callback);
+  LOG(INFO) << "New Cobalt Telemetry metric upload handler bound.";
 }
 
 void CobaltMetricsServicesManager::ToggleMetricsEnabled(bool is_enabled) {
@@ -73,6 +75,7 @@
   client->GetEnabledStateProvider()->SetConsentGiven(is_enabled);
   client->GetEnabledStateProvider()->SetReportingEnabled(is_enabled);
   UpdateUploadPermissions(is_enabled);
+  LOG(INFO) << "Cobalt Telemetry enabled state toggled to: " << is_enabled;
 }
 
 void CobaltMetricsServicesManager::SetUploadInterval(
@@ -90,6 +93,8 @@
           GetMetricsServiceClient());
   DCHECK(client);
   client->SetUploadInterval(interval_seconds);
+  LOG(INFO) << "Cobalt Telemetry metric upload interval changed to: "
+            << interval_seconds;
 }
 
 
diff --git a/cobalt/browser/web_module.cc b/cobalt/browser/web_module.cc
index 33ca0be..7e5f31b 100644
--- a/cobalt/browser/web_module.cc
+++ b/cobalt/browser/web_module.cc
@@ -537,6 +537,7 @@
       data.options.loader_thread_priority));
 
   animated_image_tracker_.reset(new loader::image::AnimatedImageTracker(
+      web_context_->name().c_str(),
       data.options.animated_image_decode_thread_priority));
 
   DCHECK_LE(0, data.options.image_cache_capacity);
@@ -975,6 +976,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   web_module_stat_tracker_->OnRenderTreeRasterized(produced_time,
                                                    rasterized_time);
+  animated_image_tracker_->OnRenderTreeRasterized();
   if (produced_time >= last_render_tree_produced_time_) {
     is_render_tree_rasterization_pending_ = false;
   }
diff --git a/cobalt/build/cobalt_configuration.py b/cobalt/build/cobalt_configuration.py
index 91b90a6..e1320ab 100644
--- a/cobalt/build/cobalt_configuration.py
+++ b/cobalt/build/cobalt_configuration.py
@@ -105,6 +105,7 @@
     ]
     return filters
 
+  # TODO(b/292007482): Replace static list with gn query.
   def GetTestTargets(self):
     return [
         'audio_test',
@@ -112,38 +113,48 @@
         'base_unittests',
         'bindings_test',
         'browser_test',
+        'components_metrics_tests',
+        'crypto_impl_test',
         'crypto_unittests',
         'csp_test',
-        'css_parser_test',
         'cssom_test',
+        'css_parser_test',
+        'cwrappers_test',
         'dom_parser_test',
         'dom_test',
         'extension_test',
+        # TODO(b/292127297): This target is not built for all platforms.
+        # 'ffmpeg_demuxer_test',
         'graphics_system_test',
         'layout_test',
         'layout_tests',
-        'cwrappers_test',
         'loader_test',
         'math_test',
         'media_capture_test',
         'media_session_test',
         'media_stream_test',
+        # TODO(b/292030213): Crashes on evergreen
+        # 'media_test',
         'memory_store_test',
         'metrics_test',
         'nb_test',
         'net_unittests',
         'network_test',
+        'overlay_info_test',
         'persistent_settings_test',
+        'png_utils_test',
         'poem_unittests',
-        'render_tree_test',
         'renderer_test',
+        'render_tree_test',
         'scroll_engine_tests',
+        'speech_test',
         'storage_test',
         'text_encoding_test',
-        'web_test',
+        'watchdog_test',
         'web_animations_test',
         'webdriver_test',
         'websocket_test',
+        'web_test',
         'worker_test',
         'xhr_test',
         'zip_unittests',
diff --git a/cobalt/demos/content/animated-webp-performance-demo/10_turtle.webp b/cobalt/demos/content/animated-webp-performance-demo/10_turtle.webp
new file mode 100644
index 0000000..800df18
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/10_turtle.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/1_fan.webp b/cobalt/demos/content/animated-webp-performance-demo/1_fan.webp
new file mode 100644
index 0000000..f982fd8
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/1_fan.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/2_heart.webp b/cobalt/demos/content/animated-webp-performance-demo/2_heart.webp
new file mode 100644
index 0000000..79cdd39
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/2_heart.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/3_cry.webp b/cobalt/demos/content/animated-webp-performance-demo/3_cry.webp
new file mode 100644
index 0000000..c045e21
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/3_cry.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/4_clap.webp b/cobalt/demos/content/animated-webp-performance-demo/4_clap.webp
new file mode 100644
index 0000000..194a34c
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/4_clap.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/5_egg.webp b/cobalt/demos/content/animated-webp-performance-demo/5_egg.webp
new file mode 100644
index 0000000..995a4cb
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/5_egg.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/6_party.webp b/cobalt/demos/content/animated-webp-performance-demo/6_party.webp
new file mode 100644
index 0000000..d5dfb16
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/6_party.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/7_rofl.webp b/cobalt/demos/content/animated-webp-performance-demo/7_rofl.webp
new file mode 100644
index 0000000..4c6c375
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/7_rofl.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/8_melt.webp b/cobalt/demos/content/animated-webp-performance-demo/8_melt.webp
new file mode 100644
index 0000000..3feba61
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/8_melt.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/9_explode.webp b/cobalt/demos/content/animated-webp-performance-demo/9_explode.webp
new file mode 100644
index 0000000..3c548ce
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/9_explode.webp
Binary files differ
diff --git a/cobalt/demos/content/animated-webp-performance-demo/index.html b/cobalt/demos/content/animated-webp-performance-demo/index.html
new file mode 100644
index 0000000..5613cc8
--- /dev/null
+++ b/cobalt/demos/content/animated-webp-performance-demo/index.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<!--
+ | Demo to help test animated webp performance metrics.
+ | We set up decoding speed tracking on a regular interval, and make a
+ | customizeable page with varying number of decoded images.
+ -->
+<html>
+
+<head>
+  <title>WebP performance test</title>
+  <style type="text/css">
+
+    body {
+      background-color: white;
+    }
+    .image {
+      width: 100px;
+      height: 100px;
+      background-size: contain;
+      display: inline-block;
+    }
+    .highlight {
+      background-color: rgb(0, 255, 0);
+    }
+  </style>
+  <script type="text/javascript">
+    window.onload = () => {
+      var size = 100; // Default pixel size of rendered images
+      var search = window.location.search;
+      var num = 1; // Default number of decoded images
+
+      // Grab URL search args
+      var matches = search.matchAll(/num=([0-9]+)/gm);
+      for (const match of matches) {
+        num = match[1]
+      }
+      var matches = search.matchAll(/size=([0-9]+)/gm);
+      for (const match of matches) {
+        size = match[1]
+      }
+
+      // Insert images into DOM tree
+      var layer = document.getElementById('layer');
+      function addImage(img, size) {
+        var el = document.createElement('span');
+        console.log(`adding ${img}`);
+        el.classList.add('image');
+        el.style['backgroundImage'] = `url(${img}.webp)`;
+        el.style['width'] = `${size}px`;
+        el.style['height'] = `${size}px`;
+        layer.appendChild(el)
+        console.log("Added image");
+      }
+      var images = [
+        "1_fan","2_heart","3_cry","4_clap", "5_egg",
+        "6_party","7_rofl","8_melt","9_explode","10_turtle"
+      ]
+      for(i = 0; i< num; i++)  {
+        (function(i) {
+          var img = images[i % 10];
+          window.setTimeout( () => {  addImage(img,size) } , 1 + i*40);
+        })(i)
+      }
+
+      // Set up function retrieve CVals.
+      var getCVal = function(name) { return 0 }
+      if (typeof h5vcc != "undefined" && typeof h5vcc.cVal != "undefined") {
+        getCVal = function(name) {
+          return h5vcc.cVal.getValue(name);
+        }
+      }
+
+      // Set up periodic stats tracking loop.
+      var last_frames = 0;
+      var last_time = performance.now();
+      function updateStats() {
+        var current_time = performance.now();
+        var time_delta_milliseconds = current_time - last_time;
+        var decoded_frames =
+          getCVal('Count.MainWebModule.AnimatedImage.DecodedFrames');
+        var underruns = getCVal('Count.MainWebModule.AnimatedImage.DecodingUnderruns');
+        var overruns = getCVal('Count.MainWebModule.AnimatedImage.DecodingOverruns');
+        var newly_decoded_frames = decoded_frames - last_frames;
+        var fps = parseInt( newly_decoded_frames * 100 / (time_delta_milliseconds / 1000.0)) / 100;
+        document.getElementById('Active').textContent =
+          getCVal('Count.MainWebModule.AnimatedImage.Active');
+        document.getElementById('DecodedFrames').textContent = decoded_frames;
+        document.getElementById('DecodingUnderruns').textContent = underruns
+        document.getElementById('DecodingOverruns').textContent = overruns;
+        document.getElementById('DecodedFPS').textContent = fps;
+        document.getElementById('UnderrunPercent').textContent =  parseInt(underruns / decoded_frames * 100.0);
+        document.getElementById('OverrunPercent').textContent =  parseInt(overruns / decoded_frames * 100.0);
+
+        last_frames = decoded_frames;
+        last_time = current_time;
+      }
+      window.setInterval(updateStats, 1000);
+
+      // Set up keyboard menu nav
+      var menu = document.getElementById('menu').children;
+      var index = 0;
+      function refresh() {
+        var textBox = document.getElementById('nav');
+        for (let i = 0; i < menu.length; i++) {
+          if (i == index) {
+            menu[i].classList.add('highlight');
+          } else {
+            menu[i].classList.remove('highlight');
+          }
+        }
+      }
+      document.addEventListener('keydown', function (e) {
+        // left, up, android left, up
+        if ([37, 38, 32782, 32780].includes(e.keyCode)) {
+          index -= 1;
+        //right, down, android right, down
+        } else if ([39, 40, 32781, 32783].includes(e.keyCode)) {
+          index += 1;
+        // enter, android enter
+        } else if ([13, 32768].includes(e.keyCode)) {
+          var el = document.getElementById('menu').children[index];
+          window.location = el.firstChild.href;
+        }
+        index = (index + menu.length) % menu.length;
+        refresh();
+      });
+      refresh();
+    }
+  </script>
+</head>
+
+<body>
+  <div class="background"></div>
+  <div id="menu">
+    <span><a href="?size=100&amp;num=1">1 small image</a></span>
+    <span><a href="?size=300&amp;num=1">1 large image</a></span>
+    <span><a href="?size=100&amp;num=2">2 small images</a></span>
+    <span><a href="?size=300&amp;num=2">2 large image</a></span>
+    <span><a href="?size=100&amp;num=3">3 small images</a></span>
+    <span><a href="?size=300&amp;num=3">3 large images</a></span>
+    <span><a href="?size=100&amp;num=4">4 small images</a></span>
+    <span><a href="?size=300&amp;num=4">4 large images</a></span>
+    <div></div>
+    <span><a href="?size=100&amp;num=4">5 small images</a></span>
+    <span><a href="?size=300&amp;num=4">5 large images</a></span>
+    <span><a href="?size=100&amp;num=6">6 small images</a></span>
+    <span><a href="?size=300&amp;num=6">6 large images</a></span>
+    <span><a href="?size=100&amp;num=8">8 small images</a></span>
+    <span><a href="?size=300&amp;num=8">8 large images</a></span>
+    <span><a href="?size=100&amp;num=10">10 small images</a></span>
+    <span><a href="?size=300&amp;num=10">10 large images</a></span>
+  </div>
+  <div id="metrics">
+    <div><span>Total images playing:</span><span id="Active"></span></div>
+    <div><span>Total frames decoded:</span><span id="DecodedFrames"></span></div>
+    <div><span>Total frames underrun:</span><span id="DecodingUnderruns"></span></div>
+    <div><span>Total frames overrun:</span><span id="DecodingOverruns"></span></div>
+    <div><span>Frames decoded per second:</span><span id="DecodedFPS"></span></div>
+    <div><span>Underrun %:</span><span id="UnderrunPercent"></span>
+      <span>Overrun %:</span><span id="OverrunPercent"></span></div>
+  </div>
+
+  <div class="layer" id="layer"></div>
+</body>
+
+</html>
diff --git a/cobalt/demos/content/video-background-demo/dash-audio.mp4 b/cobalt/demos/content/video-background-demo/dash-audio.mp4
new file mode 100644
index 0000000..b26721c
--- /dev/null
+++ b/cobalt/demos/content/video-background-demo/dash-audio.mp4
Binary files differ
diff --git a/cobalt/demos/content/video-background-demo/sddefault.jpg b/cobalt/demos/content/video-background-demo/sddefault.jpg
new file mode 100644
index 0000000..ef2dae5
--- /dev/null
+++ b/cobalt/demos/content/video-background-demo/sddefault.jpg
Binary files differ
diff --git a/cobalt/demos/content/video-background-demo/video-background-demo.html b/cobalt/demos/content/video-background-demo/video-background-demo.html
new file mode 100644
index 0000000..c68d4da
--- /dev/null
+++ b/cobalt/demos/content/video-background-demo/video-background-demo.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<!--
+ | Copyright 2023 The Cobalt Authors. All Rights Reserved.
+ |
+ | Licensed under the Apache License, Version 2.0 (the "License");
+ | you may not use this file except in compliance with the License.
+ | You may obtain a copy of the License at
+ |
+ |     http://www.apache.org/licenses/LICENSE-2.0
+ |
+ | Unless required by applicable law or agreed to in writing, software
+ | distributed under the License is distributed on an "AS IS" BASIS,
+ | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ | See the License for the specific language governing permissions and
+ | limitations under the License.
+ -->
+
+<html>
+  <head>
+    <title>Video Elements With Background</title>
+    <style>
+        body {
+          margin: 0;
+        }
+
+        video {
+          width: 100%;
+          height: 100%;
+        }
+
+        #ui-layer {
+          display: flex;
+          justify-content: space-between;
+          position: absolute;
+          top: 15%;
+          height: 85%;
+          width: 100%;
+          background-color: rgba(33, 33, 33, .75);
+          padding: 24px;
+          margin: auto;
+        }
+
+        .item {
+          width: 320px;
+          height: 240px;
+          display: inline-block;
+          margin: 24px;
+          vertical-align: middle;
+        }
+    </style>
+  </head>
+  <body>
+    <div id="ui-layer">
+      <div class="item">
+        <video id="video1" muted="1" style="background-color: #4285F4">
+        </video>
+      </div>
+      <div class="item">
+        <video id="video2" muted="1"
+           style="background-image: url(sddefault.jpg);
+                  background-size: 320px 240px;">
+        </video>
+      </div>
+      <div class="item">
+        <video id="video3" muted="1" style="background-color: #4285F4">
+        </video>
+      </div>
+      <div class="item">
+        <video id="video4" muted="1"
+           style="background-image: url(sddefault.jpg);
+                  background-size: 320px 240px;">
+        </video>
+      </div>
+    </div>
+    <script src="video-background-demo.js"></script>
+  </body>
+</html>
diff --git a/cobalt/demos/content/video-background-demo/video-background-demo.js b/cobalt/demos/content/video-background-demo/video-background-demo.js
new file mode 100644
index 0000000..1c50180
--- /dev/null
+++ b/cobalt/demos/content/video-background-demo/video-background-demo.js
@@ -0,0 +1,106 @@
+// Copyright 2023 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var nextVideoElementIndex = 0;
+var audioData;
+var videoData;
+
+function downloadMediaData(downloadedCallback) {
+  var xhr = new XMLHttpRequest;
+
+  xhr.onload = function() {
+    audioData = xhr.response;
+    console.log("Downloaded " + audioData.byteLength + " of audio data.");
+
+    xhr.onload = function() {
+      videoData = xhr.response;
+      console.log("Downloaded " + videoData.byteLength + " of video data.");
+      downloadedCallback();
+    }
+
+    xhr.open("GET", "vp9-720p.webm", true);
+    xhr.send();
+  }
+
+  xhr.open("GET", "dash-audio.mp4", true);
+  xhr.responseType = "arraybuffer";
+  xhr.send();
+}
+
+function playVideoOn(videoElement) {
+  var ms = new MediaSource;
+  ms.addEventListener('sourceopen', function() {
+    console.log("Creating SourceBuffer objects.");
+    var audioBuffer = ms.addSourceBuffer('audio/mp4; codecs="mp4a.40.2"');
+    var videoBuffer = ms.addSourceBuffer('video/webm; codecs="vp9"; decode-to-texture=true');
+    audioBuffer.addEventListener("updateend", function() {
+      audioBuffer.abort();
+      videoBuffer.addEventListener("updateend", function() {
+        setTimeout(function() {
+          videoBuffer.addEventListener("updateend", function() {
+            videoBuffer.abort();
+            ms.endOfStream();
+            videoElement.ontimeupdate = function() {
+              if (videoElement.currentTime > 10) {
+                console.log("Stop playback.");
+                videoElement.src = '';
+                videoElement.load();
+                videoElement.ontimeupdate = null;
+              }
+            }
+            console.log("Start playback.");
+            videoElement.play();
+          });
+          videoBuffer.appendBuffer(videoData.slice(1024));
+        }, 5000);
+      });
+      videoBuffer.appendBuffer(videoData.slice(0, 1024));
+    });
+    audioBuffer.appendBuffer(audioData);
+  });
+
+  console.log("Attaching MediaSource to video element.");
+  videoElement.src = URL.createObjectURL(ms);
+}
+
+function setupKeyHandler() {
+  document.onkeydown = function() {
+    videoElements = document.getElementsByTagName('video');
+    for(let i = 0; i < videoElements.length; i++) {
+      if (videoElements[i].playing) {
+        console.log("Ignore key press as a video is still playing.");
+        return;
+      }
+    }
+
+    nextVideoElementIndex = nextVideoElementIndex % videoElements.length;
+
+    console.log("Trying to play next video at index " + nextVideoElementIndex);
+
+    var currentVideoElement = videoElements[nextVideoElementIndex];
+    if (currentVideoElement.setMaxVideoCapabilities) {
+      if (nextVideoElementIndex < videoElements.length / 2) {
+        currentVideoElement.setMaxVideoCapabilities("");
+      } else {
+        currentVideoElement.setMaxVideoCapabilities("width=1920; height=1080");
+      }
+    }
+
+    nextVideoElementIndex++;
+
+    playVideoOn(currentVideoElement);
+  };
+}
+
+downloadMediaData(setupKeyHandler);
diff --git a/cobalt/demos/content/video-background-demo/vp9-720p.webm b/cobalt/demos/content/video-background-demo/vp9-720p.webm
new file mode 100644
index 0000000..08a670e
--- /dev/null
+++ b/cobalt/demos/content/video-background-demo/vp9-720p.webm
Binary files differ
diff --git a/cobalt/doc/cvals.md b/cobalt/doc/cvals.md
index 6accd8f..68317e4 100644
--- a/cobalt/doc/cvals.md
+++ b/cobalt/doc/cvals.md
@@ -119,6 +119,18 @@
     compatibility violations encountered.
 *   **Count.XHR** - The total number of xhr::XMLHttpRequest in existence
     globally.
+*   **Count.MainWebModule.AnimatedImage.Active** - The total number of currently
+    active animated image decoders. Same image from a single URL source rendered
+    multiple times across the content counts as one decoder.
+*   **Count.MainWebModule.AnimatedImage.DecodedFrames** - Total number of decoded
+    frames across all active image decoders. This number resets only when
+    WebModule gets re-created - e.g. page reload, navigation.
+*   **Count.MainWebModule.AnimatedImage.DecodingUnderruns** - Total number of
+    frames when animated image decoding has fallen behind real-time, as defined
+    by image frame exposure times. This indicates a CPU bottleneck.
+*   **Count.MainWebModule.AnimatedImage.DecodingOverruns** - Total number of
+    frames when animated image decoding has been attempted too early, before
+    next frame exposure time. This indicates a timing issue in platform.
 
 ### Event
 
diff --git a/cobalt/dom/html_video_element.cc b/cobalt/dom/html_video_element.cc
index a973f3e..75b3f9f 100644
--- a/cobalt/dom/html_video_element.cc
+++ b/cobalt/dom/html_video_element.cc
@@ -18,6 +18,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
 #include "cobalt/dom/dom_settings.h"
+#include "cobalt/dom/media_settings.h"
 #include "cobalt/dom/performance.h"
 #include "cobalt/dom/window.h"
 #include "cobalt/math/size_f.h"
@@ -30,6 +31,15 @@
 
 const char HTMLVideoElement::kTagName[] = "video";
 
+const MediaSettings& GetMediaSettings(web::EnvironmentSettings* settings) {
+  DCHECK(settings);
+  DCHECK(settings->context());
+  DCHECK(settings->context()->web_settings());
+
+  const auto& web_settings = settings->context()->web_settings();
+  return web_settings->media_settings();
+}
+
 HTMLVideoElement::HTMLVideoElement(Document* document)
     : HTMLMediaElement(document, base::Token(kTagName)) {}
 
@@ -98,9 +108,15 @@
   }
 }
 
-scoped_refptr<DecodeTargetProvider>
-HTMLVideoElement::GetDecodeTargetProvider() {
+scoped_refptr<DecodeTargetProvider> HTMLVideoElement::GetDecodeTargetProvider(
+    bool* paint_to_black) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(paint_to_black);
+
+  *paint_to_black = GetMediaSettings(environment_settings())
+                        .IsPaintingVideoBackgroundToBlack()
+                        .value_or(false);
+
   return player() ? player()->GetDecodeTargetProvider() : NULL;
 }
 
diff --git a/cobalt/dom/html_video_element.h b/cobalt/dom/html_video_element.h
index b98b6f6..914a69e 100644
--- a/cobalt/dom/html_video_element.h
+++ b/cobalt/dom/html_video_element.h
@@ -52,7 +52,10 @@
   // From HTMLElement
   scoped_refptr<HTMLVideoElement> AsHTMLVideoElement() override { return this; }
 
-  scoped_refptr<DecodeTargetProvider> GetDecodeTargetProvider();
+  // When the return value is nullptr, and |paint_to_black| is set to true, the
+  // caller is expected to paint the area covered by the video to black.
+  scoped_refptr<DecodeTargetProvider> GetDecodeTargetProvider(
+      bool* paint_to_black);
 
   WebMediaPlayer::SetBoundsCB GetSetBoundsCB();
 
diff --git a/cobalt/dom/media_settings.cc b/cobalt/dom/media_settings.cc
index 2915df3..ed39dbe 100644
--- a/cobalt/dom/media_settings.cc
+++ b/cobalt/dom/media_settings.cc
@@ -77,6 +77,12 @@
       LOG(INFO) << name << ": set to " << value;
       return true;
     }
+  } else if (name == "MediaElement.PaintingVideoBackgroundToBlack") {
+    if (value == 0 || value == 1) {
+      is_painting_video_background_to_black_ = value != 0;
+      LOG(INFO) << name << ": set to " << value;
+      return true;
+    }
   } else {
     LOG(WARNING) << "Ignore unknown setting with name \"" << name << "\"";
     return false;
diff --git a/cobalt/dom/media_settings.h b/cobalt/dom/media_settings.h
index eace022..9f1a6f4 100644
--- a/cobalt/dom/media_settings.h
+++ b/cobalt/dom/media_settings.h
@@ -41,6 +41,7 @@
 
   virtual base::Optional<int>
   GetMediaElementTimeupdateEventIntervalInMilliseconds() const = 0;
+  virtual base::Optional<bool> IsPaintingVideoBackgroundToBlack() const = 0;
 
  protected:
   MediaSettings() = default;
@@ -89,6 +90,9 @@
       const override {
     return media_element_timeupdate_event_interval_in_milliseconds_;
   }
+  base::Optional<bool> IsPaintingVideoBackgroundToBlack() const override {
+    return is_painting_video_background_to_black_;
+  }
 
   // Returns true when the setting associated with `name` is set to `value`.
   // Returns false when `name` is not associated with any settings, or if
@@ -106,6 +110,8 @@
   base::Optional<int> max_source_buffer_append_size_in_bytes_;
 
   base::Optional<int> media_element_timeupdate_event_interval_in_milliseconds_;
+
+  base::Optional<bool> is_painting_video_background_to_black_;
 };
 
 }  // namespace dom
diff --git a/cobalt/dom/media_settings_test.cc b/cobalt/dom/media_settings_test.cc
index 8850f72..e4addfe 100644
--- a/cobalt/dom/media_settings_test.cc
+++ b/cobalt/dom/media_settings_test.cc
@@ -31,6 +31,7 @@
   EXPECT_FALSE(impl.GetMaxSizeForImmediateJob());
   EXPECT_FALSE(impl.GetMaxSourceBufferAppendSizeInBytes());
   EXPECT_FALSE(impl.GetMediaElementTimeupdateEventIntervalInMilliseconds());
+  EXPECT_FALSE(impl.IsPaintingVideoBackgroundToBlack());
 }
 
 TEST(MediaSettingsImplTest, SunnyDay) {
@@ -46,6 +47,7 @@
   ASSERT_TRUE(impl.Set("MediaSource.MaxSourceBufferAppendSizeInBytes", 100000));
   ASSERT_TRUE(
       impl.Set("MediaElement.TimeupdateEventIntervalInMilliseconds", 100001));
+  ASSERT_TRUE(impl.Set("MediaElement.PaintingVideoBackgroundToBlack", 1));
 
   EXPECT_EQ(impl.GetSourceBufferEvictExtraInBytes().value(), 100);
   EXPECT_EQ(impl.GetMinimumProcessorCountToOffloadAlgorithm().value(), 101);
@@ -56,6 +58,7 @@
   EXPECT_EQ(impl.GetMaxSourceBufferAppendSizeInBytes().value(), 100000);
   EXPECT_EQ(impl.GetMediaElementTimeupdateEventIntervalInMilliseconds().value(),
             100001);
+  EXPECT_TRUE(impl.IsPaintingVideoBackgroundToBlack().value());
 }
 
 TEST(MediaSettingsImplTest, RainyDay) {
@@ -71,6 +74,7 @@
   ASSERT_FALSE(impl.Set("MediaSource.MaxSourceBufferAppendSizeInBytes", 0));
   ASSERT_FALSE(
       impl.Set("MediaElement.TimeupdateEventIntervalInMilliseconds", 0));
+  ASSERT_FALSE(impl.Set("MediaElement.PaintingVideoBackgroundToBlack", 2));
 
   EXPECT_FALSE(impl.GetSourceBufferEvictExtraInBytes());
   EXPECT_FALSE(impl.GetMinimumProcessorCountToOffloadAlgorithm());
@@ -80,6 +84,7 @@
   EXPECT_FALSE(impl.GetMaxSizeForImmediateJob());
   EXPECT_FALSE(impl.GetMaxSourceBufferAppendSizeInBytes());
   EXPECT_FALSE(impl.GetMediaElementTimeupdateEventIntervalInMilliseconds());
+  EXPECT_FALSE(impl.IsPaintingVideoBackgroundToBlack());
 }
 
 TEST(MediaSettingsImplTest, ZeroValuesWork) {
@@ -95,6 +100,7 @@
   // O is an invalid value for "MediaSource.MaxSourceBufferAppendSizeInBytes".
   // O is an invalid value for
   // "MediaElement.TimeupdateEventIntervalInMilliseconds".
+  ASSERT_TRUE(impl.Set("MediaElement.PaintingVideoBackgroundToBlack", 0));
 
   EXPECT_EQ(impl.GetSourceBufferEvictExtraInBytes().value(), 0);
   EXPECT_EQ(impl.GetMinimumProcessorCountToOffloadAlgorithm().value(), 0);
@@ -102,6 +108,7 @@
   EXPECT_FALSE(impl.IsAvoidCopyingArrayBufferEnabled().value());
   EXPECT_FALSE(impl.IsCallingEndedWhenClosedEnabled().value());
   EXPECT_EQ(impl.GetMaxSizeForImmediateJob().value(), 0);
+  EXPECT_FALSE(impl.IsPaintingVideoBackgroundToBlack().value());
 }
 
 TEST(MediaSettingsImplTest, Updatable) {
@@ -117,6 +124,7 @@
   ASSERT_TRUE(impl.Set("MediaSource.MaxSourceBufferAppendSizeInBytes", 1));
   ASSERT_TRUE(
       impl.Set("MediaElement.TimeupdateEventIntervalInMilliseconds", 1));
+  ASSERT_TRUE(impl.Set("MediaElement.PaintingVideoBackgroundToBlack", 0));
 
   ASSERT_TRUE(impl.Set("MediaSource.SourceBufferEvictExtraInBytes", 1));
   ASSERT_TRUE(
@@ -128,6 +136,7 @@
   ASSERT_TRUE(impl.Set("MediaSource.MaxSourceBufferAppendSizeInBytes", 2));
   ASSERT_TRUE(
       impl.Set("MediaElement.TimeupdateEventIntervalInMilliseconds", 2));
+  ASSERT_TRUE(impl.Set("MediaElement.PaintingVideoBackgroundToBlack", 1));
 
   EXPECT_EQ(impl.GetSourceBufferEvictExtraInBytes().value(), 1);
   EXPECT_EQ(impl.GetMinimumProcessorCountToOffloadAlgorithm().value(), 1);
@@ -138,6 +147,7 @@
   EXPECT_EQ(impl.GetMaxSourceBufferAppendSizeInBytes().value(), 2);
   EXPECT_EQ(impl.GetMediaElementTimeupdateEventIntervalInMilliseconds().value(),
             2);
+  EXPECT_TRUE(impl.IsPaintingVideoBackgroundToBlack().value());
 }
 
 TEST(MediaSettingsImplTest, InvalidSettingNames) {
diff --git a/cobalt/h5vcc/h5vcc_metric_type.idl b/cobalt/h5vcc/h5vcc_metric_type.idl
index 762cc9e..79bf952 100644
--- a/cobalt/h5vcc/h5vcc_metric_type.idl
+++ b/cobalt/h5vcc/h5vcc_metric_type.idl
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 // The various metric types we support to be published through the H5vccMetrics
-// API.
+// API. The proto will be serialized and then base64 encoded.
 enum H5vccMetricType {
   // //third_party/metrics_proto/chrome_user_metrics_extension.proto
   // ChromeUserMetricsExtension proto.
diff --git a/cobalt/h5vcc/h5vcc_metrics.idl b/cobalt/h5vcc/h5vcc_metrics.idl
index c9f62a9..1d7292c 100644
--- a/cobalt/h5vcc/h5vcc_metrics.idl
+++ b/cobalt/h5vcc/h5vcc_metrics.idl
@@ -61,7 +61,8 @@
 };
 
 // Callback invoked when a new metric payload is ready to be published. The
-// payload is a serialized protobuf and the metric type should give the consumer
-// a hint on how to deserialize it. See h5vcc_metric_type.idl for more info.
+// payload is a base64 encoded serialized protobuf and the metric type should
+// give the consumer a hint on how to deserialize it. See h5vcc_metric_type.idl
+// for more info.
 callback H5vccMetricEventHandler =
     void(H5vccMetricType metricType, DOMString metricPayload);
diff --git a/cobalt/h5vcc/h5vcc_settings.cc b/cobalt/h5vcc/h5vcc_settings.cc
index 4babfd9..e6c7b26 100644
--- a/cobalt/h5vcc/h5vcc_settings.cc
+++ b/cobalt/h5vcc/h5vcc_settings.cc
@@ -106,10 +106,16 @@
   }
 
   if (name.compare(kQUIC) == 0) {
-    if (!network_module_) {
+    if (!persistent_settings_) {
       return false;
     } else {
-      network_module_->SetEnableQuic(value != 0);
+      persistent_settings_->SetPersistentSetting(
+          network::kQuicEnabledPersistentSettingsKey,
+          std::make_unique<base::Value>(value != 0));
+      // Tell NetworkModule (if exists) to re-query persistent settings.
+      if (network_module_) {
+        network_module_->SetEnableQuicFromPersistentSettings();
+      }
       return true;
     }
   }
diff --git a/cobalt/layout/box_generator.cc b/cobalt/layout/box_generator.cc
index 6eee421..b279f0c 100644
--- a/cobalt/layout/box_generator.cc
+++ b/cobalt/layout/box_generator.cc
@@ -339,22 +339,31 @@
   // If the optional is disengaged, then we don't know if punch out is enabled
   // or not.
   base::Optional<ReplacedBox::ReplacedBoxMode> replaced_box_mode;
-  if (video_element->GetDecodeTargetProvider()) {
+  bool paint_to_black = false;
+  auto decode_target_provider =
+      video_element->GetDecodeTargetProvider(&paint_to_black);
+  if (decode_target_provider) {
     DecodeTargetProvider::OutputMode output_mode =
-        video_element->GetDecodeTargetProvider()->GetOutputMode();
-    if (output_mode != DecodeTargetProvider::kOutputModeInvalid) {
+        decode_target_provider->GetOutputMode();
+    if (output_mode == DecodeTargetProvider::kOutputModeInvalid) {
+      if (paint_to_black) {
+        replaced_box_mode = ReplacedBox::ReplacedBoxMode::kPaintToBlack;
+      }
+    } else {
       replaced_box_mode =
           (output_mode == DecodeTargetProvider::kOutputModePunchOut)
               ? ReplacedBox::ReplacedBoxMode::kPunchOutVideo
-              : ReplacedBox::ReplacedBoxMode::kVideo;
+              : ReplacedBox::ReplacedBoxMode::kDecodeToTextureVideo;
     }
+  } else {
+    // ReplacedBox won't paint anything when |decode_target_provider| is
+    // nullptr, as |replace_image_cb_| is also null in this case.
   }
 
   ReplacedBoxGenerator replaced_box_generator(
       video_element->css_computed_style_declaration(),
-      video_element->GetDecodeTargetProvider()
-          ? base::Bind(GetVideoFrame, video_element->GetDecodeTargetProvider(),
-                       resource_provider)
+      decode_target_provider
+          ? base::Bind(GetVideoFrame, decode_target_provider, resource_provider)
           : ReplacedBox::ReplaceImageCB(),
       video_element->GetSetBoundsCB(), *paragraph_, text_position,
       base::nullopt, base::nullopt, base::nullopt, context_, replaced_box_mode,
diff --git a/cobalt/layout/replaced_box.cc b/cobalt/layout/replaced_box.cc
index 21eba9a..a31407e 100644
--- a/cobalt/layout/replaced_box.cc
+++ b/cobalt/layout/replaced_box.cc
@@ -316,9 +316,14 @@
     return;
   }
 
-  if (replaced_box_mode_ == base::nullopt) {
-    // If we don't have a data stream associated with this video [yet], then
-    // we don't yet know if it is punched out or not, and so render black.
+  if (!replaced_box_mode_.has_value()) {
+    // Don't render anything, so any background color or image will be visible.
+    return;
+  }
+
+  if (replaced_box_mode_ == ReplacedBoxMode::kPaintToBlack) {
+    // Explicitly render black if we don't have a data stream associated with
+    // this video [yet], this is the same as the previous behavior.
     border_node_builder->AddChild(new RectNode(
         math::RectF(content_box_size()),
         std::unique_ptr<render_tree::Brush>(new render_tree::SolidColorBrush(
@@ -327,7 +332,7 @@
     return;
   }
 
-  if (*replaced_box_mode_ == ReplacedBox::ReplacedBoxMode::kLottie) {
+  if (*replaced_box_mode_ == ReplacedBoxMode::kLottie) {
     AnimateNode::Builder animate_node_builder;
     scoped_refptr<LottieNode> lottie_node =
         new LottieNode(nullptr, math::RectF());
@@ -347,7 +352,7 @@
   // Map-to-mesh is only supported with decode-to-texture videos.
   const bool supports_mtm =
       replaced_box_mode_ &&
-      *replaced_box_mode_ == ReplacedBox::ReplacedBoxMode::kVideo;
+      *replaced_box_mode_ == ReplacedBoxMode::kDecodeToTextureVideo;
 
   if (supports_mtm && mtm_filter_function &&
       mtm_filter_function->mesh_spec().mesh_type() !=
@@ -759,7 +764,7 @@
   scoped_refptr<CompositionNode> composition_node =
       new CompositionNode(composition_node_builder);
 
-  if (*replaced_box_mode_ == ReplacedBox::ReplacedBoxMode::kPunchOutVideo) {
+  if (*replaced_box_mode_ == ReplacedBoxMode::kPunchOutVideo) {
     LetterboxDimensions letterbox_dims =
         GetLetterboxDimensions(content_size_, content_box_size());
     AddLetterboxedPunchThroughVideoNodeToRenderTree(
diff --git a/cobalt/layout/replaced_box.h b/cobalt/layout/replaced_box.h
index f4384e5..3837b7c 100644
--- a/cobalt/layout/replaced_box.h
+++ b/cobalt/layout/replaced_box.h
@@ -43,7 +43,12 @@
   typedef base::Callback<scoped_refptr<render_tree::Image>()> ReplaceImageCB;
   typedef render_tree::PunchThroughVideoNode::SetBoundsCB SetBoundsCB;
 
-  enum class ReplacedBoxMode { kVideo, kPunchOutVideo, kLottie };
+  enum class ReplacedBoxMode {
+    kPaintToBlack,  // Paint a black rectangle
+    kDecodeToTextureVideo,
+    kPunchOutVideo,
+    kLottie
+  };
 
   ReplacedBox(const scoped_refptr<cssom::CSSComputedStyleDeclaration>&
                   css_computed_style_declaration,
diff --git a/cobalt/loader/image/animated_image_tracker.cc b/cobalt/loader/image/animated_image_tracker.cc
index 98dadca..c7a3e73 100644
--- a/cobalt/loader/image/animated_image_tracker.cc
+++ b/cobalt/loader/image/animated_image_tracker.cc
@@ -15,7 +15,9 @@
 #include "cobalt/loader/image/animated_image_tracker.h"
 
 #include <algorithm>
+#include <utility>
 
+#include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
 #include "cobalt/base/polymorphic_downcast.h"
 
@@ -24,8 +26,22 @@
 namespace image {
 
 AnimatedImageTracker::AnimatedImageTracker(
+    const char* name,
     base::ThreadPriority animated_image_decode_thread_priority)
-    : animated_image_decode_thread_("AnimatedImage") {
+    : animated_image_decode_thread_("AnimatedImage"),
+      name_(name),
+      count_animated_images_active(
+          base::StringPrintf("Count.%s.AnimatedImage.Active", name), 0,
+          "Total number of active animated image decoders."),
+      count_animated_frames_decoded(
+          base::StringPrintf("Count.%s.AnimatedImage.DecodedFrames", name), 0,
+          "Total number of decoded animated image frames."),
+      count_animated_frames_decoding_underrun(
+          base::StringPrintf("Count.%s.AnimatedImage.DecodingUnderruns", name),
+          0, "Number of underruns from decoding animated images"),
+      count_animated_frames_decoding_overrun(
+          base::StringPrintf("Count.%s.AnimatedImage.DecodingOverruns", name),
+          0, "Number of overruns from decoding animated images") {
   TRACE_EVENT0("cobalt::loader::image", "AnimatedImageTracker::RecordImage()");
   base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT,
                                 0 /* default stack size */);
@@ -123,6 +139,17 @@
   playing_urls_.clear();
 }
 
+void AnimatedImageTracker::OnRenderTreeRasterized() {
+  count_animated_images_active = playing_urls_.size();
+  for (const auto& playing_url : playing_urls_) {
+    auto image = image_map_[playing_url.first].get();
+    auto stats = image->GetFrameDeltaStats();
+    count_animated_frames_decoded += stats.frames_decoded;
+    count_animated_frames_decoding_underrun += stats.frames_underrun;
+    count_animated_frames_decoding_overrun += stats.frames_overrun;
+  }
+}
+
 }  // namespace image
 }  // namespace loader
 }  // namespace cobalt
diff --git a/cobalt/loader/image/animated_image_tracker.h b/cobalt/loader/image/animated_image_tracker.h
index f6f38e4..6df920b 100644
--- a/cobalt/loader/image/animated_image_tracker.h
+++ b/cobalt/loader/image/animated_image_tracker.h
@@ -20,6 +20,7 @@
 
 #include "base/containers/small_map.h"
 #include "base/threading/thread.h"
+#include "cobalt/base/c_val.h"
 #include "cobalt/base/unused.h"
 #include "cobalt/loader/image/image.h"
 #include "url/gurl.h"
@@ -33,7 +34,8 @@
 // playing status is updated hence decoding is turned on / off for it.
 class AnimatedImageTracker {
  public:
-  explicit AnimatedImageTracker(
+  AnimatedImageTracker(
+      const char* name,
       base::ThreadPriority animated_image_decode_thread_priority);
   ~AnimatedImageTracker();
 
@@ -54,6 +56,9 @@
   // animations.
   void Reset();
 
+  // Called from WebModule to compute image animation related stats.
+  void OnRenderTreeRasterized();
+
  private:
   void OnDisplayStart(loader::image::AnimatedImage* image);
   void OnDisplayEnd(loader::image::AnimatedImage* image);
@@ -72,6 +77,15 @@
   URLToIntMap current_url_counts_;
   URLSet playing_urls_;
 
+  // The name of the WebModule this AnimatedImage tracker belongs to, for CVals.
+  const std::string name_;
+
+  // Animated image counters
+  base::CVal<int, base::CValPublic> count_animated_images_active;
+  base::CVal<int, base::CValPublic> count_animated_frames_decoded;
+  base::CVal<int, base::CValPublic> count_animated_frames_decoding_underrun;
+  base::CVal<int, base::CValPublic> count_animated_frames_decoding_overrun;
+
   // Used to ensure that all AnimatedImageTracker methods are called on the
   // same thread (*not* |animated_image_decode_thread_|), the thread that we
   // were constructed on.
diff --git a/cobalt/loader/image/animated_webp_image.cc b/cobalt/loader/image/animated_webp_image.cc
index cab2ca0..312098d 100644
--- a/cobalt/loader/image/animated_webp_image.cc
+++ b/cobalt/loader/image/animated_webp_image.cc
@@ -146,6 +146,8 @@
     return;
   }
   is_playing_ = true;
+  current_stats.frames_underrun = 0;
+  current_stats.frames_overrun = 0;
 
   if (received_first_frame_) {
     StartDecoding();
@@ -169,7 +171,8 @@
 void AnimatedWebPImage::StartDecoding() {
   TRACE_EVENT0("cobalt::loader::image", "AnimatedWebPImage::StartDecoding()");
   lock_.AssertAcquired();
-  current_frame_time_ = base::TimeTicks::Now();
+  decoding_start_time_ = current_frame_time_ = base::TimeTicks::Now();
+  current_stats.frames_decoded = 0;
   if (task_runner_->BelongsToCurrentThread()) {
     DecodeFrames();
   } else {
@@ -265,6 +268,7 @@
       LOG(ERROR) << "Failed to decode WebP image frame.";
       return false;
     }
+    current_stats.frames_decoded++;
   }
 
   // Alpha blend the current frame on top of the buffer.
@@ -349,6 +353,7 @@
   // Always wait for a consumer to consume the previous frame before moving
   // forward with decoding the next frame.
   if (!frame_provider_->FrameConsumed()) {
+    current_stats.frames_overrun++;
     return false;
   }
 
@@ -381,6 +386,7 @@
   if (next_frame_time_ < current_time) {
     // Don't let the animation fall back for more than a frame.
     next_frame_time_ = current_time;
+    current_stats.frames_underrun++;
   }
 
   return true;
@@ -426,6 +432,25 @@
   return target_canvas;
 }
 
+AnimatedImage::AnimatedImageDecodingStats
+AnimatedWebPImage::GetFrameDeltaStats() {
+  AnimatedImageDecodingStats result;
+  if (current_stats.frames_decoded >= last_stats.frames_decoded) {
+    result.frames_decoded =
+        current_stats.frames_decoded - last_stats.frames_decoded;
+    result.frames_underrun =
+        current_stats.frames_underrun - last_stats.frames_underrun;
+    result.frames_overrun =
+        current_stats.frames_overrun - last_stats.frames_overrun;
+  } else {
+    // There was a reset somewhere
+    // Simply return total, this discards any overflow data we might have had.
+    result = current_stats;
+  }
+  last_stats = current_stats;
+  return result;
+}
+
 }  // namespace image
 }  // namespace loader
 }  // namespace cobalt
diff --git a/cobalt/loader/image/animated_webp_image.h b/cobalt/loader/image/animated_webp_image.h
index 135bf6a..4d1be04 100644
--- a/cobalt/loader/image/animated_webp_image.h
+++ b/cobalt/loader/image/animated_webp_image.h
@@ -66,6 +66,8 @@
   // Returns the render image of the frame for debugging
   scoped_refptr<render_tree::Image> GetFrameForDebugging(int target_frame);
 
+  AnimatedImageDecodingStats GetFrameDeltaStats() override;
+
  private:
   ~AnimatedWebPImage() override;
 
@@ -119,12 +121,17 @@
   base::CancelableClosure decode_closure_;
   base::TimeTicks current_frame_time_;
   base::Optional<base::TimeTicks> next_frame_time_;
+
   // The original encoded data.
   std::vector<uint8> data_buffer_;
   scoped_refptr<render_tree::Image> current_canvas_;
   scoped_refptr<FrameProvider> frame_provider_;
   base::Lock lock_;
 
+  base::TimeTicks decoding_start_time_;
+  AnimatedImageDecodingStats current_stats;
+  AnimatedImageDecodingStats last_stats;
+
   // Makes sure that the thread that sets the task_runner is always consistent.
   // This is the thread sending Play()/Stop() calls, and is not necessarily
   // the same thread that the task_runner itself is running on.
diff --git a/cobalt/loader/image/image.h b/cobalt/loader/image/image.h
index af99363..bac9849 100644
--- a/cobalt/loader/image/image.h
+++ b/cobalt/loader/image/image.h
@@ -145,6 +145,16 @@
     image_node_builder->destination_rect = destination_rect;
     image_node_builder->local_transform = local_transform;
   }
+
+  // Frame counters for decoding.
+  struct AnimatedImageDecodingStats {
+    unsigned int frames_decoded = 0;
+    unsigned int frames_underrun = 0;
+    unsigned int frames_overrun = 0;
+  };
+
+  // Returns decoded frame stats since the last call, as a delta.
+  virtual AnimatedImageDecodingStats GetFrameDeltaStats() = 0;
 };
 
 }  // namespace image
diff --git a/cobalt/media/base/sbplayer_bridge.cc b/cobalt/media/base/sbplayer_bridge.cc
index fad7fda..92dc4da 100644
--- a/cobalt/media/base/sbplayer_bridge.cc
+++ b/cobalt/media/base/sbplayer_bridge.cc
@@ -707,7 +707,11 @@
     // a method of querying that texture.
     decode_target_provider_->SetGetCurrentSbDecodeTargetFunction(base::Bind(
         &SbPlayerBridge::GetCurrentSbDecodeTarget, base::Unretained(this)));
+    SB_LOG(INFO) << "Playing in decode-to-texture mode.";
+  } else {
+    SB_LOG(INFO) << "Playing in punch-out mode.";
   }
+
   decode_target_provider_->SetOutputMode(
       ToVideoFrameProviderOutputMode(output_mode_));
 
@@ -773,7 +777,11 @@
     // a method of querying that texture.
     decode_target_provider_->SetGetCurrentSbDecodeTargetFunction(base::Bind(
         &SbPlayerBridge::GetCurrentSbDecodeTarget, base::Unretained(this)));
+    SB_LOG(INFO) << "Playing in decode-to-texture mode.";
+  } else {
+    SB_LOG(INFO) << "Playing in punch-out mode.";
   }
+
   decode_target_provider_->SetOutputMode(
       ToVideoFrameProviderOutputMode(output_mode_));
   set_bounds_helper_->SetPlayerBridge(this);
diff --git a/cobalt/media/file_data_source_test.cc b/cobalt/media/file_data_source_test.cc
index 4fe7fe7..34989f8 100644
--- a/cobalt/media/file_data_source_test.cc
+++ b/cobalt/media/file_data_source_test.cc
@@ -31,6 +31,9 @@
 }
 
 TEST(FileDataSourceTest, SunnyDay) {
+  // TODO(b/292134341): Test fails on all platforms.
+  GTEST_SKIP();
+
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   FileDataSource data_source(
       GURL("file:///cobalt/media/testing/data/"
diff --git a/cobalt/network/network_module.cc b/cobalt/network/network_module.cc
index b7caed4..8154b7c 100644
--- a/cobalt/network/network_module.cc
+++ b/cobalt/network/network_module.cc
@@ -98,11 +98,16 @@
                             custom_proxy_rules));
 }
 
-void NetworkModule::SetEnableQuic(bool enable_quic) {
-  task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&URLRequestContext::SetEnableQuic,
-                 base::Unretained(url_request_context_.get()), enable_quic));
+void NetworkModule::SetEnableQuicFromPersistentSettings() {
+  // Called on initialization and when the persistent setting is changed.
+  if (options_.persistent_settings != nullptr) {
+    bool enable_quic = options_.persistent_settings->GetPersistentSettingAsBool(
+        kQuicEnabledPersistentSettingsKey, false);
+    task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&URLRequestContext::SetEnableQuic,
+                   base::Unretained(url_request_context_.get()), enable_quic));
+  }
 }
 
 void NetworkModule::SetEnableClientHintHeadersFlagsFromPersistentSettings() {
@@ -193,6 +198,8 @@
   DCHECK(url_request_context_);
   url_request_context_getter_ = new network::URLRequestContextGetter(
       url_request_context_.get(), thread_.get());
+
+  SetEnableQuicFromPersistentSettings();
 }
 
 void NetworkModule::OnCreate(base::WaitableEvent* creation_event) {
diff --git a/cobalt/network/network_module.h b/cobalt/network/network_module.h
index 6066324..b6c8bd2 100644
--- a/cobalt/network/network_module.h
+++ b/cobalt/network/network_module.h
@@ -59,6 +59,8 @@
   kCallTypeXHR = (1u << 5),
 };
 
+const char kQuicEnabledPersistentSettingsKey[] = "QUICEnabled";
+
 // Holds bit mask flag, read into |enable_client_hint_headers_flags_|.
 const char kClientHintHeadersEnabledPersistentSettingsKey[] =
     "clientHintHeadersEnabled";
@@ -128,7 +130,7 @@
 #endif
   void SetProxy(const std::string& custom_proxy_rules);
 
-  void SetEnableQuic(bool enable_quic);
+  void SetEnableQuicFromPersistentSettings();
 
   // Checks persistent settings to determine if Client Hint Headers are enabled.
   void SetEnableClientHintHeadersFlagsFromPersistentSettings();
diff --git a/cobalt/persistent_storage/persistent_settings.cc b/cobalt/persistent_storage/persistent_settings.cc
index ce64f97..52bc864 100644
--- a/cobalt/persistent_storage/persistent_settings.cc
+++ b/cobalt/persistent_storage/persistent_settings.cc
@@ -19,7 +19,6 @@
 
 #include "base/bind.h"
 #include "components/prefs/json_pref_store.h"
-#include "components/prefs/json_read_only_pref_store.h"
 #include "starboard/common/file.h"
 #include "starboard/common/log.h"
 #include "starboard/configuration_constants.h"
@@ -51,37 +50,23 @@
       std::string(storage_dir.data()) + kSbFileSepString + file_name;
   LOG(INFO) << "Persistent settings file path: " << persistent_settings_file_;
 
-  // Initialize pref_store_ with a JSONReadOnlyPrefStore, Used for
-  // synchronous PersistentSettings::Get calls made before the asynchronous
-  // InitializeWriteablePrefStore initializes pref_store_ with a writable
-  // instance.
-  {
-    base::AutoLock auto_lock(pref_store_lock_);
-    pref_store_ = base::MakeRefCounted<JsonReadOnlyPrefStore>(
-        base::FilePath(persistent_settings_file_));
-    pref_store_->ReadPrefs();
-  }
-
   message_loop()->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&PersistentSettings::InitializeWriteablePrefStore,
+      FROM_HERE, base::Bind(&PersistentSettings::InitializePrefStore,
                             base::Unretained(this)));
+  pref_store_initialized_.Wait();
+  destruction_observer_added_.Wait();
 }
 
 PersistentSettings::~PersistentSettings() {
   DCHECK(message_loop());
   DCHECK(thread_.IsRunning());
 
-  // Ensure that the destruction observer got added and the pref store was
-  // initialized before stopping the thread. Stop the thread. This will cause
-  // the destruction observer to be notified.
-  writeable_pref_store_initialized_.Wait();
-  destruction_observer_added_.Wait();
   // Wait for all previously posted tasks to finish.
   thread_.message_loop()->task_runner()->WaitForFence();
   thread_.Stop();
 }
 
-void PersistentSettings::InitializeWriteablePrefStore() {
+void PersistentSettings::InitializePrefStore() {
   DCHECK_EQ(base::MessageLoop::current(), message_loop());
   // Register as a destruction observer to shut down the thread once all
   // pending tasks have been executed and the message loop is about to be
@@ -94,9 +79,7 @@
     pref_store_ = base::MakeRefCounted<JsonPrefStore>(
         base::FilePath(persistent_settings_file_));
     pref_store_->ReadPrefs();
-    // PersistentSettings Set and Remove Helper methods will now be able to
-    // access the pref_store_ initialized from the dedicated thread_.
-    writeable_pref_store_initialized_.Signal();
+    pref_store_initialized_.Signal();
   }
   validated_initial_settings_ = GetPersistentSettingAsBool(kValidated, false);
   if (!validated_initial_settings_) {
@@ -116,10 +99,9 @@
   DCHECK_EQ(base::MessageLoop::current(), message_loop());
   if (!validated_initial_settings_) {
     base::AutoLock auto_lock(pref_store_lock_);
-    writeable_pref_store()->SetValue(
-        kValidated, std::make_unique<base::Value>(true),
-        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    writeable_pref_store()->CommitPendingWrite();
+    pref_store_->SetValue(kValidated, std::make_unique<base::Value>(true),
+                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+    CommitPendingWrite(false);
     validated_initial_settings_ = true;
   }
 }
@@ -190,7 +172,7 @@
 
 void PersistentSettings::SetPersistentSetting(
     const std::string& key, std::unique_ptr<base::Value> value,
-    base::OnceClosure closure) {
+    base::OnceClosure closure, bool blocking) {
   if (key == kValidated) {
     LOG(ERROR) << "Cannot set protected persistent setting: " << key;
     return;
@@ -198,21 +180,20 @@
   message_loop()->task_runner()->PostTask(
       FROM_HERE, base::BindOnce(&PersistentSettings::SetPersistentSettingHelper,
                                 base::Unretained(this), key, std::move(value),
-                                std::move(closure)));
+                                std::move(closure), blocking));
 }
 
 void PersistentSettings::SetPersistentSettingHelper(
     const std::string& key, std::unique_ptr<base::Value> value,
-    base::OnceClosure closure) {
+    base::OnceClosure closure, bool blocking) {
   DCHECK_EQ(base::MessageLoop::current(), message_loop());
   if (validated_initial_settings_) {
     base::AutoLock auto_lock(pref_store_lock_);
-    writeable_pref_store()->SetValue(
-        kValidated, std::make_unique<base::Value>(false),
-        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    writeable_pref_store()->SetValue(
-        key, std::move(value), WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    writeable_pref_store()->CommitPendingWrite();
+    pref_store_->SetValue(kValidated, std::make_unique<base::Value>(false),
+                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+    pref_store_->SetValue(key, std::move(value),
+                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+    CommitPendingWrite(blocking);
   } else {
     LOG(ERROR) << "Cannot set persistent setting while unvalidated: " << key;
   }
@@ -220,24 +201,24 @@
 }
 
 void PersistentSettings::RemovePersistentSetting(const std::string& key,
-                                                 base::OnceClosure closure) {
+                                                 base::OnceClosure closure,
+                                                 bool blocking) {
   message_loop()->task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(&PersistentSettings::RemovePersistentSettingHelper,
-                     base::Unretained(this), key, std::move(closure)));
+                     base::Unretained(this), key, std::move(closure),
+                     blocking));
 }
 
 void PersistentSettings::RemovePersistentSettingHelper(
-    const std::string& key, base::OnceClosure closure) {
+    const std::string& key, base::OnceClosure closure, bool blocking) {
   DCHECK_EQ(base::MessageLoop::current(), message_loop());
   if (validated_initial_settings_) {
     base::AutoLock auto_lock(pref_store_lock_);
-    writeable_pref_store()->SetValue(
-        kValidated, std::make_unique<base::Value>(false),
-        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    writeable_pref_store()->RemoveValue(
-        key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    writeable_pref_store()->CommitPendingWrite();
+    pref_store_->SetValue(kValidated, std::make_unique<base::Value>(false),
+                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+    pref_store_->RemoveValue(key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+    CommitPendingWrite(blocking);
   } else {
     LOG(ERROR) << "Cannot remove persistent setting while unvalidated: " << key;
   }
@@ -257,12 +238,24 @@
   if (validated_initial_settings_) {
     starboard::SbFileDeleteRecursive(persistent_settings_file_.c_str(), true);
     base::AutoLock auto_lock(pref_store_lock_);
-    writeable_pref_store()->ReadPrefs();
+    pref_store_->ReadPrefs();
   } else {
     LOG(ERROR) << "Cannot delete persistent setting while unvalidated.";
   }
   std::move(closure).Run();
 }
 
+void PersistentSettings::CommitPendingWrite(bool blocking) {
+  if (blocking) {
+    base::WaitableEvent written;
+    pref_store_->CommitPendingWrite(
+        base::OnceClosure(),
+        base::BindOnce(&base::WaitableEvent::Signal, Unretained(&written)));
+    written.Wait();
+  } else {
+    pref_store_->CommitPendingWrite();
+  }
+}
+
 }  // namespace persistent_storage
 }  // namespace cobalt
diff --git a/cobalt/persistent_storage/persistent_settings.h b/cobalt/persistent_storage/persistent_settings.h
index 0cf789f..6c2c157 100644
--- a/cobalt/persistent_storage/persistent_settings.h
+++ b/cobalt/persistent_storage/persistent_settings.h
@@ -71,35 +71,34 @@
 
   void SetPersistentSetting(
       const std::string& key, std::unique_ptr<base::Value> value,
-      base::OnceClosure closure = std::move(base::DoNothing()));
+      base::OnceClosure closure = std::move(base::DoNothing()),
+      bool blocking = false);
 
   void RemovePersistentSetting(
       const std::string& key,
-      base::OnceClosure closure = std::move(base::DoNothing()));
+      base::OnceClosure closure = std::move(base::DoNothing()),
+      bool blocking = false);
 
   void DeletePersistentSettings(
       base::OnceClosure closure = std::move(base::DoNothing()));
 
  private:
   // Called by the constructor to initialize pref_store_ from
-  // the dedicated thread_ as a writeable JSONPrefStore.
-  void InitializeWriteablePrefStore();
+  // the dedicated thread_ as a JSONPrefStore.
+  void InitializePrefStore();
 
   void ValidatePersistentSettingsHelper();
 
   void SetPersistentSettingHelper(const std::string& key,
                                   std::unique_ptr<base::Value> value,
-                                  base::OnceClosure closure);
+                                  base::OnceClosure closure, bool blocking);
 
   void RemovePersistentSettingHelper(const std::string& key,
-                                     base::OnceClosure closure);
+                                     base::OnceClosure closure, bool blocking);
 
   void DeletePersistentSettingsHelper(base::OnceClosure closure);
 
-  scoped_refptr<PersistentPrefStore> writeable_pref_store() {
-    writeable_pref_store_initialized_.Wait();
-    return pref_store_;
-  }
+  void CommitPendingWrite(bool blocking);
 
   // Persistent settings file path.
   std::string persistent_settings_file_;
@@ -117,7 +116,7 @@
 
   // This event is used to signal when Initialize has been called and
   // pref_store_ mutations can now occur.
-  base::WaitableEvent writeable_pref_store_initialized_ = {
+  base::WaitableEvent pref_store_initialized_ = {
       base::WaitableEvent::ResetPolicy::MANUAL,
       base::WaitableEvent::InitialState::NOT_SIGNALED};
 
diff --git a/cobalt/persistent_storage/persistent_settings_test.cc b/cobalt/persistent_storage/persistent_settings_test.cc
index 3f88397..91b2bce 100644
--- a/cobalt/persistent_storage/persistent_settings_test.cc
+++ b/cobalt/persistent_storage/persistent_settings_test.cc
@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "cobalt/persistent_storage/persistent_settings.h"
+
 #include <utility>
 #include <vector>
 
@@ -20,9 +22,7 @@
 #include "base/callback_forward.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/scoped_task_environment.h"
-#include "base/threading/platform_thread.h"
 #include "base/values.h"
-#include "cobalt/persistent_storage/persistent_settings.h"
 #include "starboard/common/file.h"
 #include "starboard/common/log.h"
 #include "starboard/configuration_constants.h"
@@ -81,13 +81,13 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsInt("key", true));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(4.2), std::move(closure));
+      "key", std::make_unique<base::Value>(4.2), std::move(closure), true);
   test_done_.Wait();
 }
 
@@ -99,32 +99,32 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(true), std::move(closure));
+      "key", std::make_unique<base::Value>(true), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_FALSE(
+        EXPECT_FALSE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_FALSE(
+        EXPECT_FALSE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(false), std::move(closure));
+      "key", std::make_unique<base::Value>(false), std::move(closure), true);
 
   test_done_.Wait();
 }
@@ -143,13 +143,13 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ(8, persistent_settings->GetPersistentSettingAsInt("key", 8));
+        EXPECT_EQ(8, persistent_settings->GetPersistentSettingAsInt("key", 8));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(4.2), std::move(closure));
+      "key", std::make_unique<base::Value>(4.2), std::move(closure), true);
   test_done_.Wait();
 }
 
@@ -161,36 +161,36 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ(-1, persistent_settings->GetPersistentSettingAsInt("key", 8));
+        EXPECT_EQ(-1, persistent_settings->GetPersistentSettingAsInt("key", 8));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(-1), std::move(closure));
+      "key", std::make_unique<base::Value>(-1), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ(0, persistent_settings->GetPersistentSettingAsInt("key", 8));
+        EXPECT_EQ(0, persistent_settings->GetPersistentSettingAsInt("key", 8));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(0), std::move(closure));
+      "key", std::make_unique<base::Value>(0), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ(42, persistent_settings->GetPersistentSettingAsInt("key", 8));
+        EXPECT_EQ(42, persistent_settings->GetPersistentSettingAsInt("key", 8));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(42), std::move(closure));
+      "key", std::make_unique<base::Value>(42), std::move(closure), true);
   test_done_.Wait();
 }
 
@@ -214,13 +214,13 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ("hello", persistent_settings->GetPersistentSettingAsString(
+        EXPECT_EQ("hello", persistent_settings->GetPersistentSettingAsString(
                                "key", "hello"));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(4.2), std::move(closure));
+      "key", std::make_unique<base::Value>(4.2), std::move(closure), true);
   test_done_.Wait();
 }
 
@@ -232,21 +232,21 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ("", persistent_settings->GetPersistentSettingAsString(
+        EXPECT_EQ("", persistent_settings->GetPersistentSettingAsString(
                           "key", "hello"));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(""), std::move(closure));
+      "key", std::make_unique<base::Value>(""), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ(
+        EXPECT_EQ(
             "hello there",
             persistent_settings->GetPersistentSettingAsString("key", "hello"));
         test_done->Signal();
@@ -254,46 +254,47 @@
       persistent_settings.get(), &test_done_);
 
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>("hello there"), std::move(closure));
+      "key", std::make_unique<base::Value>("hello there"), std::move(closure),
+      true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ("42", persistent_settings->GetPersistentSettingAsString(
+        EXPECT_EQ("42", persistent_settings->GetPersistentSettingAsString(
                             "key", "hello"));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>("42"), std::move(closure));
+      "key", std::make_unique<base::Value>("42"), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ("\n", persistent_settings->GetPersistentSettingAsString(
+        EXPECT_EQ("\n", persistent_settings->GetPersistentSettingAsString(
                             "key", "hello"));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>("\n"), std::move(closure));
+      "key", std::make_unique<base::Value>("\n"), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_EQ("\\n", persistent_settings->GetPersistentSettingAsString(
+        EXPECT_EQ("\\n", persistent_settings->GetPersistentSettingAsString(
                              "key", "hello"));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>("\\n"), std::move(closure));
+      "key", std::make_unique<base::Value>("\\n"), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 }
@@ -307,10 +308,10 @@
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
         auto test_list = persistent_settings->GetPersistentSettingAsList("key");
-        ASSERT_FALSE(test_list.empty());
-        ASSERT_EQ(1, test_list.size());
-        ASSERT_TRUE(test_list[0].is_string());
-        ASSERT_EQ("hello", test_list[0].GetString());
+        EXPECT_FALSE(test_list.empty());
+        EXPECT_EQ(1, test_list.size());
+        EXPECT_TRUE(test_list[0].is_string());
+        EXPECT_EQ("hello", test_list[0].GetString());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
@@ -318,7 +319,7 @@
   std::vector<base::Value> list;
   list.emplace_back("hello");
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(list), std::move(closure));
+      "key", std::make_unique<base::Value>(list), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
@@ -326,19 +327,19 @@
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
         auto test_list = persistent_settings->GetPersistentSettingAsList("key");
-        ASSERT_FALSE(test_list.empty());
-        ASSERT_EQ(2, test_list.size());
-        ASSERT_TRUE(test_list[0].is_string());
-        ASSERT_EQ("hello", test_list[0].GetString());
-        ASSERT_TRUE(test_list[1].is_string());
-        ASSERT_EQ("there", test_list[1].GetString());
+        EXPECT_FALSE(test_list.empty());
+        EXPECT_EQ(2, test_list.size());
+        EXPECT_TRUE(test_list[0].is_string());
+        EXPECT_EQ("hello", test_list[0].GetString());
+        EXPECT_TRUE(test_list[1].is_string());
+        EXPECT_EQ("there", test_list[1].GetString());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   list.emplace_back("there");
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(list), std::move(closure));
+      "key", std::make_unique<base::Value>(list), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
@@ -346,21 +347,21 @@
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
         auto test_list = persistent_settings->GetPersistentSettingAsList("key");
-        ASSERT_FALSE(test_list.empty());
-        ASSERT_EQ(3, test_list.size());
-        ASSERT_TRUE(test_list[0].is_string());
-        ASSERT_EQ("hello", test_list[0].GetString());
-        ASSERT_TRUE(test_list[1].is_string());
-        ASSERT_EQ("there", test_list[1].GetString());
-        ASSERT_TRUE(test_list[2].is_int());
-        ASSERT_EQ(42, test_list[2].GetInt());
+        EXPECT_FALSE(test_list.empty());
+        EXPECT_EQ(3, test_list.size());
+        EXPECT_TRUE(test_list[0].is_string());
+        EXPECT_EQ("hello", test_list[0].GetString());
+        EXPECT_TRUE(test_list[1].is_string());
+        EXPECT_EQ("there", test_list[1].GetString());
+        EXPECT_TRUE(test_list[2].is_int());
+        EXPECT_EQ(42, test_list[2].GetInt());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   list.emplace_back(42);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(list), std::move(closure));
+      "key", std::make_unique<base::Value>(list), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 }
@@ -375,10 +376,10 @@
          base::WaitableEvent* test_done) {
         auto test_dict =
             persistent_settings->GetPersistentSettingAsDictionary("key");
-        ASSERT_FALSE(test_dict.empty());
-        ASSERT_EQ(1, test_dict.size());
-        ASSERT_TRUE(test_dict["key_string"]->is_string());
-        ASSERT_EQ("hello", test_dict["key_string"]->GetString());
+        EXPECT_FALSE(test_dict.empty());
+        EXPECT_EQ(1, test_dict.size());
+        EXPECT_TRUE(test_dict["key_string"]->is_string());
+        EXPECT_EQ("hello", test_dict["key_string"]->GetString());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
@@ -386,7 +387,7 @@
   base::flat_map<std::string, std::unique_ptr<base::Value>> dict;
   dict.try_emplace("key_string", std::make_unique<base::Value>("hello"));
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(dict), std::move(closure));
+      "key", std::make_unique<base::Value>(dict), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
@@ -395,19 +396,19 @@
          base::WaitableEvent* test_done) {
         auto test_dict =
             persistent_settings->GetPersistentSettingAsDictionary("key");
-        ASSERT_FALSE(test_dict.empty());
-        ASSERT_EQ(2, test_dict.size());
-        ASSERT_TRUE(test_dict["key_string"]->is_string());
-        ASSERT_EQ("hello", test_dict["key_string"]->GetString());
-        ASSERT_TRUE(test_dict["key_int"]->is_int());
-        ASSERT_EQ(42, test_dict["key_int"]->GetInt());
+        EXPECT_FALSE(test_dict.empty());
+        EXPECT_EQ(2, test_dict.size());
+        EXPECT_TRUE(test_dict["key_string"]->is_string());
+        EXPECT_EQ("hello", test_dict["key_string"]->GetString());
+        EXPECT_TRUE(test_dict["key_int"]->is_int());
+        EXPECT_EQ(42, test_dict["key_int"]->GetInt());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
 
   dict.try_emplace("key_int", std::make_unique<base::Value>(42));
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(dict), std::move(closure));
+      "key", std::make_unique<base::Value>(dict), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 }
@@ -425,10 +426,10 @@
          base::WaitableEvent* test_done) {
         auto test_dict = persistent_settings->GetPersistentSettingAsDictionary(
             "http://127.0.0.1:45019/");
-        ASSERT_FALSE(test_dict.empty());
-        ASSERT_EQ(1, test_dict.size());
-        ASSERT_TRUE(test_dict["http://127.0.0.1:45019/"]->is_string());
-        ASSERT_EQ("Dictionary URL Key Works!",
+        EXPECT_FALSE(test_dict.empty());
+        EXPECT_EQ(1, test_dict.size());
+        EXPECT_TRUE(test_dict["http://127.0.0.1:45019/"]->is_string());
+        EXPECT_EQ("Dictionary URL Key Works!",
                   test_dict["http://127.0.0.1:45019/"]->GetString());
         test_done->Signal();
       },
@@ -441,7 +442,7 @@
                    std::make_unique<base::Value>("Dictionary URL Key Works!"));
   persistent_settings->SetPersistentSetting("http://127.0.0.1:45019/",
                                             std::make_unique<base::Value>(dict),
-                                            std::move(closure));
+                                            std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
@@ -450,12 +451,12 @@
          base::WaitableEvent* test_done) {
         auto test_dict = persistent_settings->GetPersistentSettingAsDictionary(
             "http://127.0.0.1:45019/");
-        ASSERT_TRUE(test_dict.empty());
+        EXPECT_TRUE(test_dict.empty());
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->RemovePersistentSetting("http://127.0.0.1:45019/",
-                                               std::move(closure));
+                                               std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 }
@@ -471,29 +472,29 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(true), std::move(closure));
+      "key", std::make_unique<base::Value>(true), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_FALSE(
+        EXPECT_FALSE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
-  persistent_settings->RemovePersistentSetting("key", std::move(closure));
+  persistent_settings->RemovePersistentSetting("key", std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 }
@@ -509,24 +510,24 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(true), std::move(closure));
+      "key", std::make_unique<base::Value>(true), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_FALSE(
+        EXPECT_FALSE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
@@ -547,22 +548,18 @@
   base::OnceClosure closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(true), std::move(closure));
+      "key", std::make_unique<base::Value>(true), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
-  // Sleep for one second to allow for the previous persistent_setting's
-  // JsonPrefStore instance time to write to disk before creating a new
-  // persistent_settings and JsonPrefStore instance.
-  base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
   persistent_settings =
       std::make_unique<PersistentSettings>(kPersistentSettingsJson);
   ASSERT_TRUE(persistent_settings->GetPersistentSettingAsBool("key", true));
@@ -571,15 +568,15 @@
   closure = base::BindOnce(
       [](PersistentSettings* persistent_settings,
          base::WaitableEvent* test_done) {
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", true));
-        ASSERT_TRUE(
+        EXPECT_TRUE(
             persistent_settings->GetPersistentSettingAsBool("key", false));
         test_done->Signal();
       },
       persistent_settings.get(), &test_done_);
   persistent_settings->SetPersistentSetting(
-      "key", std::make_unique<base::Value>(false), std::move(closure));
+      "key", std::make_unique<base::Value>(false), std::move(closure), true);
   test_done_.Wait();
   test_done_.Reset();
 
diff --git a/cobalt/renderer/test/png_utils/BUILD.gn b/cobalt/renderer/test/png_utils/BUILD.gn
index 28e8ac1..2e8135e 100644
--- a/cobalt/renderer/test/png_utils/BUILD.gn
+++ b/cobalt/renderer/test/png_utils/BUILD.gn
@@ -40,15 +40,18 @@
 
   deps = [
     ":png_utils",
-    ":png_utils_copy_test_data",
     "//cobalt/base",
     "//cobalt/test:run_all_unittests",
     "//testing/gmock",
     "//testing/gtest",
   ]
+
+  data_deps = [ ":png_utils_copy_test_data" ]
 }
 
 copy("png_utils_copy_test_data") {
+  install_content = true
+
   sources = [
     "png_benchmark_image.png",
     "png_premultiplied_alpha_test_image.png",
diff --git a/cobalt/script/v8c/v8c_global_environment.cc b/cobalt/script/v8c/v8c_global_environment.cc
index 80a27d2..9ec5c07 100644
--- a/cobalt/script/v8c/v8c_global_environment.cc
+++ b/cobalt/script/v8c/v8c_global_environment.cc
@@ -97,8 +97,8 @@
   isolate_->SetData(kIsolateDataIndex, this);
   DCHECK(isolate_->GetData(kIsolateDataIndex) == this);
 
-  isolate_->SetAllowCodeGenerationFromStringsCallback(
-      AllowCodeGenerationFromStringsCallback);
+  isolate_->SetModifyCodeGenerationFromStringsCallback(
+      ModifyCodeGenerationFromStringsCallback);
 
   isolate_->SetAllowWasmCodeGenerationCallback(
       [](v8::Local<v8::Context> context, v8::Local<v8::String> source) {
@@ -371,8 +371,10 @@
 }
 
 // static
-bool V8cGlobalEnvironment::AllowCodeGenerationFromStringsCallback(
-    v8::Local<v8::Context> context, v8::Local<v8::String> source) {
+v8::ModifyCodeGenerationFromStringsResult
+V8cGlobalEnvironment::ModifyCodeGenerationFromStringsCallback(
+    v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+    bool is_code_like) {
   V8cGlobalEnvironment* global_environment =
       V8cGlobalEnvironment::GetFromIsolate(context->GetIsolate());
   DCHECK(global_environment);
@@ -385,7 +387,7 @@
   // WebAssembly callback has not been explicitly set, however we *have* set
   // one.
   DCHECK_EQ(context->IsCodeGenerationFromStringsAllowed(), false);
-  return context->IsCodeGenerationFromStringsAllowed();
+  return {context->IsCodeGenerationFromStringsAllowed(), {}};
 }
 
 // static
@@ -394,14 +396,14 @@
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   V8cGlobalEnvironment* global_environment =
       V8cGlobalEnvironment::GetFromIsolate(isolate);
-  if (isolate->GetEnteredContext().IsEmpty()) {
+  if (isolate->GetEnteredOrMicrotaskContext().IsEmpty()) {
     return;
   }
   if (message->ErrorLevel() != v8::Isolate::kMessageError) {
     return;
   }
 
-  v8::Local<v8::Context> context = isolate->GetEnteredContext();
+  v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
   ErrorReport error_report;
   error_report.message = *v8::String::Utf8Value(isolate, message->Get());
   error_report.filename =
diff --git a/cobalt/script/v8c/v8c_global_environment.h b/cobalt/script/v8c/v8c_global_environment.h
index 265c2e1..6996e62 100644
--- a/cobalt/script/v8c/v8c_global_environment.h
+++ b/cobalt/script/v8c/v8c_global_environment.h
@@ -151,8 +151,10 @@
     v8::Isolate* isolate_;
   };
 
-  static bool AllowCodeGenerationFromStringsCallback(
-      v8::Local<v8::Context> context, v8::Local<v8::String> source);
+  static v8::ModifyCodeGenerationFromStringsResult
+  ModifyCodeGenerationFromStringsCallback(v8::Local<v8::Context> context,
+                                          v8::Local<v8::Value> source,
+                                          bool is_code_like);
 
   static void MessageHandler(v8::Local<v8::Message> message,
                              v8::Local<v8::Value> data);
diff --git a/cobalt/site/docs/gen/cobalt/doc/cvals.md b/cobalt/site/docs/gen/cobalt/doc/cvals.md
index 752fc7f..665c6a1 100644
--- a/cobalt/site/docs/gen/cobalt/doc/cvals.md
+++ b/cobalt/site/docs/gen/cobalt/doc/cvals.md
@@ -79,7 +79,7 @@
 
 #### PublicCVals
 
-*   **Count.DOM.EventListeners** - The total number of EventListeners in
+*   **Count.WEB.EventListeners** - The total number of EventListeners in
     existence globally. This includes ones that are pending garbage collection.
 *   **Count.DOM.Nodes** - The total number of Nodes in existence globally. This
     includes ones that are pending garbage collection.
@@ -95,7 +95,7 @@
 
 #### DebugCVals
 
-*   **Count.DOM.ActiveJavaScriptEvents** - The number of JavaScript events that
+*   **Count.WEB.ActiveJavaScriptEvents** - The number of JavaScript events that
     are currently running.
 *   **Count.DOM.Attrs** - The total number of Attrs in existence globally. This
     includes ones that are pending garbage collection.
diff --git a/cobalt/site/docs/reference/starboard/configuration-public.md b/cobalt/site/docs/reference/starboard/configuration-public.md
index 285f90e..44659a2 100644
--- a/cobalt/site/docs/reference/starboard/configuration-public.md
+++ b/cobalt/site/docs/reference/starboard/configuration-public.md
@@ -50,7 +50,6 @@
 
 | Properties |
 | :--- |
-| **`SB_HAS_BILINEAR_FILTERING_SUPPORT`**<br><br>Indicates whether or not the given platform supports bilinear filtering. This can be checked to enable/disable renderer tests that verify that this is working properly.<br><br>The default value in the Stub implementation is `1` |
 | **`SB_HAS_NV12_TEXTURE_SUPPORT`**<br><br>Indicates whether or not the given platform supports rendering of NV12 textures. These textures typically originate from video decoders.<br><br>The default value in the Stub implementation is `0` |
 | **`SB_HAS_VIRTUAL_REALITY`**<br><br>The default value in the Stub implementation is `1` |
 
diff --git a/cobalt/site/docs/reference/starboard/modules/13/speech_recognizer.md b/cobalt/site/docs/reference/starboard/modules/13/speech_recognizer.md
deleted file mode 100644
index 2a40f19..0000000
--- a/cobalt/site/docs/reference/starboard/modules/13/speech_recognizer.md
+++ /dev/null
@@ -1,268 +0,0 @@
----
-layout: doc
-title: "Starboard Module Reference: speech_recognizer.h"
----
-
-Defines a streaming speech recognizer API. It provides access to the platform
-speech recognition service.
-
-Note that there can be only one speech recognizer. Attempting to create a second
-speech recognizer without destroying the first one will result in undefined
-behavior.
-
-`SbSpeechRecognizerCreate`, `SbSpeechRecognizerStart`, `SbSpeechRecognizerStop`,
-`SbSpeechRecognizerCancel` and `SbSpeechRecognizerDestroy` should be called from
-a single thread. Callbacks defined in `SbSpeechRecognizerHandler` will happen on
-another thread, so calls back into the SbSpeechRecognizer from the callback
-thread are disallowed.
-
-## Macros ##
-
-### kSbSpeechRecognizerInvalid ###
-
-Well-defined value for an invalid speech recognizer handle.
-
-## Enums ##
-
-### SbSpeechRecognizerError ###
-
-Indicates what has gone wrong with the recognition.
-
-#### Values ####
-
-*   `kSbNoSpeechError`
-
-    No speech was detected. Speech timed out.
-*   `kSbAborted`
-
-    Speech input was aborted somehow.
-*   `kSbAudioCaptureError`
-
-    Audio capture failed.
-*   `kSbNetworkError`
-
-    Some network communication that was required to complete the recognition
-    failed.
-*   `kSbNotAllowed`
-
-    The implementation is not allowing any speech input to occur for reasons of
-    security, privacy or user preference.
-*   `kSbServiceNotAllowed`
-
-    The implementation is not allowing the application requested speech service,
-    but would allow some speech service, to be used either because the
-    implementation doesn't support the selected one or because of reasons of
-    security, privacy or user preference.
-*   `kSbBadGrammar`
-
-    There was an error in the speech recognition grammar or semantic tags, or
-    the grammar format or semantic tag format is supported.
-*   `kSbLanguageNotSupported`
-
-    The language was not supported.
-
-## Typedefs ##
-
-### SbSpeechRecognizer ###
-
-An opaque handle to an implementation-private structure that represents a speech
-recognizer.
-
-#### Definition ####
-
-```
-typedef struct SbSpeechRecognizerPrivate* SbSpeechRecognizer
-```
-
-### SbSpeechRecognizerErrorFunction ###
-
-A function to notify that a speech recognition error occurred. `error`: The
-occurred speech recognition error.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerErrorFunction) (void *context, SbSpeechRecognizerError error)
-```
-
-### SbSpeechRecognizerResultsFunction ###
-
-A function to notify that the recognition results are ready. `results`: the list
-of recognition results. `results_size`: the number of `results`. `is_final`:
-indicates if the `results` is final.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerResultsFunction) (void *context, SbSpeechResult *results, int results_size, bool is_final)
-```
-
-### SbSpeechRecognizerSpeechDetectedFunction ###
-
-A function to notify that the user has started to speak or stops speaking.
-`detected`: true if the user has started to speak, and false if the user stops
-speaking.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerSpeechDetectedFunction) (void *context, bool detected)
-```
-
-## Structs ##
-
-### SbSpeechConfiguration ###
-
-#### Members ####
-
-*   `bool continuous`
-
-    When the continuous value is set to false, the implementation MUST return no
-    more than one final result in response to starting recognition. When the
-    continuous attribute is set to true, the implementation MUST return zero or
-    more final results representing multiple consecutive recognitions in
-    response to starting recognition. This attribute setting does not affect
-    interim results.
-*   `bool interim_results`
-
-    Controls whether interim results are returned. When set to true, interim
-    results SHOULD be returned. When set to false, interim results MUST NOT be
-    returned. This value setting does not affect final results.
-*   `int max_alternatives`
-
-    This sets the maximum number of SbSpeechResult in
-    `SbSpeechRecognizerOnResults` callback.
-
-### SbSpeechRecognizerHandler ###
-
-Allows receiving notifications from the device when recognition related events
-occur.
-
-The void* context is passed to every function.
-
-#### Members ####
-
-*   `SbSpeechRecognizerSpeechDetectedFunction on_speech_detected`
-
-    Function to notify the beginning/end of the speech.
-*   `SbSpeechRecognizerErrorFunction on_error`
-
-    Function to notify the speech error.
-*   `SbSpeechRecognizerResultsFunction on_results`
-
-    Function to notify that the recognition results are available.
-*   `void * context`
-
-    This is passed to handler functions as first argument.
-
-### SbSpeechResult ###
-
-The recognition response that is received from the recognizer.
-
-#### Members ####
-
-*   `char * transcript`
-
-    The raw words that the user spoke.
-*   `float confidence`
-
-    A numeric estimate between 0 and 1 of how confident the recognition system
-    is that the recognition is correct. A higher number means the system is more
-    confident. NaN represents an unavailable confidence score.
-
-## Functions ##
-
-### SbSpeechRecognizerCancel ###
-
-Cancels speech recognition. The speech recognizer stops listening to audio and
-does not return any information. When `SbSpeechRecognizerCancel` is called, the
-implementation MUST NOT collect additional audio, MUST NOT continue to listen to
-the user, and MUST stop recognizing. This is important for privacy reasons. If
-`SbSpeechRecognizerCancel` is called on a speech recognizer which is already
-stopped or cancelled, the implementation MUST ignore the call.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerCancel(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerCreate ###
-
-Creates a speech recognizer with a speech recognizer handler.
-
-If the system has a speech recognition service available, this function returns
-the newly created handle.
-
-If no speech recognition service is available on the device, this function
-returns `kSbSpeechRecognizerInvalid`.
-
-`SbSpeechRecognizerCreate` does not expect the passed SbSpeechRecognizerHandler
-structure to live after `SbSpeechRecognizerCreate` is called, so the
-implementation must copy the contents if necessary.
-
-#### Declaration ####
-
-```
-SbSpeechRecognizer SbSpeechRecognizerCreate(const SbSpeechRecognizerHandler *handler)
-```
-
-### SbSpeechRecognizerDestroy ###
-
-Destroys the given speech recognizer. If the speech recognizer is in the started
-state, it is first stopped and then destroyed.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerDestroy(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerIsSupported ###
-
-Returns whether the platform supports SbSpeechRecognizer.
-
-#### Declaration ####
-
-```
-bool SbSpeechRecognizerIsSupported()
-```
-
-### SbSpeechRecognizerIsValid ###
-
-Indicates whether the given speech recognizer is valid.
-
-#### Declaration ####
-
-```
-static bool SbSpeechRecognizerIsValid(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerStart ###
-
-Starts listening to audio and recognizing speech with the specified speech
-configuration. If `SbSpeechRecognizerStart` is called on an already started
-speech recognizer, the implementation MUST ignore the call and return false.
-
-Returns whether the speech recognizer is started successfully.
-
-#### Declaration ####
-
-```
-bool SbSpeechRecognizerStart(SbSpeechRecognizer recognizer, const SbSpeechConfiguration *configuration)
-```
-
-### SbSpeechRecognizerStop ###
-
-Stops listening to audio and returns a result using just the audio that it has
-already received. Once `SbSpeechRecognizerStop` is called, the implementation
-MUST NOT collect additional audio and MUST NOT continue to listen to the user.
-This is important for privacy reasons. If `SbSpeechRecognizerStop` is called on
-a speech recognizer which is already stopped or being stopped, the
-implementation MUST ignore the call.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerStop(SbSpeechRecognizer recognizer)
-```
diff --git a/cobalt/site/docs/reference/starboard/modules/14/speech_recognizer.md b/cobalt/site/docs/reference/starboard/modules/14/speech_recognizer.md
deleted file mode 100644
index 2a40f19..0000000
--- a/cobalt/site/docs/reference/starboard/modules/14/speech_recognizer.md
+++ /dev/null
@@ -1,268 +0,0 @@
----
-layout: doc
-title: "Starboard Module Reference: speech_recognizer.h"
----
-
-Defines a streaming speech recognizer API. It provides access to the platform
-speech recognition service.
-
-Note that there can be only one speech recognizer. Attempting to create a second
-speech recognizer without destroying the first one will result in undefined
-behavior.
-
-`SbSpeechRecognizerCreate`, `SbSpeechRecognizerStart`, `SbSpeechRecognizerStop`,
-`SbSpeechRecognizerCancel` and `SbSpeechRecognizerDestroy` should be called from
-a single thread. Callbacks defined in `SbSpeechRecognizerHandler` will happen on
-another thread, so calls back into the SbSpeechRecognizer from the callback
-thread are disallowed.
-
-## Macros ##
-
-### kSbSpeechRecognizerInvalid ###
-
-Well-defined value for an invalid speech recognizer handle.
-
-## Enums ##
-
-### SbSpeechRecognizerError ###
-
-Indicates what has gone wrong with the recognition.
-
-#### Values ####
-
-*   `kSbNoSpeechError`
-
-    No speech was detected. Speech timed out.
-*   `kSbAborted`
-
-    Speech input was aborted somehow.
-*   `kSbAudioCaptureError`
-
-    Audio capture failed.
-*   `kSbNetworkError`
-
-    Some network communication that was required to complete the recognition
-    failed.
-*   `kSbNotAllowed`
-
-    The implementation is not allowing any speech input to occur for reasons of
-    security, privacy or user preference.
-*   `kSbServiceNotAllowed`
-
-    The implementation is not allowing the application requested speech service,
-    but would allow some speech service, to be used either because the
-    implementation doesn't support the selected one or because of reasons of
-    security, privacy or user preference.
-*   `kSbBadGrammar`
-
-    There was an error in the speech recognition grammar or semantic tags, or
-    the grammar format or semantic tag format is supported.
-*   `kSbLanguageNotSupported`
-
-    The language was not supported.
-
-## Typedefs ##
-
-### SbSpeechRecognizer ###
-
-An opaque handle to an implementation-private structure that represents a speech
-recognizer.
-
-#### Definition ####
-
-```
-typedef struct SbSpeechRecognizerPrivate* SbSpeechRecognizer
-```
-
-### SbSpeechRecognizerErrorFunction ###
-
-A function to notify that a speech recognition error occurred. `error`: The
-occurred speech recognition error.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerErrorFunction) (void *context, SbSpeechRecognizerError error)
-```
-
-### SbSpeechRecognizerResultsFunction ###
-
-A function to notify that the recognition results are ready. `results`: the list
-of recognition results. `results_size`: the number of `results`. `is_final`:
-indicates if the `results` is final.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerResultsFunction) (void *context, SbSpeechResult *results, int results_size, bool is_final)
-```
-
-### SbSpeechRecognizerSpeechDetectedFunction ###
-
-A function to notify that the user has started to speak or stops speaking.
-`detected`: true if the user has started to speak, and false if the user stops
-speaking.
-
-#### Definition ####
-
-```
-typedef void(* SbSpeechRecognizerSpeechDetectedFunction) (void *context, bool detected)
-```
-
-## Structs ##
-
-### SbSpeechConfiguration ###
-
-#### Members ####
-
-*   `bool continuous`
-
-    When the continuous value is set to false, the implementation MUST return no
-    more than one final result in response to starting recognition. When the
-    continuous attribute is set to true, the implementation MUST return zero or
-    more final results representing multiple consecutive recognitions in
-    response to starting recognition. This attribute setting does not affect
-    interim results.
-*   `bool interim_results`
-
-    Controls whether interim results are returned. When set to true, interim
-    results SHOULD be returned. When set to false, interim results MUST NOT be
-    returned. This value setting does not affect final results.
-*   `int max_alternatives`
-
-    This sets the maximum number of SbSpeechResult in
-    `SbSpeechRecognizerOnResults` callback.
-
-### SbSpeechRecognizerHandler ###
-
-Allows receiving notifications from the device when recognition related events
-occur.
-
-The void* context is passed to every function.
-
-#### Members ####
-
-*   `SbSpeechRecognizerSpeechDetectedFunction on_speech_detected`
-
-    Function to notify the beginning/end of the speech.
-*   `SbSpeechRecognizerErrorFunction on_error`
-
-    Function to notify the speech error.
-*   `SbSpeechRecognizerResultsFunction on_results`
-
-    Function to notify that the recognition results are available.
-*   `void * context`
-
-    This is passed to handler functions as first argument.
-
-### SbSpeechResult ###
-
-The recognition response that is received from the recognizer.
-
-#### Members ####
-
-*   `char * transcript`
-
-    The raw words that the user spoke.
-*   `float confidence`
-
-    A numeric estimate between 0 and 1 of how confident the recognition system
-    is that the recognition is correct. A higher number means the system is more
-    confident. NaN represents an unavailable confidence score.
-
-## Functions ##
-
-### SbSpeechRecognizerCancel ###
-
-Cancels speech recognition. The speech recognizer stops listening to audio and
-does not return any information. When `SbSpeechRecognizerCancel` is called, the
-implementation MUST NOT collect additional audio, MUST NOT continue to listen to
-the user, and MUST stop recognizing. This is important for privacy reasons. If
-`SbSpeechRecognizerCancel` is called on a speech recognizer which is already
-stopped or cancelled, the implementation MUST ignore the call.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerCancel(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerCreate ###
-
-Creates a speech recognizer with a speech recognizer handler.
-
-If the system has a speech recognition service available, this function returns
-the newly created handle.
-
-If no speech recognition service is available on the device, this function
-returns `kSbSpeechRecognizerInvalid`.
-
-`SbSpeechRecognizerCreate` does not expect the passed SbSpeechRecognizerHandler
-structure to live after `SbSpeechRecognizerCreate` is called, so the
-implementation must copy the contents if necessary.
-
-#### Declaration ####
-
-```
-SbSpeechRecognizer SbSpeechRecognizerCreate(const SbSpeechRecognizerHandler *handler)
-```
-
-### SbSpeechRecognizerDestroy ###
-
-Destroys the given speech recognizer. If the speech recognizer is in the started
-state, it is first stopped and then destroyed.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerDestroy(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerIsSupported ###
-
-Returns whether the platform supports SbSpeechRecognizer.
-
-#### Declaration ####
-
-```
-bool SbSpeechRecognizerIsSupported()
-```
-
-### SbSpeechRecognizerIsValid ###
-
-Indicates whether the given speech recognizer is valid.
-
-#### Declaration ####
-
-```
-static bool SbSpeechRecognizerIsValid(SbSpeechRecognizer recognizer)
-```
-
-### SbSpeechRecognizerStart ###
-
-Starts listening to audio and recognizing speech with the specified speech
-configuration. If `SbSpeechRecognizerStart` is called on an already started
-speech recognizer, the implementation MUST ignore the call and return false.
-
-Returns whether the speech recognizer is started successfully.
-
-#### Declaration ####
-
-```
-bool SbSpeechRecognizerStart(SbSpeechRecognizer recognizer, const SbSpeechConfiguration *configuration)
-```
-
-### SbSpeechRecognizerStop ###
-
-Stops listening to audio and returns a result using just the audio that it has
-already received. Once `SbSpeechRecognizerStop` is called, the implementation
-MUST NOT collect additional audio and MUST NOT continue to listen to the user.
-This is important for privacy reasons. If `SbSpeechRecognizerStop` is called on
-a speech recognizer which is already stopped or being stopped, the
-implementation MUST ignore the call.
-
-#### Declaration ####
-
-```
-void SbSpeechRecognizerStop(SbSpeechRecognizer recognizer)
-```
diff --git a/cobalt/version.h b/cobalt/version.h
index b0b7424..6eb86c4 100644
--- a/cobalt/version.h
+++ b/cobalt/version.h
@@ -35,6 +35,6 @@
 //                  release is cut.
 //.
 
-#define COBALT_VERSION "24.lts.2"
+#define COBALT_VERSION "24.lts.3"
 
 #endif  // COBALT_VERSION_H_
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index b7c04f3..53e47b4 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -120,6 +120,11 @@
 
   if (use_cobalt_customizations) {
     sources -= [
+      # Allows removal of unused sampled_profile.proto, which adds ~200KB to
+      # the binary. See b/290819695.
+      "call_stack_profile_metrics_provider.cc",
+      "call_stack_profile_metrics_provider.h",
+
       # All code should be OS agnostic above SB.
       "drive_metrics_provider_android.cc",
       "drive_metrics_provider_ios.mm",
@@ -130,7 +135,7 @@
       # MemoryMapped files, etc).
       "file_metrics_provider.cc",
       "file_metrics_provider.h",
-       # All code should be OS agnostic above SB.
+      # All code should be OS agnostic above SB.
       "machine_id_provider_win.cc",
       "system_memory_stats_recorder_linux.cc",
       "system_memory_stats_recorder_win.cc",
@@ -279,7 +284,6 @@
       "//components/metrics/public/interfaces:single_sample_metrics_mojo_bindings",
     ]
   }
-  
 
   source_set("call_stack_profile_params") {
     public = [
@@ -380,7 +384,6 @@
   }
 }
 
-# TODO(b/283275474): Re-enable as many of these tests as possible.
 if (!use_cobalt_customizations) {
   source_set("unit_tests") {
     testonly = true
@@ -469,3 +472,34 @@
     ]
   }
 }
+
+if (use_cobalt_customizations) {
+  target(gtest_target_type, "components_metrics_tests") {
+    testonly = true
+    has_pedantic_warnings = true
+    sources = [
+      "histogram_encoder_unittest.cc",
+      "metrics_log_manager_unittest.cc",
+      "metrics_log_store_unittest.cc",
+      "metrics_log_unittest.cc",
+      "metrics_service_unittest.cc",
+      "metrics_state_manager_unittest.cc",
+      "reporting_service_unittest.cc",
+      "stability_metrics_helper_unittest.cc",
+      "stability_metrics_provider_unittest.cc",
+    ]
+
+    deps = [
+      ":metrics",
+      ":test_support",
+      "//base",
+      "//base/test:test_support",
+      "//cobalt/test:run_all_unittests",
+      "//components/prefs:test_support",
+      "//components/variations",
+      "//extensions/buildflags",
+      "//testing/gtest",
+      "//third_party/zlib/google:compression_utils",
+    ]
+  }
+}
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc
index 39ad9b1..8fe32c7 100644
--- a/components/metrics/metrics_log.cc
+++ b/components/metrics/metrics_log.cc
@@ -169,11 +169,8 @@
 #endif
 
   metrics::SystemProfileProto::OS* os = system_profile->mutable_os();
-// TODO(b/283256747): Remove when base::SysInfo is Starboardized.
-#if !defined(STARBOARD)
   os->set_name(base::SysInfo::OperatingSystemName());
   os->set_version(base::SysInfo::OperatingSystemVersion());
-#endif
 #if defined(OS_CHROMEOS)
   os->set_kernel_version(base::SysInfo::KernelVersion());
 #elif defined(OS_ANDROID)
@@ -332,7 +329,8 @@
         internal::kUserActionEventLimit,
         uma_proto_.user_action_event_size() - internal::kUserActionEventLimit);
   }
-
+// Omnibox proto removed for binary size reasons: b/290819695.
+#if !defined(USE_COBALT_CUSTOMIZATIONS)
   if (uma_proto_.omnibox_event_size() > internal::kOmniboxEventLimit) {
     UMA_HISTOGRAM_COUNTS_100000("UMA.TruncatedEvents.Omnibox",
                                 uma_proto_.omnibox_event_size());
@@ -340,6 +338,7 @@
         internal::kOmniboxEventLimit,
         uma_proto_.omnibox_event_size() - internal::kOmniboxEventLimit);
   }
+#endif
 }
 
 void MetricsLog::GetEncodedLog(std::string* encoded_log) {
diff --git a/components/metrics/metrics_log_unittest.cc b/components/metrics/metrics_log_unittest.cc
index 8af49a8..bddc0fc 100644
--- a/components/metrics/metrics_log_unittest.cc
+++ b/components/metrics/metrics_log_unittest.cc
@@ -142,7 +142,7 @@
 #endif
   metrics::SystemProfileProto::Hardware* hardware =
       system_profile->mutable_hardware();
-#if !defined(OS_IOS)
+#if !defined(OS_IOS) && !defined(STARBOARD)
   hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture());
 #endif
   hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB());
@@ -229,6 +229,8 @@
   EXPECT_EQ(12, histogram_proto.bucket(4).max());
 }
 
+// TODO(b/283255893): Remove when base::CPU is Starboardized.
+#if !defined(STARBOARD)
 TEST_F(MetricsLogTest, RecordEnvironment) {
   TestMetricsServiceClient client;
   TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client);
@@ -238,6 +240,7 @@
   // Check that the system profile on the log has the correct values set.
   CheckSystemProfile(log.system_profile());
 }
+#endif
 
 TEST_F(MetricsLogTest, RecordEnvironmentEnableDefault) {
   TestMetricsServiceClient client;
@@ -343,6 +346,8 @@
     log.RecordUserAction("BasicAction");
     EXPECT_EQ(i + 1, log.uma_proto().user_action_event_size());
   }
+// Omnibox proto removed for binary size reasons: b/290819695.
+#if !defined(USE_COBALT_CUSTOMIZATIONS)
   for (int i = 0; i < internal::kOmniboxEventLimit * 2; ++i) {
     // Add an empty omnibox event. Not fully realistic since these are normally
     // supplied by a metrics provider.
@@ -355,6 +360,7 @@
   EXPECT_EQ(internal::kUserActionEventLimit,
             log.uma_proto().user_action_event_size());
   EXPECT_EQ(internal::kOmniboxEventLimit, log.uma_proto().omnibox_event_size());
+#endif
 }
 
 }  // namespace metrics
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc
index 4350238..f10b79a 100644
--- a/components/metrics/metrics_service_unittest.cc
+++ b/components/metrics/metrics_service_unittest.cc
@@ -244,7 +244,10 @@
   EXPECT_TRUE(uma_log.has_session_id());
   EXPECT_TRUE(uma_log.has_system_profile());
   EXPECT_EQ(0, uma_log.user_action_event_size());
+// Omnibox proto removed for binary size reasons: b/290819695.
+#if !defined(USE_COBALT_CUSTOMIZATIONS)
   EXPECT_EQ(0, uma_log.omnibox_event_size());
+#endif
   EXPECT_EQ(0, uma_log.perf_data_size());
   CheckForNonStabilityHistograms(uma_log);
 
@@ -311,7 +314,10 @@
   EXPECT_TRUE(uma_log.has_session_id());
   EXPECT_TRUE(uma_log.has_system_profile());
   EXPECT_EQ(0, uma_log.user_action_event_size());
+// Omnibox proto removed for binary size reasons: b/290819695.
+#if !defined(USE_COBALT_CUSTOMIZATIONS)
   EXPECT_EQ(0, uma_log.omnibox_event_size());
+#endif
   EXPECT_EQ(0, uma_log.perf_data_size());
   CheckForNonStabilityHistograms(uma_log);
 
diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
index 3b89398..28772bf 100644
--- a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
+++ b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
@@ -38,6 +38,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Locale;
+import java.util.Optional;
 
 /** A wrapper of the MediaCodec class. */
 @SuppressWarnings("unused")
@@ -82,7 +83,6 @@
   private boolean mFlushed;
   private long mLastPresentationTimeUs;
   private final String mMime;
-  private boolean mAdaptivePlaybackSupported;
   private double mPlaybackRate = 1.0;
   private int mFps = 30;
 
@@ -269,6 +269,7 @@
     private int mStatus;
     // May be null if mStatus is not MEDIA_CODEC_OK.
     private MediaFormat mFormat;
+    private Optional<Boolean> mFormatHasCropValues = Optional.empty();
 
     @SuppressWarnings("unused")
     @UsedByNative
@@ -277,18 +278,16 @@
       mFormat = null;
     }
 
-    @SuppressWarnings("unused")
-    @UsedByNative
-    private GetOutputFormatResult(int status, MediaFormat format) {
-      mStatus = status;
-      mFormat = format;
-    }
-
     private boolean formatHasCropValues() {
-      return mFormat.containsKey(KEY_CROP_RIGHT)
-          && mFormat.containsKey(KEY_CROP_LEFT)
-          && mFormat.containsKey(KEY_CROP_BOTTOM)
-          && mFormat.containsKey(KEY_CROP_TOP);
+      if (!mFormatHasCropValues.isPresent()) {
+        boolean hasCropValues =
+            mFormat.containsKey(KEY_CROP_RIGHT)
+                && mFormat.containsKey(KEY_CROP_LEFT)
+                && mFormat.containsKey(KEY_CROP_BOTTOM)
+                && mFormat.containsKey(KEY_CROP_TOP);
+        mFormatHasCropValues = Optional.of(hasCropValues);
+      }
+      return mFormatHasCropValues.get();
     }
 
     @SuppressWarnings("unused")
@@ -299,18 +298,38 @@
 
     @SuppressWarnings("unused")
     @UsedByNative
-    private int width() {
-      return formatHasCropValues()
-          ? mFormat.getInteger(KEY_CROP_RIGHT) - mFormat.getInteger(KEY_CROP_LEFT) + 1
-          : mFormat.getInteger(MediaFormat.KEY_WIDTH);
+    private int textureWidth() {
+      return mFormat.getInteger(MediaFormat.KEY_WIDTH);
     }
 
     @SuppressWarnings("unused")
     @UsedByNative
-    private int height() {
-      return formatHasCropValues()
-          ? mFormat.getInteger(KEY_CROP_BOTTOM) - mFormat.getInteger(KEY_CROP_TOP) + 1
-          : mFormat.getInteger(MediaFormat.KEY_HEIGHT);
+    private int textureHeight() {
+      return mFormat.getInteger(MediaFormat.KEY_HEIGHT);
+    }
+
+    @SuppressWarnings("unused")
+    @UsedByNative
+    private int cropLeft() {
+      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_LEFT) : -1;
+    }
+
+    @SuppressWarnings("unused")
+    @UsedByNative
+    private int cropTop() {
+      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_TOP) : -1;
+    }
+
+    @SuppressWarnings("unused")
+    @UsedByNative
+    private int cropRight() {
+      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_RIGHT) : -1;
+    }
+
+    @SuppressWarnings("unused")
+    @UsedByNative
+    private int cropBottom() {
+      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_BOTTOM) : -1;
     }
 
     @SuppressWarnings("unused")
@@ -427,7 +446,6 @@
       long nativeMediaCodecBridge,
       MediaCodec mediaCodec,
       String mime,
-      boolean adaptivePlaybackSupported,
       BitrateAdjustmentTypes bitrateAdjustmentType,
       int tunnelModeAudioSessionId) {
     if (mediaCodec == null) {
@@ -438,7 +456,6 @@
     mMime = mime; // TODO: Delete the unused mMime field
     mLastPresentationTimeUs = 0;
     mFlushed = true;
-    mAdaptivePlaybackSupported = adaptivePlaybackSupported;
     mBitrateAdjustmentType = bitrateAdjustmentType;
     mCallback =
         new MediaCodec.Callback() {
@@ -552,12 +569,7 @@
     }
     MediaCodecBridge bridge =
         new MediaCodecBridge(
-            nativeMediaCodecBridge,
-            mediaCodec,
-            mime,
-            true,
-            BitrateAdjustmentTypes.NO_ADJUSTMENT,
-            -1);
+            nativeMediaCodecBridge, mediaCodec, mime, BitrateAdjustmentTypes.NO_ADJUSTMENT, -1);
 
     MediaFormat mediaFormat = createAudioFormat(mime, sampleRate, channelCount);
 
@@ -591,8 +603,10 @@
       long nativeMediaCodecBridge,
       String mime,
       String decoderName,
-      int width,
-      int height,
+      // `widthHint` and `heightHint` are used to create the Android video format, which don't have
+      // to be directly related to the resolution of the video.
+      int widthHint,
+      int heightHint,
       int fps,
       int maxWidth,
       int maxHeight,
@@ -652,10 +666,10 @@
             nativeMediaCodecBridge,
             mediaCodec,
             mime,
-            true,
             BitrateAdjustmentTypes.NO_ADJUSTMENT,
             tunnelModeAudioSessionId);
-    MediaFormat mediaFormat = createVideoDecoderFormat(mime, width, height, videoCapabilities);
+    MediaFormat mediaFormat =
+        createVideoDecoderFormat(mime, widthHint, heightHint, videoCapabilities);
 
     boolean shouldConfigureHdr =
         colorInfo != null && MediaCodecUtil.isHdrCapableVideoDecoder(mime, codecCapabilities);
@@ -759,14 +773,7 @@
     }
 
     if (!bridge.configureVideo(
-        mediaFormat,
-        surface,
-        crypto,
-        0,
-        true,
-        maxWidth,
-        maxHeight,
-        outCreateMediaCodecBridgeResult)) {
+        mediaFormat, surface, crypto, 0, maxWidth, maxHeight, outCreateMediaCodecBridgeResult)) {
       Log.e(TAG, "Failed to configure video codec.");
       bridge.release();
       // outCreateMediaCodecBridgeResult.mErrorMessage is set inside configureVideo() on error.
@@ -853,7 +860,7 @@
     try {
       mFlushed = true;
       mMediaCodec.flush();
-    } catch (IllegalStateException e) {
+    } catch (Exception e) {
       Log.e(TAG, "Failed to flush MediaCodec", e);
       return MEDIA_CODEC_ERROR;
     }
@@ -1019,6 +1026,9 @@
           "Failed to queue secure input buffer, CryptoException with error code "
               + e.getErrorCode());
       return MEDIA_CODEC_ERROR;
+    } catch (IllegalArgumentException e) {
+      Log.e(TAG, "Failed to queue secure input buffer, IllegalArgumentException " + e);
+      return MEDIA_CODEC_ERROR;
     } catch (IllegalStateException e) {
       Log.e(TAG, "Failed to queue secure input buffer, IllegalStateException " + e);
       return MEDIA_CODEC_ERROR;
@@ -1055,37 +1065,25 @@
       Surface surface,
       MediaCrypto crypto,
       int flags,
-      boolean allowAdaptivePlayback,
       int maxSupportedWidth,
       int maxSupportedHeight,
       CreateMediaCodecBridgeResult outCreateMediaCodecBridgeResult) {
     try {
-      // If adaptive playback is turned off by request, then treat it as
-      // not supported.  Note that configureVideo is only called once
-      // during creation, else this would prevent re-enabling adaptive
-      // playback later.
-      if (!allowAdaptivePlayback) {
-        mAdaptivePlaybackSupported = false;
+      // Since we haven't passed the properties of the stream we're playing down to this level, from
+      // our perspective, we could potentially adapt up to 8k at any point. We thus request 8k
+      // buffers up front, unless the decoder claims to not be able to do 8k, in which case we're
+      // ok, since we would've rejected a 8k stream when canPlayType was called, and then use those
+      // decoder values instead. We only support 8k for API level 29 and above.
+      if (Build.VERSION.SDK_INT > 28) {
+        format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(7680, maxSupportedWidth));
+        format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(4320, maxSupportedHeight));
+      } else {
+        // Android 5.0/5.1 seems not support 8K. Fallback to 4K until we get a
+        // better way to get maximum supported resolution.
+        format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(3840, maxSupportedWidth));
+        format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(2160, maxSupportedHeight));
       }
 
-      if (mAdaptivePlaybackSupported) {
-        // Since we haven't passed the properties of the stream we're playing
-        // down to this level, from our perspective, we could potentially
-        // adapt up to 8k at any point. We thus request 8k buffers up front,
-        // unless the decoder claims to not be able to do 8k, in which case
-        // we're ok, since we would've rejected a 8k stream when canPlayType
-        // was called, and then use those decoder values instead. We only
-        // support 8k for API level 29 and above.
-        if (Build.VERSION.SDK_INT > 28) {
-          format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(7680, maxSupportedWidth));
-          format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(4320, maxSupportedHeight));
-        } else {
-          // Android 5.0/5.1 seems not support 8K. Fallback to 4K until we get a
-          // better way to get maximum supported resolution.
-          format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(3840, maxSupportedWidth));
-          format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(2160, maxSupportedHeight));
-        }
-      }
       maybeSetMaxInputSize(format);
       mMediaCodec.configure(format, surface, crypto, flags);
       mFrameRateEstimator = new FrameRateEstimator();
@@ -1115,11 +1113,11 @@
   }
 
   private static MediaFormat createVideoDecoderFormat(
-      String mime, int width, int height, VideoCapabilities videoCapabilities) {
+      String mime, int widthHint, int heightHint, VideoCapabilities videoCapabilities) {
     return MediaFormat.createVideoFormat(
         mime,
-        alignDimension(width, videoCapabilities.getWidthAlignment()),
-        alignDimension(height, videoCapabilities.getHeightAlignment()));
+        alignDimension(widthHint, videoCapabilities.getWidthAlignment()),
+        alignDimension(heightHint, videoCapabilities.getHeightAlignment()));
   }
 
   private static int alignDimension(int size, int alignment) {
@@ -1145,11 +1143,11 @@
       return;
     }
     int maxHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
-    if (mAdaptivePlaybackSupported && format.containsKey(MediaFormat.KEY_MAX_HEIGHT)) {
+    if (format.containsKey(MediaFormat.KEY_MAX_HEIGHT)) {
       maxHeight = Math.max(maxHeight, format.getInteger(MediaFormat.KEY_MAX_HEIGHT));
     }
     int maxWidth = format.getInteger(MediaFormat.KEY_WIDTH);
-    if (mAdaptivePlaybackSupported && format.containsKey(MediaFormat.KEY_MAX_WIDTH)) {
+    if (format.containsKey(MediaFormat.KEY_MAX_WIDTH)) {
       maxWidth = Math.max(maxHeight, format.getInteger(MediaFormat.KEY_MAX_WIDTH));
     }
     int maxPixels;
@@ -1198,14 +1196,6 @@
 
   @SuppressWarnings("unused")
   @UsedByNative
-  private boolean isAdaptivePlaybackSupported(int width, int height) {
-    // If media codec has adaptive playback supported, then the max sizes
-    // used during creation are only hints.
-    return mAdaptivePlaybackSupported;
-  }
-
-  @SuppressWarnings("unused")
-  @UsedByNative
   private static void setCodecSpecificData(MediaFormat format, int index, byte[] bytes) {
     // Codec Specific Data is set in the MediaFormat as ByteBuffer entries with keys csd-0,
     // csd-1, and so on. See: http://developer.android.com/reference/android/media/MediaCodec.html
diff --git a/starboard/android/shared/BUILD.gn b/starboard/android/shared/BUILD.gn
index 17d91c7..b07982a 100644
--- a/starboard/android/shared/BUILD.gn
+++ b/starboard/android/shared/BUILD.gn
@@ -476,8 +476,11 @@
 
   sources = media_tests_sources + player_tests_sources + [
               "//starboard/common/test_main.cc",
+              "//starboard/shared/starboard/drm/drm_test_helpers.cc",
+              "//starboard/shared/starboard/drm/drm_test_helpers.h",
               "jni_env_ext_test.cc",
               "model_year_test.cc",
+              "player_get_preferred_output_mode_test.cc",
             ]
 
   configs += [ "//starboard/build/config:starboard_implementation" ]
diff --git a/starboard/android/shared/audio_renderer_passthrough.cc b/starboard/android/shared/audio_renderer_passthrough.cc
index c43fac3..610baaa 100644
--- a/starboard/android/shared/audio_renderer_passthrough.cc
+++ b/starboard/android/shared/audio_renderer_passthrough.cc
@@ -282,6 +282,7 @@
   stop_called_ = false;
   playback_head_position_when_stopped_ = 0;
   stopped_at_ = 0;
+  first_audio_timestamp_ = -1;
   if (!seek_to_time_set) {
     seek_to_time_ = seek_to_time;
   }
@@ -312,9 +313,17 @@
     return seek_to_time_;
   }
 
+  SbTime audio_start_time;
+  if (first_audio_timestamp_ > -1) {
+    audio_start_time = first_audio_timestamp_;
+  } else {
+    audio_start_time = seek_to_time_;
+  }
+
+  SbTime playback_time;
   if (stop_called_) {
     // When AudioTrackBridge::Stop() is called, the playback will continue until
-    // all the frames written are played, as the AudioTrack in created in
+    // all the frames written are played, as the AudioTrack is created in
     // MODE_STREAM.
     auto now = SbTimeGetMonotonicNow();
     SB_DCHECK(now >= stopped_at_);
@@ -324,8 +333,10 @@
     int64_t total_frames_played =
         frames_played + playback_head_position_when_stopped_;
     total_frames_played = std::min(total_frames_played, total_frames_written_);
-    return seek_to_time_ + total_frames_played * kSbTimeSecond /
+    playback_time =
+        audio_start_time + total_frames_played * kSbTimeSecond /
                                audio_stream_info_.samples_per_second;
+    return std::max(playback_time, seek_to_time_);
   }
 
   SbTime updated_at;
@@ -334,14 +345,13 @@
   if (playback_head_position <= 0) {
     // The playback is warming up, don't adjust the media time by the monotonic
     // system time.
-    return seek_to_time_;
+    return std::max(audio_start_time, seek_to_time_);
   }
 
   // TODO: This may cause time regression, because the unadjusted time will be
   //       returned on pause, after an adjusted time has been returned.
-  SbTime playback_time =
-      seek_to_time_ + playback_head_position * kSbTimeSecond /
-                          audio_stream_info_.samples_per_second;
+  playback_time = audio_start_time + playback_head_position * kSbTimeSecond /
+                                         audio_stream_info_.samples_per_second;
 
   // When underlying AudioTrack is paused, we use returned playback time
   // directly. Note that we should not use |paused_| or |playback_rate_| here.
@@ -352,7 +362,7 @@
   // before calling AudioTrack.Play(), the returned playback time and last frame
   // consumed time would be the same as at when we pause the video.
   if (audio_track_paused_) {
-    return playback_time;
+    return std::max(playback_time, seek_to_time_);
   }
 
   // TODO: Cap this to the maximum frames written to the AudioTrack.
@@ -366,7 +376,7 @@
 
   playback_time += std::max<SbTime>(now - updated_at, 0);
 
-  return playback_time;
+  return std::max(playback_time, seek_to_time_);
 }
 
 void AudioRendererPassthrough::CreateAudioTrackAndStartProcessing() {
@@ -542,6 +552,11 @@
         audio_track_bridge_->PauseAndFlush();
         return;
       }
+
+      if (first_audio_timestamp_ < 0) {
+        first_audio_timestamp_ = sync_time;
+      }
+
       decoded_audio_writing_offset_ += samples_written;
 
       if (decoded_audio_writing_offset_ ==
diff --git a/starboard/android/shared/audio_renderer_passthrough.h b/starboard/android/shared/audio_renderer_passthrough.h
index d4063df..7d9a1a3 100644
--- a/starboard/android/shared/audio_renderer_passthrough.h
+++ b/starboard/android/shared/audio_renderer_passthrough.h
@@ -130,6 +130,7 @@
   int64_t playback_head_position_when_stopped_ = 0;
   SbTimeMonotonic stopped_at_ = 0;
   SbTime seek_to_time_ = 0;
+  SbTime first_audio_timestamp_ = -1;
   double volume_ = 1.0;
   bool paused_ = true;
   double playback_rate_ = 1.0;
diff --git a/starboard/android/shared/media_codec_bridge.cc b/starboard/android/shared/media_codec_bridge.cc
index 298ea0c..fe97038 100644
--- a/starboard/android/shared/media_codec_bridge.cc
+++ b/starboard/android/shared/media_codec_bridge.cc
@@ -215,8 +215,8 @@
 // static
 scoped_ptr<MediaCodecBridge> MediaCodecBridge::CreateVideoMediaCodecBridge(
     SbMediaVideoCodec video_codec,
-    int width,
-    int height,
+    int width_hint,
+    int height_hint,
     int fps,
     optional<int> max_width,
     optional<int> max_height,
@@ -322,9 +322,10 @@
       "Ldev/cobalt/media/MediaCodecBridge$CreateMediaCodecBridgeResult;)"
       "V",
       reinterpret_cast<jlong>(native_media_codec_bridge.get()), j_mime.Get(),
-      j_decoder_name.Get(), width, height, fps, max_width.value_or(-1),
-      max_height.value_or(-1), j_surface, j_media_crypto, j_color_info.Get(),
-      tunnel_mode_audio_session_id, j_create_media_codec_bridge_result.Get());
+      j_decoder_name.Get(), width_hint, height_hint, fps,
+      max_width.value_or(-1), max_height.value_or(-1), j_surface,
+      j_media_crypto, j_color_info.Get(), tunnel_mode_audio_session_id,
+      j_create_media_codec_bridge_result.Get());
 
   jobject j_media_codec_bridge = env->CallObjectMethodOrAbort(
       j_create_media_codec_bridge_result.Get(), "mediaCodecBridge",
@@ -451,16 +452,25 @@
                                                 "()I");
 }
 
-SurfaceDimensions MediaCodecBridge::GetOutputDimensions() {
+FrameSize MediaCodecBridge::GetOutputSize() {
   JniEnvExt* env = JniEnvExt::Get();
   env->CallVoidMethodOrAbort(
       j_media_codec_bridge_, "getOutputFormat",
       "(Ldev/cobalt/media/MediaCodecBridge$GetOutputFormatResult;)V",
       j_reused_get_output_format_result_);
-  return {env->CallIntMethodOrAbort(j_reused_get_output_format_result_, "width",
-                                    "()I"),
-          env->CallIntMethodOrAbort(j_reused_get_output_format_result_,
-                                    "height", "()I")};
+
+  auto call_int_method = [env, this](const char* name) {
+    return env->CallIntMethodOrAbort(j_reused_get_output_format_result_, name,
+                                     "()I");
+  };
+
+  FrameSize size = {
+      call_int_method("textureWidth"), call_int_method("textureHeight"),
+      call_int_method("cropLeft"),     call_int_method("cropTop"),
+      call_int_method("cropRight"),    call_int_method("cropBottom")};
+
+  size.DCheckValid();
+  return size;
 }
 
 AudioOutputFormatResult MediaCodecBridge::GetAudioOutputFormat() {
diff --git a/starboard/android/shared/media_codec_bridge.h b/starboard/android/shared/media_codec_bridge.h
index 1490b75..bf395d5 100644
--- a/starboard/android/shared/media_codec_bridge.h
+++ b/starboard/android/shared/media_codec_bridge.h
@@ -63,9 +63,53 @@
   jint num_bytes;
 };
 
-struct SurfaceDimensions {
-  jint width;
-  jint height;
+struct FrameSize {
+  jint texture_width;
+  jint texture_height;
+
+  // Crop values can be set to -1 when they are not provided by the platform
+  jint crop_left = -1;
+  jint crop_top = -1;
+  jint crop_right = -1;
+  jint crop_bottom = -1;
+
+  bool has_crop_values() const {
+    return crop_left >= 0 && crop_top >= 0 && crop_right >= 0 &&
+           crop_bottom >= 0;
+  }
+
+  jint display_width() const {
+    if (has_crop_values()) {
+      return crop_right - crop_left + 1;
+    }
+
+    return texture_width;
+  }
+
+  jint display_height() const {
+    if (has_crop_values()) {
+      return crop_bottom - crop_top + 1;
+    }
+
+    return texture_height;
+  }
+
+  void DCheckValid() const {
+    SB_DCHECK(texture_width >= 0) << texture_width;
+    SB_DCHECK(texture_height >= 0) << texture_height;
+
+    if (crop_left >= 0 || crop_top >= 0 || crop_right >= 0 ||
+        crop_bottom >= 0) {
+      // If there is at least one crop value set, all of them should be set.
+      SB_DCHECK(crop_left >= 0) << crop_left;
+      SB_DCHECK(crop_top >= 0) << crop_top;
+      SB_DCHECK(crop_right >= 0) << crop_right;
+      SB_DCHECK(crop_bottom >= 0) << crop_bottom;
+      SB_DCHECK(has_crop_values());
+      SB_DCHECK(display_width() >= 0) << display_width();
+      SB_DCHECK(display_height() >= 0) << display_height();
+    }
+  }
 };
 
 struct AudioOutputFormatResult {
@@ -113,8 +157,11 @@
   // them without the other), which will be checked in the function.
   static scoped_ptr<MediaCodecBridge> CreateVideoMediaCodecBridge(
       SbMediaVideoCodec video_codec,
-      int width,
-      int height,
+      // `width_hint` and `height_hint` are used to create the Android video
+      // format, which don't have to be directly related to the resolution of
+      // the video.
+      int width_hint,
+      int height_hint,
       int fps,
       optional<int> max_width,
       optional<int> max_height,
@@ -152,7 +199,7 @@
 
   void SetPlaybackRate(double playback_rate);
   jint Flush();
-  SurfaceDimensions GetOutputDimensions();
+  FrameSize GetOutputSize();
   AudioOutputFormatResult GetAudioOutputFormat();
 
   void OnMediaCodecError(bool is_recoverable,
diff --git a/starboard/android/shared/media_decoder.cc b/starboard/android/shared/media_decoder.cc
index a44acf8..721680e 100644
--- a/starboard/android/shared/media_decoder.cc
+++ b/starboard/android/shared/media_decoder.cc
@@ -60,7 +60,7 @@
     case MEDIA_CODEC_ERROR:
       return "MEDIA_CODEC_ERROR";
     default:
-      SB_NOTREACHED();
+      SB_NOTREACHED() << "Unknown status value: " << status;
       return "MEDIA_CODEC_ERROR_UNKNOWN";
   }
 }
@@ -103,8 +103,8 @@
 
 MediaDecoder::MediaDecoder(Host* host,
                            SbMediaVideoCodec video_codec,
-                           int width,
-                           int height,
+                           int width_hint,
+                           int height_hint,
                            optional<int> max_width,
                            optional<int> max_height,
                            int fps,
@@ -130,7 +130,7 @@
       drm_system_ && drm_system_->require_secured_decoder();
   SB_DCHECK(!drm_system_ || j_media_crypto);
   media_codec_bridge_ = MediaCodecBridge::CreateVideoMediaCodecBridge(
-      video_codec, width, height, fps, max_width, max_height, this,
+      video_codec, width_hint, height_hint, fps, max_width, max_height, this,
       j_output_surface, j_media_crypto, color_metadata, require_secured_decoder,
       require_software_codec, tunnel_mode_audio_session_id,
       force_big_endian_hdr_metadata, force_improved_support_check,
diff --git a/starboard/android/shared/media_decoder.h b/starboard/android/shared/media_decoder.h
index 350e611..7c7a2eb 100644
--- a/starboard/android/shared/media_decoder.h
+++ b/starboard/android/shared/media_decoder.h
@@ -82,8 +82,11 @@
                SbDrmSystem drm_system);
   MediaDecoder(Host* host,
                SbMediaVideoCodec video_codec,
-               int width,
-               int height,
+               // `width_hint` and `height_hint` are used to create the Android
+               // video format, which don't have to be directly related to the
+               // resolution of the video.
+               int width_hint,
+               int height_hint,
                optional<int> max_width,
                optional<int> max_height,
                int fps,
diff --git a/starboard/android/shared/player_components_factory.h b/starboard/android/shared/player_components_factory.h
index eb85c45..18db0ba 100644
--- a/starboard/android/shared/player_components_factory.h
+++ b/starboard/android/shared/player_components_factory.h
@@ -515,8 +515,8 @@
     }
 
     scoped_ptr<VideoDecoder> video_decoder(new VideoDecoder(
-        creation_parameters.video_codec(), creation_parameters.drm_system(),
-        creation_parameters.output_mode(),
+        creation_parameters.video_stream_info(),
+        creation_parameters.drm_system(), creation_parameters.output_mode(),
         creation_parameters.decode_target_graphics_context_provider(),
         creation_parameters.max_video_capabilities(),
         tunnel_mode_audio_session_id, force_secure_pipeline_under_tunnel_mode,
diff --git a/starboard/android/shared/player_get_preferred_output_mode.cc b/starboard/android/shared/player_get_preferred_output_mode.cc
index 4639159..c7485e3 100644
--- a/starboard/android/shared/player_get_preferred_output_mode.cc
+++ b/starboard/android/shared/player_get_preferred_output_mode.cc
@@ -17,6 +17,7 @@
 #include <algorithm>
 
 #include "starboard/configuration.h"
+#include "starboard/shared/starboard/media/media_util.h"
 #include "starboard/shared/starboard/player/filter/player_components.h"
 #include "starboard/string.h"
 
@@ -64,35 +65,49 @@
   auto drm_system = creation_param->drm_system;
   auto max_video_capabilities = video_stream_info.max_video_capabilities;
 
-  // Sub players must use decode-to-texture on Android.
+  bool is_sdr = true;
+  if (codec != kSbMediaVideoCodecNone) {
+    const auto& color_metadata = video_stream_info.color_metadata;
+    is_sdr = starboard::shared::starboard::media::IsSDRVideo(
+        color_metadata.bits_per_channel, color_metadata.primaries,
+        color_metadata.transfer, color_metadata.matrix);
+  }
+
   if (max_video_capabilities && strlen(max_video_capabilities) > 0) {
+    // Sub players must use "decode-to-texture" on Android.
+    // Since hdr videos are not supported under "decode-to-texture" mode, reject
+    // it for sub players.
     if (PlayerComponents::Factory::OutputModeSupported(
-            kSbPlayerOutputModeDecodeToTexture, codec, drm_system)) {
+            kSbPlayerOutputModeDecodeToTexture, codec, drm_system) &&
+        is_sdr) {
       return kSbPlayerOutputModeDecodeToTexture;
     }
-    SB_NOTREACHED();
     return kSbPlayerOutputModeInvalid;
   }
 
-  // The main player may use any output mode.
-  SbPlayerOutputMode output_modes_to_check[] = {
-      kSbPlayerOutputModePunchOut,
-      kSbPlayerOutputModeDecodeToTexture,
-  };
+  SbPlayerOutputMode output_modes_to_check[2] = {kSbPlayerOutputModeInvalid,
+                                                 kSbPlayerOutputModeInvalid};
+  int number_of_output_modes_to_check = 2;
 
-  // Check |kSbPlayerOutputModeDecodeToTexture| first if the caller prefers it.
-  if (creation_param->output_mode == kSbPlayerOutputModeDecodeToTexture) {
-    std::swap(output_modes_to_check[0], output_modes_to_check[1]);
+  if (is_sdr) {
+    if (creation_param->output_mode == kSbPlayerOutputModeDecodeToTexture) {
+      output_modes_to_check[0] = kSbPlayerOutputModeDecodeToTexture;
+      output_modes_to_check[1] = kSbPlayerOutputModePunchOut;
+    } else {
+      output_modes_to_check[0] = kSbPlayerOutputModePunchOut;
+      output_modes_to_check[1] = kSbPlayerOutputModeDecodeToTexture;
+    }
+  } else {
+    // HDR videos require "punch-out".
+    output_modes_to_check[0] = kSbPlayerOutputModePunchOut;
+    number_of_output_modes_to_check = 1;
   }
 
-  if (PlayerComponents::Factory::OutputModeSupported(output_modes_to_check[0],
-                                                     codec, drm_system)) {
-    return output_modes_to_check[0];
-  }
-
-  if (PlayerComponents::Factory::OutputModeSupported(output_modes_to_check[1],
-                                                     codec, drm_system)) {
-    return output_modes_to_check[1];
+  for (int i = 0; i < number_of_output_modes_to_check; ++i) {
+    if (PlayerComponents::Factory::OutputModeSupported(output_modes_to_check[i],
+                                                       codec, drm_system)) {
+      return output_modes_to_check[i];
+    }
   }
 
   SB_LOG(WARNING) << "creation_param->video_stream_info.codec ("
diff --git a/starboard/android/shared/player_get_preferred_output_mode_test.cc b/starboard/android/shared/player_get_preferred_output_mode_test.cc
new file mode 100644
index 0000000..775d76c
--- /dev/null
+++ b/starboard/android/shared/player_get_preferred_output_mode_test.cc
@@ -0,0 +1,149 @@
+// Copyright 2023 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include "starboard/drm.h"
+#include "starboard/media.h"
+#include "starboard/player.h"
+#include "starboard/shared/starboard/drm/drm_test_helpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// The Android TV `SbPlayerGetPreferredOutputMode()` implementation has special
+// constraints that requires it own tests.
+
+namespace starboard {
+namespace android {
+namespace shared {
+namespace {
+
+using ::starboard::shared::starboard::drm::CreateDummyDrmSystem;
+
+SbPlayerCreationParam GetDefaultPlaybackParam() {
+  SbPlayerCreationParam creation_param = {
+      kSbDrmSystemInvalid,
+      {
+          kSbMediaAudioCodecAac,
+      },
+      {
+          kSbMediaVideoCodecVp9,
+      },
+  };
+
+  creation_param.audio_stream_info.mime = "";
+  creation_param.audio_stream_info.number_of_channels = 2;
+  creation_param.audio_stream_info.samples_per_second = 48000;
+  creation_param.audio_stream_info.bits_per_sample = 16;
+
+  auto& video_stream_info = creation_param.video_stream_info;
+
+  video_stream_info.mime = "";
+  video_stream_info.max_video_capabilities = "";
+  video_stream_info.frame_width = 640;
+  video_stream_info.frame_height = 480;
+
+  video_stream_info.color_metadata.bits_per_channel = 8;
+  video_stream_info.color_metadata.primaries = kSbMediaPrimaryIdBt709;
+  video_stream_info.color_metadata.transfer = kSbMediaTransferIdBt709;
+  video_stream_info.color_metadata.matrix = kSbMediaMatrixIdBt709;
+
+  return creation_param;
+}
+
+SbPlayerCreationParam GetSdrPlaybackParam() {
+  return GetDefaultPlaybackParam();
+}
+
+SbPlayerCreationParam GetHdrPlaybackParam() {
+  SbPlayerCreationParam creation_param = GetDefaultPlaybackParam();
+  auto& video_stream_info = creation_param.video_stream_info;
+
+  video_stream_info.color_metadata.bits_per_channel = 10;
+  video_stream_info.color_metadata.primaries = kSbMediaPrimaryIdBt2020;
+  video_stream_info.color_metadata.transfer = kSbMediaTransferId10BitBt2020;
+  video_stream_info.color_metadata.matrix =
+      kSbMediaMatrixIdBt2020ConstantLuminance;
+
+  return creation_param;
+}
+
+TEST(SbPlayerGetPreferredOutputModeTest, HdrPlaybackRequiresPunchOut) {
+  SbPlayerCreationParam creation_param = GetHdrPlaybackParam();
+
+  creation_param.output_mode = kSbPlayerOutputModeDecodeToTexture;
+  auto preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModePunchOut);
+}
+
+TEST(SbPlayerGetPreferredOutputModeTest,
+     SecondaryPlayerRequiresDecodeToTexture) {
+  SbPlayerCreationParam creation_param = GetSdrPlaybackParam();
+
+  creation_param.video_stream_info.max_video_capabilities =
+      "width=640; height=480";
+  creation_param.output_mode = kSbPlayerOutputModePunchOut;
+  auto preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModeDecodeToTexture);
+}
+
+TEST(SbPlayerGetPreferredOutputModeTest, SecondaryPlayerCannotBeHdr) {
+  SbPlayerCreationParam creation_param = GetHdrPlaybackParam();
+
+  creation_param.video_stream_info.max_video_capabilities =
+      "width=640; height=480";
+  creation_param.output_mode = kSbPlayerOutputModeDecodeToTexture;
+  auto preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModeInvalid);
+}
+
+TEST(SbPlayerGetPreferredOutputModeTest, SecuredDrmRequiresPunchOut) {
+  SbPlayerCreationParam creation_param = GetSdrPlaybackParam();
+
+  SbDrmSystem drm_system = CreateDummyDrmSystem("com.widevine");
+  ASSERT_TRUE(SbDrmSystemIsValid(drm_system));
+
+  creation_param.drm_system = drm_system;
+  creation_param.output_mode = kSbPlayerOutputModeDecodeToTexture;
+  auto preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModePunchOut);
+
+  SbDrmDestroySystem(drm_system);
+}
+
+TEST(SbPlayerGetPreferredOutputModeTest,
+     SecuredDrmWithDecodeToTextureIsInvalid) {
+  SbPlayerCreationParam creation_param = GetSdrPlaybackParam();
+
+  SbDrmSystem drm_system = CreateDummyDrmSystem("com.widevine");
+  ASSERT_TRUE(SbDrmSystemIsValid(drm_system));
+
+  creation_param.drm_system = drm_system;
+  creation_param.video_stream_info.max_video_capabilities =
+      "width=640; height=480";
+
+  creation_param.output_mode = kSbPlayerOutputModePunchOut;
+  auto preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModeInvalid);
+
+  creation_param.output_mode = kSbPlayerOutputModeDecodeToTexture;
+  preferred_output_mode = SbPlayerGetPreferredOutputMode(&creation_param);
+  EXPECT_EQ(preferred_output_mode, kSbPlayerOutputModeInvalid);
+
+  SbDrmDestroySystem(drm_system);
+}
+
+}  // namespace
+}  // namespace shared
+}  // namespace android
+}  // namespace starboard
diff --git a/starboard/android/shared/test_filters.py b/starboard/android/shared/test_filters.py
index b2a269b..f4840c1 100644
--- a/starboard/android/shared/test_filters.py
+++ b/starboard/android/shared/test_filters.py
@@ -85,6 +85,15 @@
 
         # TODO: Filter this test on a per-device basis.
         'SbMediaCanPlayMimeAndKeySystem.MinimumSupport',
+
+        # TODO: b/289281412 Make this test work on lab devices consistently.
+        'SbPlayerWriteSampleTests/SbPlayerWriteSampleTest.PartialAudio/*',
+
+        # TODO: b/292319097 Make this test work on lab devices consistently.
+        'SbPlayerTest.MaxVideoCapabilities',
+
+        # TODO: b/292409536 Make this test fork on lab devices consistently.
+        'SbPlayerWriteSampleTests/SbPlayerWriteSampleTest.PartialAudioDiscardAll/*',
     ],
 }
 # pylint: enable=line-too-long
diff --git a/starboard/android/shared/video_decoder.cc b/starboard/android/shared/video_decoder.cc
index e906faf..89ea05d 100644
--- a/starboard/android/shared/video_decoder.cc
+++ b/starboard/android/shared/video_decoder.cc
@@ -102,12 +102,12 @@
 }
 
 void ParseMaxResolution(const std::string& max_video_capabilities,
-                        int window_width,
-                        int window_height,
+                        int frame_width,
+                        int frame_height,
                         optional<int>* max_width,
                         optional<int>* max_height) {
-  SB_DCHECK(window_width > 0);
-  SB_DCHECK(window_height > 0);
+  SB_DCHECK(frame_width > 0);
+  SB_DCHECK(frame_height > 0);
   SB_DCHECK(max_width);
   SB_DCHECK(max_height);
 
@@ -148,31 +148,31 @@
     return;
   }
 
-  if (window_width <= 0 || window_height <= 0) {
+  if (frame_width <= 0 || frame_height <= 0) {
     // We DCHECK() above, but just be safe.
     SB_LOG(WARNING)
-        << "Failed to parse max resolutions due to invalid window resolutions ("
-        << window_width << ", " << window_height << ").";
+        << "Failed to parse max resolutions due to invalid frame resolutions ("
+        << frame_width << ", " << frame_height << ").";
     return;
   }
 
   if (width > 0) {
     *max_width = width;
-    *max_height = max_width->value() * window_height / window_width;
+    *max_height = max_width->value() * frame_height / frame_width;
     SB_LOG(INFO) << "Inferred max height (" << *max_height
                  << ") from max_width (" << *max_width
-                 << ") and window resolution @ (" << window_width << ", "
-                 << window_height << ").";
+                 << ") and frame resolution @ (" << frame_width << ", "
+                 << frame_height << ").";
     return;
   }
 
   if (height > 0) {
     *max_height = height;
-    *max_width = max_height->value() * window_width / window_height;
+    *max_width = max_height->value() * frame_width / frame_height;
     SB_LOG(INFO) << "Inferred max width (" << *max_width
                  << ") from max_height (" << *max_height
-                 << ") and window resolution @ (" << window_width << ", "
-                 << window_height << ").";
+                 << ") and frame resolution @ (" << frame_width << ", "
+                 << frame_height << ").";
   }
 }
 
@@ -344,7 +344,7 @@
   bool rendered_;
 };
 
-VideoDecoder::VideoDecoder(SbMediaVideoCodec video_codec,
+VideoDecoder::VideoDecoder(const VideoStreamInfo& video_stream_info,
                            SbDrmSystem drm_system,
                            SbPlayerOutputMode output_mode,
                            SbDecodeTargetGraphicsContextProvider*
@@ -356,7 +356,7 @@
                            bool force_big_endian_hdr_metadata,
                            bool force_improved_support_check,
                            std::string* error_message)
-    : video_codec_(video_codec),
+    : video_codec_(video_stream_info.codec),
       drm_system_(static_cast<DrmSystem*>(drm_system)),
       output_mode_(output_mode),
       decode_target_graphics_context_provider_(
@@ -390,7 +390,7 @@
   }
 
   if (video_codec_ != kSbMediaVideoCodecAv1) {
-    if (!InitializeCodec(error_message)) {
+    if (!InitializeCodec(video_stream_info, error_message)) {
       *error_message =
           "Failed to initialize video decoder with error: " + *error_message;
       SB_LOG(ERROR) << *error_message;
@@ -490,7 +490,8 @@
     // because we need to change the color metadata.
     if (video_codec_ != kSbMediaVideoCodecAv1 && media_decoder_ == NULL) {
       std::string error_message;
-      if (!InitializeCodec(&error_message)) {
+      if (!InitializeCodec(input_buffers.front()->video_stream_info(),
+                           &error_message)) {
         error_message =
             "Failed to reinitialize codec with error: " + error_message;
         SB_LOG(ERROR) << error_message;
@@ -519,7 +520,8 @@
       return;
     }
     std::string error_message;
-    if (!InitializeCodec(&error_message)) {
+    if (!InitializeCodec(pending_input_buffers_.front()->video_stream_info(),
+                         &error_message)) {
       error_message =
           "Failed to reinitialize codec with error: " + error_message;
       SB_LOG(ERROR) << error_message;
@@ -556,7 +558,8 @@
     SB_DCHECK(pending_input_buffers_.size() == input_buffer_written_);
 
     std::string error_message;
-    if (!InitializeCodec(&error_message)) {
+    if (!InitializeCodec(pending_input_buffers_.front()->video_stream_info(),
+                         &error_message)) {
       error_message =
           "Failed to reinitialize codec with error: " + error_message;
       SB_LOG(ERROR) << error_message;
@@ -601,11 +604,12 @@
   //       it depends on the behavior of the video renderer.
 }
 
-bool VideoDecoder::InitializeCodec(std::string* error_message) {
+bool VideoDecoder::InitializeCodec(const VideoStreamInfo& video_stream_info,
+                                   std::string* error_message) {
   SB_DCHECK(BelongsToCurrentThread());
   SB_DCHECK(error_message);
 
-  if (video_codec_ == kSbMediaVideoCodecAv1) {
+  if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
     SB_DCHECK(pending_input_buffers_.size() > 0);
 
     // Guesstimate the video fps.
@@ -679,17 +683,9 @@
     return false;
   }
 
-  int window_width, window_height;
-  if (!GetVideoWindowSize(&window_width, &window_height)) {
-    *error_message =
-        "Can't initialize the codec since we don't have a video window.";
-    SB_LOG(ERROR) << *error_message;
-    return false;
-  }
-
   jobject j_media_crypto = drm_system_ ? drm_system_->GetMediaCrypto() : NULL;
   SB_DCHECK(!drm_system_ || j_media_crypto);
-  if (video_codec_ == kSbMediaVideoCodecAv1) {
+  if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
     SB_DCHECK(video_fps_ > 0);
   } else {
     SB_DCHECK(video_fps_ == 0);
@@ -698,12 +694,13 @@
   optional<int> max_width, max_height;
   // TODO(b/281431214): Evaluate if we should also parse the fps from
   //                    `max_video_capabilities_` and pass to MediaDecoder ctor.
-  ParseMaxResolution(max_video_capabilities_, window_width, window_height,
-                     &max_width, &max_height);
+  ParseMaxResolution(max_video_capabilities_, video_stream_info.frame_width,
+                     video_stream_info.frame_height, &max_width, &max_height);
 
   media_decoder_.reset(new MediaDecoder(
-      this, video_codec_, window_width, window_height, max_width, max_height,
-      video_fps_, j_output_surface, drm_system_,
+      this, video_stream_info.codec, video_stream_info.frame_width,
+      video_stream_info.frame_height, max_width, max_height, video_fps_,
+      j_output_surface, drm_system_,
       color_metadata_ ? &*color_metadata_ : nullptr, require_software_codec_,
       std::bind(&VideoDecoder::OnTunnelModeFrameRendered, this, _1),
       tunnel_mode_audio_session_id_, force_big_endian_hdr_metadata_,
@@ -715,7 +712,7 @@
     }
     media_decoder_->SetPlaybackRate(playback_rate_);
 
-    if (video_codec_ == kSbMediaVideoCodecAv1) {
+    if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
       SB_DCHECK(!pending_input_buffers_.empty());
     } else {
       SB_DCHECK(pending_input_buffers_.empty());
@@ -889,11 +886,8 @@
   SB_DLOG(INFO) << "Output format changed, trying to dequeue again.";
 
   ScopedLock lock(decode_target_mutex_);
-  // Record the latest width/height of the decoded input.
-  SurfaceDimensions output_dimensions =
-      media_codec_bridge->GetOutputDimensions();
-  frame_width_ = output_dimensions.width;
-  frame_height_ = output_dimensions.height;
+  // Record the latest dimensions of the decoded input.
+  frame_sizes_.push_back(media_codec_bridge->GetOutputSize());
 
   if (tunnel_mode_audio_session_id_ != -1) {
     return;
@@ -906,9 +900,9 @@
     output_format_ = starboard::nullopt;
     return;
   }
-  output_format_ = VideoOutputFormat(video_codec_, output_dimensions.width,
-                                     output_dimensions.height,
-                                     (color_metadata_ ? true : false));
+  output_format_ = VideoOutputFormat(
+      video_codec_, frame_sizes_.back().display_width(),
+      frame_sizes_.back().display_height(), (color_metadata_ ? true : false));
   first_output_format_changed_ = true;
   auto max_output_buffers =
       MaxMediaCodecOutputBuffersLookupTable::GetInstance()
@@ -931,6 +925,7 @@
 }
 
 namespace {
+
 void updateTexImage(jobject surface_texture) {
   JniEnvExt* env = JniEnvExt::Get();
   env->CallVoidMethodOrAbort(surface_texture, "updateTexImage", "()V");
@@ -1013,6 +1008,7 @@
   content_region->top = extent_y * height;
   content_region->bottom = origin_y * height;
 }
+
 }  // namespace
 
 // When in decode-to-texture mode, this returns the current decoded video frame.
@@ -1025,17 +1021,7 @@
     bool has_new_texture = has_new_texture_available_.exchange(false);
     if (has_new_texture) {
       updateTexImage(decode_target_->data->surface_texture);
-
-      decode_target_->data->info.planes[0].width = frame_width_;
-      decode_target_->data->info.planes[0].height = frame_height_;
-      decode_target_->data->info.width = frame_width_;
-      decode_target_->data->info.height = frame_height_;
-
-      float matrix4x4[16];
-      getTransformMatrix(decode_target_->data->surface_texture, matrix4x4);
-      SetDecodeTargetContentRegionFromMatrix(
-          &decode_target_->data->info.planes[0].content_region, frame_width_,
-          frame_height_, matrix4x4);
+      UpdateDecodeTargetSizeAndContentRegion_Locked();
 
       if (!first_texture_received_) {
         first_texture_received_ = true;
@@ -1051,6 +1037,97 @@
   return kSbDecodeTargetInvalid;
 }
 
+void VideoDecoder::UpdateDecodeTargetSizeAndContentRegion_Locked() {
+  decode_target_mutex_.DCheckAcquired();
+
+  SB_DCHECK(!frame_sizes_.empty());
+
+  while (!frame_sizes_.empty()) {
+    const auto& frame_size = frame_sizes_.front();
+    if (frame_size.has_crop_values()) {
+      decode_target_->data->info.planes[0].width = frame_size.texture_width;
+      decode_target_->data->info.planes[0].height = frame_size.texture_height;
+      decode_target_->data->info.width = frame_size.texture_width;
+      decode_target_->data->info.height = frame_size.texture_height;
+
+      float matrix4x4[16];
+      getTransformMatrix(decode_target_->data->surface_texture, matrix4x4);
+
+      auto& content_region =
+          decode_target_->data->info.planes[0].content_region;
+      SetDecodeTargetContentRegionFromMatrix(
+          &content_region, frame_size.texture_width, frame_size.texture_height,
+          matrix4x4);
+
+      // Now we have two crop rectangles, one from the MediaFormat, one from the
+      // transform of the surface texture.  Their sizes should match.
+      // Note that we cannot compare individual corners directly, as the values
+      // retrieving from the surface texture can be flipped.
+      int content_region_width =
+          std::abs(content_region.left - content_region.right) + 1;
+      int content_region_height =
+          std::abs(content_region.bottom - content_region.top) + 1;
+      // Using 2 as epsilon, as the texture may get clipped by one pixel from
+      // each side.
+      bool are_crop_values_matching =
+          std::abs(content_region_width - frame_size.display_width()) <= 2 &&
+          std::abs(content_region_height - frame_size.display_height()) <= 2;
+      if (are_crop_values_matching) {
+        return;
+      }
+
+#if !defined(COBALT_BUILD_TYPE_GOLD)
+      // If we failed to find any matching clip regions, the crop values
+      // returned from the platform may be inconsistent.
+      // Crash in non-gold mode, and fallback to the old logic in gold mode to
+      // avoid terminating the app in production.
+      SB_CHECK(frame_sizes_.size() > 1)
+          << frame_size.texture_width << "x" << frame_size.texture_height
+          << " - (" << content_region.left << ", " << content_region.top << ", "
+          << content_region.right << ", " << content_region.bottom << "), ("
+          << frame_size.crop_left << "), (" << frame_size.crop_top << "), ("
+          << frame_size.crop_right << "), (" << frame_size.crop_bottom << ")";
+#endif  // !defined(COBALT_BUILD_TYPE_GOLD)
+    } else {
+      SB_LOG(WARNING) << "Crop values not set.";
+    }
+
+    if (frame_sizes_.size() == 1) {
+      SB_LOG(WARNING) << "Setting content region frame width/height failed,"
+                      << " fallback to the legacy logic.";
+      break;
+    }
+
+    frame_sizes_.erase(frame_sizes_.begin());
+  }
+
+  SB_DCHECK(!frame_sizes_.empty());
+  if (frame_sizes_.empty()) {
+    // This should never happen.  Appending a default value so it aligns to the
+    // legacy behavior, where a single value (instead of an std::vector<>) is
+    // used.
+    frame_sizes_.resize(1);
+  }
+
+  // The legacy logic works when the crop rectangle has the same aspect ratio as
+  // the video texture, which is true for most of the playbacks.
+  // Leaving the legacy logic in place in case the new logic above doesn't work
+  // on some devices, so at least the majority of playbacks still work.
+  decode_target_->data->info.planes[0].width =
+      frame_sizes_.back().display_width();
+  decode_target_->data->info.planes[0].height =
+      frame_sizes_.back().display_height();
+  decode_target_->data->info.width = frame_sizes_.back().display_width();
+  decode_target_->data->info.height = frame_sizes_.back().display_height();
+
+  float matrix4x4[16];
+  getTransformMatrix(decode_target_->data->surface_texture, matrix4x4);
+  SetDecodeTargetContentRegionFromMatrix(
+      &decode_target_->data->info.planes[0].content_region,
+      frame_sizes_.back().display_width(), frame_sizes_.back().display_height(),
+      matrix4x4);
+}
+
 void VideoDecoder::SetPlaybackRate(double playback_rate) {
   playback_rate_ = playback_rate;
   if (media_decoder_) {
diff --git a/starboard/android/shared/video_decoder.h b/starboard/android/shared/video_decoder.h
index d8eafed..232db16 100644
--- a/starboard/android/shared/video_decoder.h
+++ b/starboard/android/shared/video_decoder.h
@@ -34,6 +34,7 @@
 #include "starboard/media.h"
 #include "starboard/player.h"
 #include "starboard/shared/internal_only.h"
+#include "starboard/shared/starboard/media/media_util.h"
 #include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
 #include "starboard/shared/starboard/player/filter/video_render_algorithm.h"
 #include "starboard/shared/starboard/player/filter/video_renderer_sink.h"
@@ -50,6 +51,8 @@
       private ::starboard::shared::starboard::player::JobQueue::JobOwner,
       private VideoSurfaceHolder {
  public:
+  typedef ::starboard::shared::starboard::media::VideoStreamInfo
+      VideoStreamInfo;
   typedef ::starboard::shared::starboard::player::filter::VideoRenderAlgorithm
       VideoRenderAlgorithm;
   typedef ::starboard::shared::starboard::player::filter::VideoRendererSink
@@ -57,7 +60,7 @@
 
   class Sink;
 
-  VideoDecoder(SbMediaVideoCodec video_codec,
+  VideoDecoder(const VideoStreamInfo& video_stream_info,
                SbDrmSystem drm_system,
                SbPlayerOutputMode output_mode,
                SbDecodeTargetGraphicsContextProvider*
@@ -90,6 +93,7 @@
   void Reset() override;
   SbDecodeTarget GetCurrentDecodeTarget() override;
 
+  void UpdateDecodeTargetSizeAndContentRegion_Locked();
   void SetPlaybackRate(double playback_rate);
 
   void OnNewTextureAvailable();
@@ -99,7 +103,8 @@
  private:
   // Attempt to initialize the codec.  Returns whether initialization was
   // successful.
-  bool InitializeCodec(std::string* error_message);
+  bool InitializeCodec(const VideoStreamInfo& video_stream_info,
+                       std::string* error_message);
   void TeardownCodec();
 
   void WriteInputBuffersInternal(const InputBuffers& input_buffers);
@@ -168,9 +173,12 @@
   // and we do so through this mutex.
   Mutex decode_target_mutex_;
 
-  // The width and height of the latest decoded frame.
-  int32_t frame_width_ = 0;
-  int32_t frame_height_ = 0;
+  // The size infos of the frames in use, i.e. the frames being displayed, and
+  // the frames recently decoded frames and pending display.
+  // They are the same at most of the time, but they can be different when there
+  // is a format change. For example, when the newly decoded frames are at
+  // 1080p, and the frames being played are still at 480p.
+  std::vector<FrameSize> frame_sizes_;
 
   double playback_rate_ = 1.0;
 
diff --git a/starboard/android/shared/video_render_algorithm.cc b/starboard/android/shared/video_render_algorithm.cc
index 74ed628..5edf96f 100644
--- a/starboard/android/shared/video_render_algorithm.cc
+++ b/starboard/android/shared/video_render_algorithm.cc
@@ -26,7 +26,7 @@
 
 namespace {
 
-const SbTimeMonotonic kBufferTooLateThreshold = -30 * kSbTimeMillisecond;
+const SbTimeMonotonic kBufferTooLateThreshold = -32 * kSbTimeMillisecond;
 const SbTimeMonotonic kBufferReadyThreshold = 50 * kSbTimeMillisecond;
 
 jlong GetSystemNanoTime() {
diff --git a/starboard/build/config/BUILDCONFIG.gn b/starboard/build/config/BUILDCONFIG.gn
index e57c265..64bd0f8 100644
--- a/starboard/build/config/BUILDCONFIG.gn
+++ b/starboard/build/config/BUILDCONFIG.gn
@@ -90,13 +90,16 @@
 # TODO(b/272790873): Set host_cpu to x86 for 32 bit builds.
 if (target_cpu == "x86" || target_cpu == "arm") {
   _host_toolchain_cpu = "x86"
+} else if (target_cpu == "arm64") {
+  # TODO(b/292107465): Set host_cpu to x64 for arm64 builds.
+  _host_toolchain_cpu = "x64"
 } else {
   _host_toolchain_cpu = host_cpu
 }
 host_toolchain = "//starboard/build/toolchain/$host_os:$_host_toolchain_cpu"
 
 if (build_with_separate_cobalt_toolchain) {
-  cobalt_toolchain = "//starboard/build/toolchain/linux:clang_lld"
+  cobalt_toolchain = "//starboard/build/toolchain:clang"
   starboard_toolchain = "//$starboard_path/toolchain:starboard"
 } else {
   cobalt_toolchain = "//$starboard_path/toolchain:target"
diff --git a/starboard/build/platform_configuration.py b/starboard/build/platform_configuration.py
index c5bac3d..af3fa2c 100644
--- a/starboard/build/platform_configuration.py
+++ b/starboard/build/platform_configuration.py
@@ -165,13 +165,19 @@
     Returns:
       A list of strings of test target names.
     """
+    # TODO(b/292007482): Replace static list with gn query.
     return [
         'app_key_files_test',
         'app_key_test',
+        'common_test',
+        'cwrappers_test',
         'drain_file_test',
         'elf_loader_test',
+        'eztime_test',
         'installation_manager_test',
         'nplb',
+        # TODO(b/292138589): Fails on various linux configs.
+        # 'nplb_evergreen_compat_tests',
         'player_filter_tests',
         'reset_evergreen_update_test',
         'slot_management_test',
diff --git a/starboard/build/toolchain/linux/clang_lld_toolchain.gni b/starboard/build/toolchain/BUILD.gn
similarity index 65%
rename from starboard/build/toolchain/linux/clang_lld_toolchain.gni
rename to starboard/build/toolchain/BUILD.gn
index f9de0de..2bfec6e 100644
--- a/starboard/build/toolchain/linux/clang_lld_toolchain.gni
+++ b/starboard/build/toolchain/BUILD.gn
@@ -12,21 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("//build/config/clang/clang.gni")
 import("//build/toolchain/gcc_toolchain.gni")
 
-template("clang_lld_toolchain") {
-  not_needed(invoker, "*")
-
-  gcc_toolchain(target_name) {
-    prefix = rebase_path("$clang_base_path/bin", root_build_dir)
-    cc = "$prefix/clang"
-    cxx = "$prefix/clang++"
-    ld = "$prefix/ld.lld"
-    ar = "$prefix/llvm-ar"
-    nm = "nm"
-
-    toolchain_args = {
-      is_clang = true
-    }
-  }
+clang_toolchain("clang") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/build/toolchain/linux/BUILD.gn b/starboard/build/toolchain/linux/BUILD.gn
index 97a5b53..24da4aa 100644
--- a/starboard/build/toolchain/linux/BUILD.gn
+++ b/starboard/build/toolchain/linux/BUILD.gn
@@ -14,7 +14,6 @@
 
 import("//build/toolchain/gcc_toolchain.gni")
 import("//starboard/build/platform_path.gni")
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
 
 clang_toolchain("x64") {
   clang_base_path = clang_base_path
@@ -37,6 +36,3 @@
     is_clang_16 = true
   }
 }
-
-clang_lld_toolchain("clang_lld") {
-}
diff --git a/starboard/build/toolchain/mac/BUILD.gn b/starboard/build/toolchain/mac/BUILD.gn
index 780c648..7e11b90 100644
--- a/starboard/build/toolchain/mac/BUILD.gn
+++ b/starboard/build/toolchain/mac/BUILD.gn
@@ -24,3 +24,13 @@
     toolchain_config_path = "//starboard/build/config/mac:host"
   }
 }
+
+apple_toolchain("arm64") {
+  bin_path = apple_clang_base_path
+  toolchain_args = {
+    current_os = "mac"
+    current_cpu = "arm64"
+    use_xcode_clang = true
+    toolchain_config_path = "//starboard/build/config/mac:host"
+  }
+}
diff --git a/starboard/doc/evergreen/cobalt_evergreen_overview.md b/starboard/doc/evergreen/cobalt_evergreen_overview.md
index e614373..8e2591c 100644
--- a/starboard/doc/evergreen/cobalt_evergreen_overview.md
+++ b/starboard/doc/evergreen/cobalt_evergreen_overview.md
@@ -131,7 +131,7 @@
 
 *   `kSbSystemPathStorageDirectory`
     *   Dedicated location for storing Cobalt Evergreen-related binaries
-    *   This path must be writable and have at least 96MB of reserved space for
+    *   This path must be writable and have at least 64MB of reserved space for
         Evergreen updates. Please see the “Platforms Requirements” section below
         for more details.
 *   `kSbMemoryMapProtectExec`
@@ -195,12 +195,12 @@
 
 *   V8
 
-Additional reserved storage (96MB) is required for Evergreen binaries. We expect
+Additional reserved storage (64MB) is required for Evergreen binaries. We expect
 Evergreen implementations to have an initial Cobalt preloaded on the device and
 an additional reserved space for additional Cobalt update storage.
 
 *   Initial Cobalt binary deployment - 64MB
-*   Additional Cobalt update storage - 96MB
+*   Additional Cobalt update storage - 64MB
     *   Required for 2 update slots under `kSbSystemPathStorageDirectory`
 
 As Cobalt Evergreen is intended to be updated from Google Cloud architecture
diff --git a/starboard/evergreen/arm/hardfp/platform_configuration/BUILD.gn b/starboard/evergreen/arm/hardfp/platform_configuration/BUILD.gn
index 2dcac4f..c4403ea 100644
--- a/starboard/evergreen/arm/hardfp/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/arm/hardfp/platform_configuration/BUILD.gn
@@ -28,7 +28,7 @@
     "//starboard/evergreen/arm/shared/platform_configuration",
   ]
   ldflags = [
-    "-m",
-    "armelf",
+    "-Wl,-m",
+    "-Wl,armelf",
   ]
 }
diff --git a/starboard/evergreen/arm/hardfp/toolchain/BUILD.gn b/starboard/evergreen/arm/hardfp/toolchain/BUILD.gn
index 5bc6339..8f50b01 100644
--- a/starboard/evergreen/arm/hardfp/toolchain/BUILD.gn
+++ b/starboard/evergreen/arm/hardfp/toolchain/BUILD.gn
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
+import("//build/config/clang/clang.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
-clang_lld_toolchain("target") {
+clang_toolchain("target") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/evergreen/arm/softfp/platform_configuration/BUILD.gn b/starboard/evergreen/arm/softfp/platform_configuration/BUILD.gn
index 0de964f..907d14e 100644
--- a/starboard/evergreen/arm/softfp/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/arm/softfp/platform_configuration/BUILD.gn
@@ -28,7 +28,7 @@
     "//starboard/evergreen/arm/shared/platform_configuration",
   ]
   ldflags = [
-    "-m",
-    "armelf",
+    "-Wl,-m",
+    "-Wl,armelf",
   ]
 }
diff --git a/starboard/evergreen/arm/softfp/toolchain/BUILD.gn b/starboard/evergreen/arm/softfp/toolchain/BUILD.gn
index 5bc6339..8f50b01 100644
--- a/starboard/evergreen/arm/softfp/toolchain/BUILD.gn
+++ b/starboard/evergreen/arm/softfp/toolchain/BUILD.gn
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
+import("//build/config/clang/clang.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
-clang_lld_toolchain("target") {
+clang_toolchain("target") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/evergreen/arm64/platform_configuration/BUILD.gn b/starboard/evergreen/arm64/platform_configuration/BUILD.gn
index ce00c13..20a22bb 100644
--- a/starboard/evergreen/arm64/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/arm64/platform_configuration/BUILD.gn
@@ -31,8 +31,8 @@
   ]
 
   ldflags = [
-    "-m",
-    "aarch64elf",
+    "-Wl,-m",
+    "-Wl,aarch64elf",
   ]
   cflags = [ "-isystem" +
              rebase_path("//third_party/musl/arch/aarch64", root_build_dir) ]
diff --git a/starboard/evergreen/arm64/toolchain/BUILD.gn b/starboard/evergreen/arm64/toolchain/BUILD.gn
index 5bc6339..8f50b01 100644
--- a/starboard/evergreen/arm64/toolchain/BUILD.gn
+++ b/starboard/evergreen/arm64/toolchain/BUILD.gn
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
+import("//build/config/clang/clang.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
-clang_lld_toolchain("target") {
+clang_toolchain("target") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/evergreen/shared/platform_configuration/BUILD.gn b/starboard/evergreen/shared/platform_configuration/BUILD.gn
index 6b154a0..94f7208 100644
--- a/starboard/evergreen/shared/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/shared/platform_configuration/BUILD.gn
@@ -14,20 +14,19 @@
 
 config("platform_configuration") {
   ldflags = [
-    "--build-id",
-    "--gc-sections",
-    "-X",
-    "-v",
-    "-eh-frame-hdr",
-    "--fini=__cxa_finalize",
-    "-shared",
-    "-L$clang_base_path",
-    "-L/usr/lib",
-    "-L/lib",
-    "-nostdlib",
-    "--whole-archive",
-    "--no-whole-archive",
-    "-u GetEvergreenSabiString",
+    "-fuse-ld=lld",
+    "-Wl,--build-id",
+    "-Wl,--gc-sections",
+    "-Wl,-X",
+    "-Wl,-v",
+    "-Wl,-eh-frame-hdr",
+    "-Wl,--fini=__cxa_finalize",
+    "-Wl,-shared",
+    "-Wl,-L$clang_base_path",
+    "-Wl,-L/usr/lib",
+    "-Wl,-L/lib",
+    "-Wl,-nostdlib",
+    "-Wl,-u GetEvergreenSabiString",
   ]
 
   cflags = [
@@ -201,7 +200,7 @@
 config("size") {
   cflags = [ "-Os" ]
   if (is_qa || is_gold) {
-    ldflags = [ "--icf=safe" ]
+    ldflags = [ "-Wl,--icf=safe" ]
   }
 }
 
diff --git a/starboard/evergreen/x64/platform_configuration/BUILD.gn b/starboard/evergreen/x64/platform_configuration/BUILD.gn
index 47d7e22..d49869b 100644
--- a/starboard/evergreen/x64/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/x64/platform_configuration/BUILD.gn
@@ -28,8 +28,8 @@
   ]
 
   ldflags = [
-    "-m",
-    "elf_x86_64",
+    "-Wl,-m",
+    "-Wl,elf_x86_64",
   ]
   cflags = [ "-isystem" +
              rebase_path("//third_party/musl/arch/x86_64", root_build_dir) ]
diff --git a/starboard/evergreen/x64/toolchain/BUILD.gn b/starboard/evergreen/x64/toolchain/BUILD.gn
index 5bc6339..8f50b01 100644
--- a/starboard/evergreen/x64/toolchain/BUILD.gn
+++ b/starboard/evergreen/x64/toolchain/BUILD.gn
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
+import("//build/config/clang/clang.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
-clang_lld_toolchain("target") {
+clang_toolchain("target") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/evergreen/x86/platform_configuration/BUILD.gn b/starboard/evergreen/x86/platform_configuration/BUILD.gn
index 633a354..d1bcbc0 100644
--- a/starboard/evergreen/x86/platform_configuration/BUILD.gn
+++ b/starboard/evergreen/x86/platform_configuration/BUILD.gn
@@ -27,6 +27,10 @@
     "//starboard/evergreen/shared/platform_configuration",
   ]
 
+  ldflags = [
+    "-Wl,-m",
+    "-Wl,elf_i386",
+  ]
   cflags = [ "-isystem" +
              rebase_path("//third_party/musl/arch/i386", root_build_dir) ]
 }
diff --git a/starboard/evergreen/x86/toolchain/BUILD.gn b/starboard/evergreen/x86/toolchain/BUILD.gn
index 5bc6339..8f50b01 100644
--- a/starboard/evergreen/x86/toolchain/BUILD.gn
+++ b/starboard/evergreen/x86/toolchain/BUILD.gn
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//starboard/build/toolchain/linux/clang_lld_toolchain.gni")
+import("//build/config/clang/clang.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
-clang_lld_toolchain("target") {
+clang_toolchain("target") {
+  clang_base_path = clang_base_path
 }
diff --git a/starboard/nplb/BUILD.gn b/starboard/nplb/BUILD.gn
index 7cfa816..08e415a 100644
--- a/starboard/nplb/BUILD.gn
+++ b/starboard/nplb/BUILD.gn
@@ -23,6 +23,8 @@
     "//starboard/nplb/sabi/signedness_of_char_test.cc",
     "//starboard/nplb/sabi/size_test.cc",
     "//starboard/nplb/sabi/struct_alignment_test.cc",
+    "//starboard/shared/starboard/drm/drm_test_helpers.cc",
+    "//starboard/shared/starboard/drm/drm_test_helpers.h",
     "//starboard/testing/fake_graphics_context_provider.cc",
     "//starboard/testing/fake_graphics_context_provider.h",
     "accessibility_test.cc",
@@ -55,7 +57,6 @@
     "directory_get_next_test.cc",
     "directory_open_test.cc",
     "drm_get_metrics_test.cc",
-    "drm_helpers.cc",
     "drm_helpers.h",
     "drm_is_server_certificate_updatable_test.cc",
     "drm_session_test.cc",
diff --git a/starboard/nplb/drm_helpers.h b/starboard/nplb/drm_helpers.h
index 6717fcc..1d64f49 100644
--- a/starboard/nplb/drm_helpers.h
+++ b/starboard/nplb/drm_helpers.h
@@ -1,4 +1,4 @@
-// Copyright 2018 The Cobalt Authors. All Rights Reserved.
+// Copyright 2023 The Cobalt Authors. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,136 +15,24 @@
 #ifndef STARBOARD_NPLB_DRM_HELPERS_H_
 #define STARBOARD_NPLB_DRM_HELPERS_H_
 
-#include "starboard/drm.h"
+#include "starboard/shared/starboard/drm/drm_test_helpers.h"
 
 namespace starboard {
 namespace nplb {
 
-void DummySessionUpdateRequestFunc(SbDrmSystem drm_system,
-                                   void* context,
-                                   int ticket,
-                                   SbDrmStatus status,
-                                   SbDrmSessionRequestType type,
-                                   const char* error_message,
-                                   const void* session_id,
-                                   int session_id_size,
-                                   const void* content,
-                                   int content_size,
-                                   const char* url);
+using ::starboard::shared::starboard::drm::DummyServerCertificateUpdatedFunc;
+using ::starboard::shared::starboard::drm::DummySessionClosedFunc;
+using ::starboard::shared::starboard::drm::DummySessionKeyStatusesChangedFunc;
+using ::starboard::shared::starboard::drm::DummySessionUpdatedFunc;
+using ::starboard::shared::starboard::drm::DummySessionUpdateRequestFunc;
 
-void DummySessionUpdatedFunc(SbDrmSystem drm_system,
-                             void* context,
-                             int ticket,
-                             SbDrmStatus status,
-                             const char* error_message,
-                             const void* session_id,
-                             int session_id_size);
+using ::starboard::shared::starboard::drm::CreateDummyDrmSystem;
 
-void DummyServerCertificateUpdatedFunc(SbDrmSystem drm_system,
-                                       void* context,
-                                       int ticket,
-                                       SbDrmStatus status,
-                                       const char* error_message);
+using ::starboard::shared::starboard::drm::kEncryptionSchemes;
+using ::starboard::shared::starboard::drm::kKeySystems;
+using ::starboard::shared::starboard::drm::kWidevineCertificate;
 
-void DummySessionKeyStatusesChangedFunc(SbDrmSystem drm_system,
-                                        void* context,
-                                        const void* session_id,
-                                        int session_id_size,
-                                        int number_of_keys,
-                                        const SbDrmKeyId* key_ids,
-                                        const SbDrmKeyStatus* key_statuses);
-
-void DummySessionClosedFunc(SbDrmSystem drm_system,
-                            void* context,
-                            const void* session_id,
-                            int session_id_size);
-
-SbDrmSystem CreateDummyDrmSystem(const char* key_system);
-
-static const char* kKeySystems[] = {
-    "com.widevine",
-    "com.widevine.alpha",
-    "com.youtube.playready",
-    "com.youtube.fairplay",
-};
-
-static const char* kEncryptionSchemes[] = {
-    "cenc",
-    "cbcs",
-    "cbcs-1-9",
-};
-
-static constexpr uint8_t kWidevineCertificate[] = {
-    0x0a, 0xc1, 0x02, 0x08, 0x03, 0x12, 0x10, 0x17, 0x05, 0xb9, 0x17, 0xcc,
-    0x12, 0x04, 0x86, 0x8b, 0x06, 0x33, 0x3a, 0x2f, 0x77, 0x2a, 0x8c, 0x18,
-    0x82, 0xb4, 0x82, 0x92, 0x05, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a,
-    0x02, 0x82, 0x01, 0x01, 0x00, 0x99, 0xed, 0x5b, 0x3b, 0x32, 0x7d, 0xab,
-    0x5e, 0x24, 0xef, 0xc3, 0xb6, 0x2a, 0x95, 0xb5, 0x98, 0x52, 0x0a, 0xd5,
-    0xbc, 0xcb, 0x37, 0x50, 0x3e, 0x06, 0x45, 0xb8, 0x14, 0xd8, 0x76, 0xb8,
-    0xdf, 0x40, 0x51, 0x04, 0x41, 0xad, 0x8c, 0xe3, 0xad, 0xb1, 0x1b, 0xb8,
-    0x8c, 0x4e, 0x72, 0x5a, 0x5e, 0x4a, 0x9e, 0x07, 0x95, 0x29, 0x1d, 0x58,
-    0x58, 0x40, 0x23, 0xa7, 0xe1, 0xaf, 0x0e, 0x38, 0xa9, 0x12, 0x79, 0x39,
-    0x30, 0x08, 0x61, 0x0b, 0x6f, 0x15, 0x8c, 0x87, 0x8c, 0x7e, 0x21, 0xbf,
-    0xfb, 0xfe, 0xea, 0x77, 0xe1, 0x01, 0x9e, 0x1e, 0x57, 0x81, 0xe8, 0xa4,
-    0x5f, 0x46, 0x26, 0x3d, 0x14, 0xe6, 0x0e, 0x80, 0x58, 0xa8, 0x60, 0x7a,
-    0xdc, 0xe0, 0x4f, 0xac, 0x84, 0x57, 0xb1, 0x37, 0xa8, 0xd6, 0x7c, 0xcd,
-    0xeb, 0x33, 0x70, 0x5d, 0x98, 0x3a, 0x21, 0xfb, 0x4e, 0xec, 0xbd, 0x4a,
-    0x10, 0xca, 0x47, 0x49, 0x0c, 0xa4, 0x7e, 0xaa, 0x5d, 0x43, 0x82, 0x18,
-    0xdd, 0xba, 0xf1, 0xca, 0xde, 0x33, 0x92, 0xf1, 0x3d, 0x6f, 0xfb, 0x64,
-    0x42, 0xfd, 0x31, 0xe1, 0xbf, 0x40, 0xb0, 0xc6, 0x04, 0xd1, 0xc4, 0xba,
-    0x4c, 0x95, 0x20, 0xa4, 0xbf, 0x97, 0xee, 0xbd, 0x60, 0x92, 0x9a, 0xfc,
-    0xee, 0xf5, 0x5b, 0xba, 0xf5, 0x64, 0xe2, 0xd0, 0xe7, 0x6c, 0xd7, 0xc5,
-    0x5c, 0x73, 0xa0, 0x82, 0xb9, 0x96, 0x12, 0x0b, 0x83, 0x59, 0xed, 0xce,
-    0x24, 0x70, 0x70, 0x82, 0x68, 0x0d, 0x6f, 0x67, 0xc6, 0xd8, 0x2c, 0x4a,
-    0xc5, 0xf3, 0x13, 0x44, 0x90, 0xa7, 0x4e, 0xec, 0x37, 0xaf, 0x4b, 0x2f,
-    0x01, 0x0c, 0x59, 0xe8, 0x28, 0x43, 0xe2, 0x58, 0x2f, 0x0b, 0x6b, 0x9f,
-    0x5d, 0xb0, 0xfc, 0x5e, 0x6e, 0xdf, 0x64, 0xfb, 0xd3, 0x08, 0xb4, 0x71,
-    0x1b, 0xcf, 0x12, 0x50, 0x01, 0x9c, 0x9f, 0x5a, 0x09, 0x02, 0x03, 0x01,
-    0x00, 0x01, 0x3a, 0x14, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2e,
-    0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
-    0x12, 0x80, 0x03, 0xae, 0x34, 0x73, 0x14, 0xb5, 0xa8, 0x35, 0x29, 0x7f,
-    0x27, 0x13, 0x88, 0xfb, 0x7b, 0xb8, 0xcb, 0x52, 0x77, 0xd2, 0x49, 0x82,
-    0x3c, 0xdd, 0xd1, 0xda, 0x30, 0xb9, 0x33, 0x39, 0x51, 0x1e, 0xb3, 0xcc,
-    0xbd, 0xea, 0x04, 0xb9, 0x44, 0xb9, 0x27, 0xc1, 0x21, 0x34, 0x6e, 0xfd,
-    0xbd, 0xea, 0xc9, 0xd4, 0x13, 0x91, 0x7e, 0x6e, 0xc1, 0x76, 0xa1, 0x04,
-    0x38, 0x46, 0x0a, 0x50, 0x3b, 0xc1, 0x95, 0x2b, 0x9b, 0xa4, 0xe4, 0xce,
-    0x0f, 0xc4, 0xbf, 0xc2, 0x0a, 0x98, 0x08, 0xaa, 0xaf, 0x4b, 0xfc, 0xd1,
-    0x9c, 0x1d, 0xcf, 0xcd, 0xf5, 0x74, 0xcc, 0xac, 0x28, 0xd1, 0xb4, 0x10,
-    0x41, 0x6c, 0xf9, 0xde, 0x88, 0x04, 0x30, 0x1c, 0xbd, 0xb3, 0x34, 0xca,
-    0xfc, 0xd0, 0xd4, 0x09, 0x78, 0x42, 0x3a, 0x64, 0x2e, 0x54, 0x61, 0x3d,
-    0xf0, 0xaf, 0xcf, 0x96, 0xca, 0x4a, 0x92, 0x49, 0xd8, 0x55, 0xe4, 0x2b,
-    0x3a, 0x70, 0x3e, 0xf1, 0x76, 0x7f, 0x6a, 0x9b, 0xd3, 0x6d, 0x6b, 0xf8,
-    0x2b, 0xe7, 0x6b, 0xbf, 0x0c, 0xba, 0x4f, 0xde, 0x59, 0xd2, 0xab, 0xcc,
-    0x76, 0xfe, 0xb6, 0x42, 0x47, 0xb8, 0x5c, 0x43, 0x1f, 0xbc, 0xa5, 0x22,
-    0x66, 0xb6, 0x19, 0xfc, 0x36, 0x97, 0x95, 0x43, 0xfc, 0xa9, 0xcb, 0xbd,
-    0xbb, 0xfa, 0xfa, 0x0e, 0x1a, 0x55, 0xe7, 0x55, 0xa3, 0xc7, 0xbc, 0xe6,
-    0x55, 0xf9, 0x64, 0x6f, 0x58, 0x2a, 0xb9, 0xcf, 0x70, 0xaa, 0x08, 0xb9,
-    0x79, 0xf8, 0x67, 0xf6, 0x3a, 0x0b, 0x2b, 0x7f, 0xdb, 0x36, 0x2c, 0x5b,
-    0xc4, 0xec, 0xd5, 0x55, 0xd8, 0x5b, 0xca, 0xa9, 0xc5, 0x93, 0xc3, 0x83,
-    0xc8, 0x57, 0xd4, 0x9d, 0xaa, 0xb7, 0x7e, 0x40, 0xb7, 0x85, 0x1d, 0xdf,
-    0xd2, 0x49, 0x98, 0x80, 0x8e, 0x35, 0xb2, 0x58, 0xe7, 0x5d, 0x78, 0xea,
-    0xc0, 0xca, 0x16, 0xf7, 0x04, 0x73, 0x04, 0xc2, 0x0d, 0x93, 0xed, 0xe4,
-    0xe8, 0xff, 0x1c, 0x6f, 0x17, 0xe6, 0x24, 0x3e, 0x3f, 0x3d, 0xa8, 0xfc,
-    0x17, 0x09, 0x87, 0x0e, 0xc4, 0x5f, 0xba, 0x82, 0x3a, 0x26, 0x3f, 0x0c,
-    0xef, 0xa1, 0xf7, 0x09, 0x3b, 0x19, 0x09, 0x92, 0x83, 0x26, 0x33, 0x37,
-    0x05, 0x04, 0x3a, 0x29, 0xbd, 0xa6, 0xf9, 0xb4, 0x34, 0x2c, 0xc8, 0xdf,
-    0x54, 0x3c, 0xb1, 0xa1, 0x18, 0x2f, 0x7c, 0x5f, 0xff, 0x33, 0xf1, 0x04,
-    0x90, 0xfa, 0xca, 0x5b, 0x25, 0x36, 0x0b, 0x76, 0x01, 0x5e, 0x9c, 0x5a,
-    0x06, 0xab, 0x8e, 0xe0, 0x2f, 0x00, 0xd2, 0xe8, 0xd5, 0x98, 0x61, 0x04,
-    0xaa, 0xcc, 0x4d, 0xd4, 0x75, 0xfd, 0x96, 0xee, 0x9c, 0xe4, 0xe3, 0x26,
-    0xf2, 0x1b, 0x83, 0xc7, 0x05, 0x85, 0x77, 0xb3, 0x87, 0x32, 0xcd, 0xda,
-    0xbc, 0x6a, 0x6b, 0xed, 0x13, 0xfb, 0x0d, 0x49, 0xd3, 0x8a, 0x45, 0xeb,
-    0x87, 0xa5, 0xf4};
-
-// Widevine-specific CENC Initialization data.
-// https://www.w3.org/TR/eme-stream-mp4/
-// https://www.w3.org/TR/eme-initdata-cenc/#common-system
-static constexpr uint8_t kCencInitData[] = {
-    0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00,
-    0x00, 0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8,
-    0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed, 0x00, 0x00, 0x00, 0x14, 0x08,
-    0x01, 0x12, 0x10, 0x31, 0xfd, 0x5b, 0x66, 0x19, 0xfc, 0x5e, 0xad,
-    0x86, 0x7c, 0xff, 0xb5, 0x84, 0xed, 0x4c, 0x19};
+using ::starboard::shared::starboard::drm::kCencInitData;
 
 }  // namespace nplb
 }  // namespace starboard
diff --git a/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc b/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc
index 218cfb3..2445fd4 100644
--- a/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc
+++ b/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc
@@ -32,7 +32,7 @@
 namespace {
 
 const char kFileName[] = "test_file.data";
-const size_t kBufSize = 96 * 1024 * 1024;  // 96 MB
+const size_t kBufSize = 64 * 1024 * 1024;  // 64 MB
 
 class StorageTest : public ::testing::Test {
  protected:
diff --git a/starboard/nplb/drm_helpers.cc b/starboard/shared/starboard/drm/drm_test_helpers.cc
similarity index 93%
rename from starboard/nplb/drm_helpers.cc
rename to starboard/shared/starboard/drm/drm_test_helpers.cc
index cac39fa..f010f4c 100644
--- a/starboard/nplb/drm_helpers.cc
+++ b/starboard/shared/starboard/drm/drm_test_helpers.cc
@@ -12,12 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "starboard/nplb/drm_helpers.h"
+#include "starboard/shared/starboard/drm/drm_test_helpers.h"
 
 #include "starboard/drm.h"
 
 namespace starboard {
-namespace nplb {
+namespace shared {
+namespace starboard {
+namespace drm {
 
 void DummySessionUpdateRequestFunc(SbDrmSystem drm_system,
                                    void* context,
@@ -65,5 +67,7 @@
       DummyServerCertificateUpdatedFunc, DummySessionClosedFunc);
 }
 
-}  // namespace nplb
+}  // namespace drm
+}  // namespace starboard
+}  // namespace shared
 }  // namespace starboard
diff --git a/starboard/shared/starboard/drm/drm_test_helpers.h b/starboard/shared/starboard/drm/drm_test_helpers.h
new file mode 100644
index 0000000..4ed08b8
--- /dev/null
+++ b/starboard/shared/starboard/drm/drm_test_helpers.h
@@ -0,0 +1,158 @@
+// Copyright 2018 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_STARBOARD_DRM_DRM_TEST_HELPERS_H_
+#define STARBOARD_SHARED_STARBOARD_DRM_DRM_TEST_HELPERS_H_
+
+#include "starboard/drm.h"
+
+// Helpers to be used by tests
+
+namespace starboard {
+namespace shared {
+namespace starboard {
+namespace drm {
+
+void DummySessionUpdateRequestFunc(SbDrmSystem drm_system,
+                                   void* context,
+                                   int ticket,
+                                   SbDrmStatus status,
+                                   SbDrmSessionRequestType type,
+                                   const char* error_message,
+                                   const void* session_id,
+                                   int session_id_size,
+                                   const void* content,
+                                   int content_size,
+                                   const char* url);
+
+void DummySessionUpdatedFunc(SbDrmSystem drm_system,
+                             void* context,
+                             int ticket,
+                             SbDrmStatus status,
+                             const char* error_message,
+                             const void* session_id,
+                             int session_id_size);
+
+void DummyServerCertificateUpdatedFunc(SbDrmSystem drm_system,
+                                       void* context,
+                                       int ticket,
+                                       SbDrmStatus status,
+                                       const char* error_message);
+
+void DummySessionKeyStatusesChangedFunc(SbDrmSystem drm_system,
+                                        void* context,
+                                        const void* session_id,
+                                        int session_id_size,
+                                        int number_of_keys,
+                                        const SbDrmKeyId* key_ids,
+                                        const SbDrmKeyStatus* key_statuses);
+
+void DummySessionClosedFunc(SbDrmSystem drm_system,
+                            void* context,
+                            const void* session_id,
+                            int session_id_size);
+
+SbDrmSystem CreateDummyDrmSystem(const char* key_system);
+
+static const char* kKeySystems[] = {
+    "com.widevine",
+    "com.widevine.alpha",
+    "com.youtube.playready",
+    "com.youtube.fairplay",
+};
+
+static const char* kEncryptionSchemes[] = {
+    "cenc",
+    "cbcs",
+    "cbcs-1-9",
+};
+
+static constexpr uint8_t kWidevineCertificate[] = {
+    0x0a, 0xc1, 0x02, 0x08, 0x03, 0x12, 0x10, 0x17, 0x05, 0xb9, 0x17, 0xcc,
+    0x12, 0x04, 0x86, 0x8b, 0x06, 0x33, 0x3a, 0x2f, 0x77, 0x2a, 0x8c, 0x18,
+    0x82, 0xb4, 0x82, 0x92, 0x05, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0x99, 0xed, 0x5b, 0x3b, 0x32, 0x7d, 0xab,
+    0x5e, 0x24, 0xef, 0xc3, 0xb6, 0x2a, 0x95, 0xb5, 0x98, 0x52, 0x0a, 0xd5,
+    0xbc, 0xcb, 0x37, 0x50, 0x3e, 0x06, 0x45, 0xb8, 0x14, 0xd8, 0x76, 0xb8,
+    0xdf, 0x40, 0x51, 0x04, 0x41, 0xad, 0x8c, 0xe3, 0xad, 0xb1, 0x1b, 0xb8,
+    0x8c, 0x4e, 0x72, 0x5a, 0x5e, 0x4a, 0x9e, 0x07, 0x95, 0x29, 0x1d, 0x58,
+    0x58, 0x40, 0x23, 0xa7, 0xe1, 0xaf, 0x0e, 0x38, 0xa9, 0x12, 0x79, 0x39,
+    0x30, 0x08, 0x61, 0x0b, 0x6f, 0x15, 0x8c, 0x87, 0x8c, 0x7e, 0x21, 0xbf,
+    0xfb, 0xfe, 0xea, 0x77, 0xe1, 0x01, 0x9e, 0x1e, 0x57, 0x81, 0xe8, 0xa4,
+    0x5f, 0x46, 0x26, 0x3d, 0x14, 0xe6, 0x0e, 0x80, 0x58, 0xa8, 0x60, 0x7a,
+    0xdc, 0xe0, 0x4f, 0xac, 0x84, 0x57, 0xb1, 0x37, 0xa8, 0xd6, 0x7c, 0xcd,
+    0xeb, 0x33, 0x70, 0x5d, 0x98, 0x3a, 0x21, 0xfb, 0x4e, 0xec, 0xbd, 0x4a,
+    0x10, 0xca, 0x47, 0x49, 0x0c, 0xa4, 0x7e, 0xaa, 0x5d, 0x43, 0x82, 0x18,
+    0xdd, 0xba, 0xf1, 0xca, 0xde, 0x33, 0x92, 0xf1, 0x3d, 0x6f, 0xfb, 0x64,
+    0x42, 0xfd, 0x31, 0xe1, 0xbf, 0x40, 0xb0, 0xc6, 0x04, 0xd1, 0xc4, 0xba,
+    0x4c, 0x95, 0x20, 0xa4, 0xbf, 0x97, 0xee, 0xbd, 0x60, 0x92, 0x9a, 0xfc,
+    0xee, 0xf5, 0x5b, 0xba, 0xf5, 0x64, 0xe2, 0xd0, 0xe7, 0x6c, 0xd7, 0xc5,
+    0x5c, 0x73, 0xa0, 0x82, 0xb9, 0x96, 0x12, 0x0b, 0x83, 0x59, 0xed, 0xce,
+    0x24, 0x70, 0x70, 0x82, 0x68, 0x0d, 0x6f, 0x67, 0xc6, 0xd8, 0x2c, 0x4a,
+    0xc5, 0xf3, 0x13, 0x44, 0x90, 0xa7, 0x4e, 0xec, 0x37, 0xaf, 0x4b, 0x2f,
+    0x01, 0x0c, 0x59, 0xe8, 0x28, 0x43, 0xe2, 0x58, 0x2f, 0x0b, 0x6b, 0x9f,
+    0x5d, 0xb0, 0xfc, 0x5e, 0x6e, 0xdf, 0x64, 0xfb, 0xd3, 0x08, 0xb4, 0x71,
+    0x1b, 0xcf, 0x12, 0x50, 0x01, 0x9c, 0x9f, 0x5a, 0x09, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0x3a, 0x14, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2e,
+    0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x12, 0x80, 0x03, 0xae, 0x34, 0x73, 0x14, 0xb5, 0xa8, 0x35, 0x29, 0x7f,
+    0x27, 0x13, 0x88, 0xfb, 0x7b, 0xb8, 0xcb, 0x52, 0x77, 0xd2, 0x49, 0x82,
+    0x3c, 0xdd, 0xd1, 0xda, 0x30, 0xb9, 0x33, 0x39, 0x51, 0x1e, 0xb3, 0xcc,
+    0xbd, 0xea, 0x04, 0xb9, 0x44, 0xb9, 0x27, 0xc1, 0x21, 0x34, 0x6e, 0xfd,
+    0xbd, 0xea, 0xc9, 0xd4, 0x13, 0x91, 0x7e, 0x6e, 0xc1, 0x76, 0xa1, 0x04,
+    0x38, 0x46, 0x0a, 0x50, 0x3b, 0xc1, 0x95, 0x2b, 0x9b, 0xa4, 0xe4, 0xce,
+    0x0f, 0xc4, 0xbf, 0xc2, 0x0a, 0x98, 0x08, 0xaa, 0xaf, 0x4b, 0xfc, 0xd1,
+    0x9c, 0x1d, 0xcf, 0xcd, 0xf5, 0x74, 0xcc, 0xac, 0x28, 0xd1, 0xb4, 0x10,
+    0x41, 0x6c, 0xf9, 0xde, 0x88, 0x04, 0x30, 0x1c, 0xbd, 0xb3, 0x34, 0xca,
+    0xfc, 0xd0, 0xd4, 0x09, 0x78, 0x42, 0x3a, 0x64, 0x2e, 0x54, 0x61, 0x3d,
+    0xf0, 0xaf, 0xcf, 0x96, 0xca, 0x4a, 0x92, 0x49, 0xd8, 0x55, 0xe4, 0x2b,
+    0x3a, 0x70, 0x3e, 0xf1, 0x76, 0x7f, 0x6a, 0x9b, 0xd3, 0x6d, 0x6b, 0xf8,
+    0x2b, 0xe7, 0x6b, 0xbf, 0x0c, 0xba, 0x4f, 0xde, 0x59, 0xd2, 0xab, 0xcc,
+    0x76, 0xfe, 0xb6, 0x42, 0x47, 0xb8, 0x5c, 0x43, 0x1f, 0xbc, 0xa5, 0x22,
+    0x66, 0xb6, 0x19, 0xfc, 0x36, 0x97, 0x95, 0x43, 0xfc, 0xa9, 0xcb, 0xbd,
+    0xbb, 0xfa, 0xfa, 0x0e, 0x1a, 0x55, 0xe7, 0x55, 0xa3, 0xc7, 0xbc, 0xe6,
+    0x55, 0xf9, 0x64, 0x6f, 0x58, 0x2a, 0xb9, 0xcf, 0x70, 0xaa, 0x08, 0xb9,
+    0x79, 0xf8, 0x67, 0xf6, 0x3a, 0x0b, 0x2b, 0x7f, 0xdb, 0x36, 0x2c, 0x5b,
+    0xc4, 0xec, 0xd5, 0x55, 0xd8, 0x5b, 0xca, 0xa9, 0xc5, 0x93, 0xc3, 0x83,
+    0xc8, 0x57, 0xd4, 0x9d, 0xaa, 0xb7, 0x7e, 0x40, 0xb7, 0x85, 0x1d, 0xdf,
+    0xd2, 0x49, 0x98, 0x80, 0x8e, 0x35, 0xb2, 0x58, 0xe7, 0x5d, 0x78, 0xea,
+    0xc0, 0xca, 0x16, 0xf7, 0x04, 0x73, 0x04, 0xc2, 0x0d, 0x93, 0xed, 0xe4,
+    0xe8, 0xff, 0x1c, 0x6f, 0x17, 0xe6, 0x24, 0x3e, 0x3f, 0x3d, 0xa8, 0xfc,
+    0x17, 0x09, 0x87, 0x0e, 0xc4, 0x5f, 0xba, 0x82, 0x3a, 0x26, 0x3f, 0x0c,
+    0xef, 0xa1, 0xf7, 0x09, 0x3b, 0x19, 0x09, 0x92, 0x83, 0x26, 0x33, 0x37,
+    0x05, 0x04, 0x3a, 0x29, 0xbd, 0xa6, 0xf9, 0xb4, 0x34, 0x2c, 0xc8, 0xdf,
+    0x54, 0x3c, 0xb1, 0xa1, 0x18, 0x2f, 0x7c, 0x5f, 0xff, 0x33, 0xf1, 0x04,
+    0x90, 0xfa, 0xca, 0x5b, 0x25, 0x36, 0x0b, 0x76, 0x01, 0x5e, 0x9c, 0x5a,
+    0x06, 0xab, 0x8e, 0xe0, 0x2f, 0x00, 0xd2, 0xe8, 0xd5, 0x98, 0x61, 0x04,
+    0xaa, 0xcc, 0x4d, 0xd4, 0x75, 0xfd, 0x96, 0xee, 0x9c, 0xe4, 0xe3, 0x26,
+    0xf2, 0x1b, 0x83, 0xc7, 0x05, 0x85, 0x77, 0xb3, 0x87, 0x32, 0xcd, 0xda,
+    0xbc, 0x6a, 0x6b, 0xed, 0x13, 0xfb, 0x0d, 0x49, 0xd3, 0x8a, 0x45, 0xeb,
+    0x87, 0xa5, 0xf4};
+
+// Widevine-specific CENC Initialization data.
+// https://www.w3.org/TR/eme-stream-mp4/
+// https://www.w3.org/TR/eme-initdata-cenc/#common-system
+static constexpr uint8_t kCencInitData[] = {
+    0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00,
+    0x00, 0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8,
+    0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed, 0x00, 0x00, 0x00, 0x14, 0x08,
+    0x01, 0x12, 0x10, 0x31, 0xfd, 0x5b, 0x66, 0x19, 0xfc, 0x5e, 0xad,
+    0x86, 0x7c, 0xff, 0xb5, 0x84, 0xed, 0x4c, 0x19};
+
+}  // namespace drm
+}  // namespace starboard
+}  // namespace shared
+}  // namespace starboard
+
+#endif  // STARBOARD_SHARED_STARBOARD_DRM_DRM_TEST_HELPERS_H_
diff --git a/starboard/win/win32/args.gn b/starboard/win/win32/args.gn
index 5dba6c9..ca2004d 100644
--- a/starboard/win/win32/args.gn
+++ b/starboard/win/win32/args.gn
@@ -16,4 +16,3 @@
 target_os = "win"
 target_cpu = "x64"
 is_clang = false
-is_internal_build = true
diff --git a/starboard/win/win32/cobalt/configuration.py b/starboard/win/win32/cobalt/configuration.py
index 0128815..1fff087 100644
--- a/starboard/win/win32/cobalt/configuration.py
+++ b/starboard/win/win32/cobalt/configuration.py
@@ -52,4 +52,13 @@
           # Flaky test to be re-enabled after b/271006511 is fixed.
           'CookieMonsterTest.PredicateSeesAllCookies',
       ],
+      'watchdog_test': [
+          # TODO(b/292027298): Enable once test failure is fixed.
+          'WatchdogTest.FrequentConsecutiveViolationsShouldNotWrite'
+          'WatchdogTest.PingInfosAreEvictedAfterMax',
+          'WatchdogTest.RedundantViolationsShouldStack',
+          'WatchdogTest.ViolationsAreEvictedAfterMax',
+          'WatchdogTest.ViolationsJsonShouldPersistAndBeValid',
+          'WatchdogTest.ViolationsShouldResetAfterFetch',
+      ],
   }
diff --git a/third_party/googletest/src/googletest/src/gtest.cc b/third_party/googletest/src/googletest/src/gtest.cc
index 76a0f72..ce395bc 100644
--- a/third_party/googletest/src/googletest/src/gtest.cc
+++ b/third_party/googletest/src/googletest/src/gtest.cc
@@ -1152,7 +1152,10 @@
 // Timer instead.
 TimeInMillis GetTimeInMillis() {
 #if GTEST_OS_STARBOARD
-  return SbTimeGetNow() / kSbTimeMillisecond;
+  // Use EzTime to get millis from posix epoch.
+  EzTimeValue time_value;
+  EzTimeValueGetNow(&time_value, NULL);
+  return time_value.tv_sec * 1000 + time_value.tv_usec / 1000;
 #else
   return std::chrono::duration_cast<std::chrono::milliseconds>(
              std::chrono::system_clock::now() -
diff --git a/third_party/libevent/evdns.c b/third_party/libevent/evdns.c
index d72fdaa..780d6b1 100644
--- a/third_party/libevent/evdns.c
+++ b/third_party/libevent/evdns.c
@@ -2496,9 +2496,12 @@
 static char *
 search_make_new(const struct search_state *const state, int n, const char *const base_name) {
 	const int base_len = strlen(base_name);
-	const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
+	char need_to_append_dot;
 	struct search_domain *dom;
 
+	if (!base_len) return NULL;
+	need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
+
 	for (dom = state->head; dom; dom = dom->next) {
 		if (!n--) {
 			/* this is the postfix we want */
diff --git a/third_party/libwebp/.cmake-format.py b/third_party/libwebp/.cmake-format.py
new file mode 100644
index 0000000..71043af
--- /dev/null
+++ b/third_party/libwebp/.cmake-format.py
@@ -0,0 +1,240 @@
+# ----------------------------------
+# Options affecting listfile parsing
+# ----------------------------------
+with section("parse"):
+
+  # Specify structure for custom cmake functions
+  additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'],
+             'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}}
+
+  # Override configurations per-command where available
+  override_spec = {}
+
+  # Specify variable tags.
+  vartags = []
+
+  # Specify property tags.
+  proptags = []
+
+# -----------------------------
+# Options affecting formatting.
+# -----------------------------
+with section("format"):
+
+  # Disable formatting entirely, making cmake-format a no-op
+  disable = False
+
+  # How wide to allow formatted cmake files
+  line_width = 80
+
+  # How many spaces to tab for indent
+  tab_size = 2
+
+  # If true, lines are indented using tab characters (utf-8 0x09) instead of
+  # <tab_size> space characters (utf-8 0x20). In cases where the layout would
+  # require a fractional tab character, the behavior of the  fractional
+  # indentation is governed by <fractional_tab_policy>
+  use_tabchars = False
+
+  # If <use_tabchars> is True, then the value of this variable indicates how
+  # fractional indentions are handled during whitespace replacement. If set to
+  # 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set
+  # to `round-up` fractional indentation is replaced with a single tab character
+  # (utf-8 0x09) effectively shifting the column to the next tabstop
+  fractional_tab_policy = 'use-space'
+
+  # If an argument group contains more than this many sub-groups (parg or kwarg
+  # groups) then force it to a vertical layout.
+  max_subgroups_hwrap = 3
+
+  # If a positional argument group contains more than this many arguments, then
+  # force it to a vertical layout.
+  max_pargs_hwrap = 6
+
+  # If a cmdline positional group consumes more than this many lines without
+  # nesting, then invalidate the layout (and nest)
+  max_rows_cmdline = 2
+
+  # If true, separate flow control names from their parentheses with a space
+  separate_ctrl_name_with_space = False
+
+  # If true, separate function names from parentheses with a space
+  separate_fn_name_with_space = False
+
+  # If a statement is wrapped to more than one line, than dangle the closing
+  # parenthesis on its own line.
+  dangle_parens = False
+
+  # If the trailing parenthesis must be 'dangled' on its on line, then align it
+  # to this reference: `prefix`: the start of the statement,  `prefix-indent`:
+  # the start of the statement, plus one indentation  level, `child`: align to
+  # the column of the arguments
+  dangle_align = 'prefix'
+
+  # If the statement spelling length (including space and parenthesis) is
+  # smaller than this amount, then force reject nested layouts.
+  min_prefix_chars = 4
+
+  # If the statement spelling length (including space and parenthesis) is larger
+  # than the tab width by more than this amount, then force reject un-nested
+  # layouts.
+  max_prefix_chars = 10
+
+  # If a candidate layout is wrapped horizontally but it exceeds this many
+  # lines, then reject the layout.
+  max_lines_hwrap = 2
+
+  # What style line endings to use in the output.
+  line_ending = 'unix'
+
+  # Format command names consistently as 'lower' or 'upper' case
+  command_case = 'canonical'
+
+  # Format keywords consistently as 'lower' or 'upper' case
+  keyword_case = 'unchanged'
+
+  # A list of command names which should always be wrapped
+  always_wrap = []
+
+  # If true, the argument lists which are known to be sortable will be sorted
+  # lexicographicall
+  enable_sort = True
+
+  # If true, the parsers may infer whether or not an argument list is sortable
+  # (without annotation).
+  autosort = False
+
+  # By default, if cmake-format cannot successfully fit everything into the
+  # desired linewidth it will apply the last, most agressive attempt that it
+  # made. If this flag is True, however, cmake-format will print error, exit
+  # with non-zero status code, and write-out nothing
+  require_valid_layout = False
+
+  # A dictionary mapping layout nodes to a list of wrap decisions. See the
+  # documentation for more information.
+  layout_passes = {}
+
+# ------------------------------------------------
+# Options affecting comment reflow and formatting.
+# ------------------------------------------------
+with section("markup"):
+
+  # What character to use for bulleted lists
+  bullet_char = '*'
+
+  # What character to use as punctuation after numerals in an enumerated list
+  enum_char = '.'
+
+  # If comment markup is enabled, don't reflow the first comment block in each
+  # listfile. Use this to preserve formatting of your copyright/license
+  # statements.
+  first_comment_is_literal = True
+
+  # If comment markup is enabled, don't reflow any comment block which matches
+  # this (regex) pattern. Default is `None` (disabled).
+  literal_comment_pattern = None
+
+  # Regular expression to match preformat fences in comments default=
+  # ``r'^\s*([`~]{3}[`~]*)(.*)$'``
+  fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$'
+
+  # Regular expression to match rulers in comments default=
+  # ``r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'``
+  ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$'
+
+  # If a comment line matches starts with this pattern then it is explicitly a
+  # trailing comment for the preceeding argument. Default is '#<'
+  explicit_trailing_pattern = '#<'
+
+  # If a comment line starts with at least this many consecutive hash
+  # characters, then don't lstrip() them off. This allows for lazy hash rulers
+  # where the first hash char is not separated by space
+  hashruler_min_length = 10
+
+  # If true, then insert a space between the first hash char and remaining hash
+  # chars in a hash ruler, and normalize its length to fill the column
+  canonicalize_hashrulers = True
+
+  # enable comment markup parsing and reflow
+  enable_markup = True
+
+# ----------------------------
+# Options affecting the linter
+# ----------------------------
+with section("lint"):
+
+  # a list of lint codes to disable
+  disabled_codes = []
+
+  # regular expression pattern describing valid function names
+  function_pattern = '[0-9a-z_]+'
+
+  # regular expression pattern describing valid macro names
+  macro_pattern = '[0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with global
+  # (cache) scope
+  global_var_pattern = '[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with global
+  # scope (but internal semantic)
+  internal_var_pattern = '_[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with local
+  # scope
+  local_var_pattern = '[a-z][a-z0-9_]+'
+
+  # regular expression pattern describing valid names for privatedirectory
+  # variables
+  private_var_pattern = '_[0-9a-z_]+'
+
+  # regular expression pattern describing valid names for public directory
+  # variables
+  public_var_pattern = '[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for function/macro
+  # arguments and loop variables.
+  argument_var_pattern = '[a-z][a-z0-9_]+'
+
+  # regular expression pattern describing valid names for keywords used in
+  # functions or macros
+  keyword_pattern = '[A-Z][0-9A-Z_]+'
+
+  # In the heuristic for C0201, how many conditionals to match within a loop in
+  # before considering the loop a parser.
+  max_conditionals_custom_parser = 2
+
+  # Require at least this many newlines between statements
+  min_statement_spacing = 1
+
+  # Require no more than this many newlines between statements
+  max_statement_spacing = 2
+  max_returns = 6
+  max_branches = 12
+  max_arguments = 5
+  max_localvars = 15
+  max_statements = 50
+
+# -------------------------------
+# Options affecting file encoding
+# -------------------------------
+with section("encode"):
+
+  # If true, emit the unicode byte-order mark (BOM) at the start of the file
+  emit_byteorder_mark = False
+
+  # Specify the encoding of the input file. Defaults to utf-8
+  input_encoding = 'utf-8'
+
+  # Specify the encoding of the output file. Defaults to utf-8. Note that cmake
+  # only claims to support utf-8 so be careful when using anything else
+  output_encoding = 'utf-8'
+
+# -------------------------------------
+# Miscellaneous configurations options.
+# -------------------------------------
+with section("misc"):
+
+  # A dictionary containing any per-command configuration overrides. Currently
+  # only `command_case` is supported.
+  per_command = {}
diff --git a/third_party/libwebp/.pylintrc b/third_party/libwebp/.pylintrc
new file mode 100644
index 0000000..4658b84
--- /dev/null
+++ b/third_party/libwebp/.pylintrc
@@ -0,0 +1,441 @@
+# This Pylint rcfile contains a best-effort configuration to uphold the
+# best-practices and style described in the Google Python style guide:
+#   https://google.github.io/styleguide/pyguide.html
+#
+# Its canonical open-source location is:
+#   https://google.github.io/styleguide/pylintrc
+
+[MASTER]
+
+# Files or directories to be skipped. They should be base names, not paths.
+ignore=third_party
+
+# Files or directories matching the regex patterns are skipped. The regex
+# matches against base names, not paths.
+ignore-patterns=
+
+# Pickle collected data for later comparisons.
+persistent=no
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Use multiple processes to speed up Pylint.
+jobs=4
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
+confidence=
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=abstract-method,
+        apply-builtin,
+        arguments-differ,
+        attribute-defined-outside-init,
+        backtick,
+        bad-option-value,
+        basestring-builtin,
+        buffer-builtin,
+        c-extension-no-member,
+        consider-using-enumerate,
+        cmp-builtin,
+        cmp-method,
+        coerce-builtin,
+        coerce-method,
+        delslice-method,
+        div-method,
+        duplicate-code,
+        eq-without-hash,
+        execfile-builtin,
+        file-builtin,
+        filter-builtin-not-iterating,
+        fixme,
+        getslice-method,
+        global-statement,
+        hex-method,
+        idiv-method,
+        implicit-str-concat-in-sequence,
+        import-error,
+        import-self,
+        import-star-module-level,
+        inconsistent-return-statements,
+        input-builtin,
+        intern-builtin,
+        invalid-str-codec,
+        locally-disabled,
+        long-builtin,
+        long-suffix,
+        map-builtin-not-iterating,
+        misplaced-comparison-constant,
+        missing-function-docstring,
+        metaclass-assignment,
+        next-method-called,
+        next-method-defined,
+        no-absolute-import,
+        no-else-break,
+        no-else-continue,
+        no-else-raise,
+        no-else-return,
+        no-init,  # added
+        no-member,
+        no-name-in-module,
+        no-self-use,
+        nonzero-method,
+        oct-method,
+        old-division,
+        old-ne-operator,
+        old-octal-literal,
+        old-raise-syntax,
+        parameter-unpacking,
+        print-statement,
+        raising-string,
+        range-builtin-not-iterating,
+        raw_input-builtin,
+        rdiv-method,
+        reduce-builtin,
+        relative-import,
+        reload-builtin,
+        round-builtin,
+        setslice-method,
+        signature-differs,
+        standarderror-builtin,
+        suppressed-message,
+        sys-max-int,
+        too-few-public-methods,
+        too-many-ancestors,
+        too-many-arguments,
+        too-many-boolean-expressions,
+        too-many-branches,
+        too-many-instance-attributes,
+        too-many-locals,
+        too-many-nested-blocks,
+        too-many-public-methods,
+        too-many-return-statements,
+        too-many-statements,
+        trailing-newlines,
+        unichr-builtin,
+        unicode-builtin,
+        unnecessary-pass,
+        unpacking-in-except,
+        useless-else-on-loop,
+        useless-object-inheritance,
+        useless-suppression,
+        using-cmp-argument,
+        wrong-import-order,
+        xrange-builtin,
+        zip-builtin-not-iterating,
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]". This option is deprecated
+# and it will be removed in Pylint 2.0.
+files-output=no
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+
+[BASIC]
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=main,_,PRESUBMIT
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Include a hint for the correct naming format with invalid-name
+include-naming-hint=no
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
+
+# Regular expression matching correct function names
+function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
+
+# Regular expression matching correct variable names
+variable-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression matching correct constant names
+const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression matching correct attribute names
+attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
+
+# Regular expression matching correct argument names
+argument-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression matching correct class attribute names
+class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression matching correct inline iteration names
+inlinevar-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression matching correct class names
+class-rgx=^_?[A-Z][a-zA-Z0-9]*$
+
+# Regular expression matching correct module names
+module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
+
+# Regular expression matching correct method names
+method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=10
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis. It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
+# lines made too long by directives to pytype.
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=(?x)(
+  ^\s*(\#\ )?<?https?://\S+>?$|
+  ^\s*(from\s+\S+\s+)?import\s+.+$)
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=yes
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=
+
+# Maximum number of lines in a module
+max-module-lines=99999
+
+# String used as indentation unit.  The internal Google style guide mandates 2
+# spaces.  Google's externaly-published style guide says 4, consistent with
+# PEP 8.  Here, we use 2 spaces, for conformity with many open-sourced Google
+# projects (like TensorFlow).
+indent-string='  '
+
+# Number of spaces of indent required inside a hanging  or continued line.
+indent-after-paren=4
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=TODO
+
+
+[STRING]
+
+# This flag controls whether inconsistent-quotes generates a warning when the
+# character used as a quote delimiter is used inconsistently within a module.
+check-quote-consistency=yes
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the name of dummy variables (i.e. expectedly
+# not used).
+dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,_cb
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
+
+
+[LOGGING]
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format
+logging-modules=logging,absl.logging,tensorflow.io.logging
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+
+[SPELLING]
+
+# Spelling dictionary name. Available dictionaries: none. To make it working
+# install python-enchant package.
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to indicated private dictionary in
+# --spelling-private-dict-file option instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,
+                   TERMIOS,
+                   Bastion,
+                   rexec,
+                   sets
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant, absl
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,
+                      __new__,
+                      setUp
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+                  _fields,
+                  _replace,
+                  _source,
+                  _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls,
+                            class_
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=StandardError,
+                       Exception,
+                       BaseException
diff --git a/third_party/libwebp/.style.yapf b/third_party/libwebp/.style.yapf
new file mode 100644
index 0000000..0be981a
--- /dev/null
+++ b/third_party/libwebp/.style.yapf
@@ -0,0 +1,2 @@
+[style]
+based_on_style = yapf
\ No newline at end of file
diff --git a/third_party/libwebp/AUTHORS b/third_party/libwebp/AUTHORS
index 83c7b9c..8359b20 100644
--- a/third_party/libwebp/AUTHORS
+++ b/third_party/libwebp/AUTHORS
@@ -1,28 +1,45 @@
 Contributors:
+- Aidan O'Loan (aidanol at gmail dot com)
+- Alan Browning (browning at google dot com)
+- Alexandru Ardelean (ardeleanalex at gmail dot com)
+- Brian Ledger (brianpl at google dot com)
 - Charles Munger (clm at google dot com)
+- Cheng Yi (cyi at google dot com)
 - Christian Duvivier (cduvivier at google dot com)
+- Christopher Degawa (ccom at randomderp dot com)
+- Clement Courbet (courbet at google dot com)
 - Djordje Pesut (djordje dot pesut at imgtec dot com)
+- Frank Barchard (fbarchard at google dot com)
 - Hui Su (huisu at google dot com)
+- H. Vetinari (h dot vetinari at gmx dot com)
+- Ilya Kurdyukov (jpegqs at gmail dot com)
+- Ingvar Stepanyan (rreverser at google dot com)
 - James Zern (jzern at google dot com)
 - Jan Engelhardt (jengelh at medozas dot de)
 - Jehan (jehan at girinstud dot io)
-- Johann (johann dot koenig at duck dot com)
+- Jeremy Maitin-Shepard (jbms at google dot com)
+- Johann Koenig (johann dot koenig at duck dot com)
 - Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
 - Jyrki Alakuijala (jyrki at google dot com)
+- Konstantin Ivlev (tomskside at gmail dot com)
 - Lode Vandevenne (lode at google dot com)
 - Lou Quillio (louquillio at google dot com)
 - Mans Rullgard (mans at mansr dot com)
 - Marcin Kowalczyk (qrczak at google dot com)
 - Martin Olsson (mnemo at minimum dot se)
+- Maryla Ustarroz-Calonge (maryla at google dot com)
 - Mikołaj Zalewski (mikolajz at google dot com)
 - Mislav Bradac (mislavm at google dot com)
 - Nico Weber (thakis at chromium dot org)
 - Noel Chromium (noel at chromium dot org)
+- Nozomi Isozaki (nontan at pixiv dot co dot jp)
+- Oliver Wolff (oliver dot wolff at qt dot io)
 - Owen Rodley (orodley at google dot com)
 - Parag Salasakar (img dot mips1 at gmail dot com)
 - Pascal Massimino (pascal dot massimino at gmail dot com)
 - Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
 - Pierre Joye (pierre dot php at gmail dot com)
+- Roberto Alanis (alanisbaez at google dot com)
 - Sam Clegg (sbc at chromium dot org)
 - Scott Hancher (seh at google dot com)
 - Scott LaVarnway (slavarnway at google dot com)
@@ -31,9 +48,13 @@
 - Somnath Banerjee (somnath dot banerjee at gmail dot com)
 - Sriraman Tallam (tmsriram at google dot com)
 - Tamar Levy (tamar dot levy at intel dot com)
+- Thiago Perrotta (tperrotta at google dot com)
 - Timothy Gu (timothygu99 at gmail dot com)
 - Urvang Joshi (urvang at google dot com)
 - Vikas Arora (vikasa at google dot com)
 - Vincent Rabaud (vrabaud at google dot com)
 - Vlad Tsyrklevich (vtsyrklevich at chromium dot org)
+- Wan-Teh Chang (wtc at google dot com)
 - Yang Zhang (yang dot zhang at arm dot com)
+- Yannis Guyon (yguyon at google dot com)
+- Zhi An Ng (zhin at chromium dot org)
diff --git a/third_party/libwebp/Android.mk b/third_party/libwebp/Android.mk
index 6752f77..9d16f08 100644
--- a/third_party/libwebp/Android.mk
+++ b/third_party/libwebp/Android.mk
@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 WEBP_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD
@@ -33,6 +35,15 @@
   NEON := c
 endif
 
+sharpyuv_srcs := \
+    sharpyuv/sharpyuv.c \
+    sharpyuv/sharpyuv_cpu.c \
+    sharpyuv/sharpyuv_csp.c \
+    sharpyuv/sharpyuv_dsp.c \
+    sharpyuv/sharpyuv_gamma.c \
+    sharpyuv/sharpyuv_neon.$(NEON) \
+    sharpyuv/sharpyuv_sse2.c \
+
 dec_srcs := \
     src/dec/alpha_dec.c \
     src/dec/buffer_dec.c \
@@ -74,6 +85,7 @@
     src/dsp/lossless_msa.c \
     src/dsp/lossless_neon.$(NEON) \
     src/dsp/lossless_sse2.c \
+    src/dsp/lossless_sse41.c \
     src/dsp/rescaler.c \
     src/dsp/rescaler_mips32.c \
     src/dsp/rescaler_mips_dsp_r2.c \
@@ -97,9 +109,9 @@
     src/dsp/cost.c \
     src/dsp/cost_mips32.c \
     src/dsp/cost_mips_dsp_r2.c \
+    src/dsp/cost_neon.$(NEON) \
     src/dsp/cost_sse2.c \
     src/dsp/enc.c \
-    src/dsp/enc_avx2.c \
     src/dsp/enc_mips32.c \
     src/dsp/enc_mips_dsp_r2.c \
     src/dsp/enc_msa.c \
@@ -174,7 +186,7 @@
     $(utils_dec_srcs) \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
 
 # prefer arm over thumb mode for performance gains
 LOCAL_ARM_MODE := arm
@@ -203,12 +215,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
+    $(sharpyuv_srcs) \
     $(dsp_enc_srcs) \
     $(enc_srcs) \
     $(utils_enc_srcs) \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src $(LOCAL_PATH)
 
 # prefer arm over thumb mode for performance gains
 LOCAL_ARM_MODE := arm
@@ -231,7 +244,7 @@
 LOCAL_SRC_FILES := $(demux_srcs)
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
 
 # prefer arm over thumb mode for performance gains
 LOCAL_ARM_MODE := arm
@@ -254,7 +267,7 @@
 LOCAL_SRC_FILES := $(mux_srcs)
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
 
 # prefer arm over thumb mode for performance gains
 LOCAL_ARM_MODE := arm
@@ -278,3 +291,4 @@
 ifeq ($(USE_CPUFEATURES),yes)
   $(call import-module,android/cpufeatures)
 endif
+endif  # NDK_ROOT
diff --git a/third_party/libwebp/BUILD.gn b/third_party/libwebp/BUILD.gn
index 8b6c476..537325c 100644
--- a/third_party/libwebp/BUILD.gn
+++ b/third_party/libwebp/BUILD.gn
@@ -25,6 +25,14 @@
       "//starboard/build/config:speed",
       ":libwebp_direct_config",
     ]
+    if (is_win) {
+      cflags_c = [ "/wd4312" ]  # warning C4312: 'type cast': conversion from 'int' to 'int *'
+    } else {
+      cflags_c = [
+        "-Wno-implicit-function-declaration",
+        "-Wno-int-to-pointer-cast",
+      ]
+    }
   }
 }
 
@@ -83,6 +91,11 @@
   sources = libwebp_enc_sources
 }
 
+libwebp_lib("libwebp_sharpyuv") {
+  sources = libwebp_sharpyuv_sources
+  deps = [ ":libwebp_dsp_dec_common" ]
+}
+
 libwebp_lib("libwebp_dsp_enc") {
   sources = libwebp_dsp_enc_sources
 }
@@ -93,7 +106,7 @@
 
 config("libwebp_direct_config") {
   include_dirs = [ "." ]
-  if (is_starboard && !is_win) {
+  if (is_starboard && (target_os == "android" || target_os == "linux")) {
     if (current_cpu == "x64" || current_cpu == "x86") {
       cflags = [
         "-msse2",
@@ -113,8 +126,7 @@
       ]
       defines += [ "WEBP_HAVE_AVX2" ]
     }
-    if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon &&
-        (target_os == "android" || target_os == "linux")) {
+    if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon ) {
       defines = [ "WEBP_HAVE_NEON" ]
       cflags = [ "-mfpu=neon" ]
     }
@@ -129,6 +141,7 @@
     ":libwebp_dsp_dec_common",
     ":libwebp_dsp_enc",
     ":libwebp_enc",
+    ":libwebp_sharpyuv",
     ":libwebp_utils_dec",
     ":libwebp_utils_enc",
   ]
diff --git a/third_party/libwebp/CMakeLists.txt b/third_party/libwebp/CMakeLists.txt
index ea263b3..ad5e14c 100644
--- a/third_party/libwebp/CMakeLists.txt
+++ b/third_party/libwebp/CMakeLists.txt
@@ -1,79 +1,219 @@
-cmake_minimum_required(VERSION 2.8.7)
+#  Copyright (c) 2020 Google LLC.
+#
+#  Use of this source code is governed by a BSD-style license
+#  that can be found in the LICENSE file in the root of the source
+#  tree. An additional intellectual property rights grant can be found
+#  in the file PATENTS.  All contributing project authors may
+#  be found in the AUTHORS file in the root of the source tree.
 
-project(libwebp C)
-
-# Options for coder / decoder executables.
-option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON)
-option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
-option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
-option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
-option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
-option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." OFF)
-option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
-option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
-option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
-
-if(WEBP_BUILD_WEBP_JS)
-  set(WEBP_ENABLE_SIMD OFF)
+if(APPLE)
+  cmake_minimum_required(VERSION 3.17)
+else()
+  cmake_minimum_required(VERSION 3.7)
 endif()
 
+if(POLICY CMP0072)
+  cmake_policy(SET CMP0072 NEW)
+endif()
+
+project(WebP C)
+
+# Options for coder / decoder executables.
+if(BUILD_SHARED_LIBS)
+  set(WEBP_LINK_STATIC_DEFAULT OFF)
+else()
+  set(WEBP_LINK_STATIC_DEFAULT ON)
+endif()
+option(WEBP_LINK_STATIC
+       "Link using static libraries. If OFF, use dynamic libraries."
+       ${WEBP_LINK_STATIC_DEFAULT})
+if(NOT EMSCRIPTEN)
+  # Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature.
+  # Users can still explicitly opt-in to make a SIMD-enabled build.
+  set(WEBP_ENABLE_SIMD_DEFAULT ON)
+endif()
+option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
+       ${WEBP_ENABLE_SIMD_DEFAULT})
+option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
+option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
+option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
+option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON)
+option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." ON)
+option(WEBP_BUILD_VWEBP "Build the vwebp viewer tool." ON)
+option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." ON)
+option(WEBP_BUILD_LIBWEBPMUX "Build the libwebpmux library." ON)
+option(WEBP_BUILD_WEBPMUX "Build the webpmux command line tool." ON)
+option(WEBP_BUILD_EXTRAS "Build extras." ON)
+option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
+option(WEBP_USE_THREAD "Enable threading support" ON)
+option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
+option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
+       OFF)
+set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
+set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
+
+if(WEBP_LINK_STATIC)
+  if(WIN32)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  endif()
+  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+  # vwebp does not compile on Ubuntu with static libraries so disabling it for
+  # now.
+  set(WEBP_BUILD_VWEBP OFF)
+endif()
+
+# Option needed for handling Unicode file names on Windows.
+if(WIN32)
+  option(WEBP_UNICODE "Build Unicode executables." ON)
+endif()
+
+if(WEBP_BUILD_WEBP_JS)
+  set(WEBP_BUILD_ANIM_UTILS OFF)
+  set(WEBP_BUILD_CWEBP OFF)
+  set(WEBP_BUILD_DWEBP OFF)
+  set(WEBP_BUILD_GIF2WEBP OFF)
+  set(WEBP_BUILD_IMG2WEBP OFF)
+  set(WEBP_BUILD_VWEBP OFF)
+  set(WEBP_BUILD_WEBPINFO OFF)
+  set(WEBP_BUILD_WEBPMUX OFF)
+  set(WEBP_BUILD_EXTRAS OFF)
+  set(WEBP_USE_THREAD OFF)
+
+  if(WEBP_ENABLE_SIMD)
+    message(NOTICE
+            "wasm2js does not support SIMD, disabling webp.js generation.")
+  endif()
+endif()
+
+set(SHARPYUV_DEP_LIBRARIES)
+set(SHARPYUV_DEP_INCLUDE_DIRS)
 set(WEBP_DEP_LIBRARIES)
 set(WEBP_DEP_INCLUDE_DIRS)
 
 if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE "Release" CACHE
-    "Build type: Release, Debug or RelWithDebInfo" STRING FORCE
-  )
+  set(CMAKE_BUILD_TYPE "Release"
+      CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
+            FORCE)
 endif()
 
 # Include dependencies.
+if(WEBP_BUILD_ANIM_UTILS
+   OR WEBP_BUILD_CWEBP
+   OR WEBP_BUILD_DWEBP
+   OR WEBP_BUILD_EXTRAS
+   OR WEBP_BUILD_GIF2WEBP
+   OR WEBP_BUILD_IMG2WEBP)
+  set(WEBP_FIND_IMG_LIBS TRUE)
+else()
+  set(WEBP_FIND_IMG_LIBS FALSE)
+endif()
 include(cmake/deps.cmake)
+include(GNUInstallDirs)
 
-################################################################################
+if(BUILD_SHARED_LIBS AND NOT DEFINED CMAKE_INSTALL_RPATH)
+  # Set the rpath to match autoconf/libtool behavior. Note this must be set
+  # before target creation.
+  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+
+# ##############################################################################
 # Options.
 if(WEBP_ENABLE_SWAP_16BIT_CSP)
   add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
 endif()
 
-################################################################################
+if(NOT WEBP_BITTRACE STREQUAL "0")
+  add_definitions(-DBITTRACE=${WEBP_BITTRACE})
+endif()
+
+if(WEBP_UNICODE)
+  # Windows recommends setting both UNICODE and _UNICODE.
+  add_definitions(-DUNICODE -D_UNICODE)
+endif()
+
+if(MSVC AND BUILD_SHARED_LIBS)
+  add_definitions(-DWEBP_DLL)
+endif()
+
+# pkg-config variables used by *.pc.in.
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix "\${prefix}")
+if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
+  set(libdir "${CMAKE_INSTALL_LIBDIR}")
+else()
+  set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
+  set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
+else()
+  set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
+endif()
+set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
+set(INSTALLED_LIBRARIES)
+
+if(MSVC)
+  # match the naming convention used by nmake
+  set(webp_libname_prefix "lib")
+  set(CMAKE_SHARED_LIBRARY_PREFIX "${webp_libname_prefix}")
+  set(CMAKE_IMPORT_LIBRARY_PREFIX "${webp_libname_prefix}")
+  set(CMAKE_STATIC_LIBRARY_PREFIX "${webp_libname_prefix}")
+endif()
+
+set(CMAKE_C_VISIBILITY_PRESET hidden)
+
+# ##############################################################################
 # Android only.
 if(ANDROID)
   include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
-  add_library(cpufeatures STATIC
-    ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c
-  )
-  target_link_libraries(cpufeatures dl)
-  set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
-  set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
-    ${ANDROID_NDK}/sources/android/cpufeatures
-  )
+  add_library(cpufeatures-webp STATIC
+              ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
+  list(APPEND INSTALLED_LIBRARIES cpufeatures-webp)
+  target_link_libraries(cpufeatures-webp dl)
+  set(SHARPYUV_DEP_LIBRARIES ${SHARPYUV_DEP_LIBRARIES} cpufeatures-webp)
+  set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures-webp)
+  set(cpufeatures_include_dir ${ANDROID_NDK}/sources/android/cpufeatures)
+  set(SHARPYUV_DEP_INCLUDE_DIRS ${SHARPYUV_DEP_INCLUDE_DIRS}
+                                ${cpufeatures_include_dir})
+  set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${cpufeatures_include_dir})
   add_definitions(-DHAVE_CPU_FEATURES_H=1)
   set(HAVE_CPU_FEATURES_H 1)
 else()
   set(HAVE_CPU_FEATURES_H 0)
 endif()
 
-################################################################################
-# WebP source files.
-# Read the Makefile.am to get the source files.
+function(configure_pkg_config FILE)
+  configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
+                 "${CMAKE_CURRENT_BINARY_DIR}/${FILE}" @ONLY)
 
-# We expect the Makefiles to define the sources as defined in
-# the first regex. E.g.:
-# libimagedec_la_SOURCES  = image_dec.c image_dec.h
+  if(HAVE_MATH_LIBRARY)
+    # MSVC doesn't have libm
+    file(READ ${CMAKE_CURRENT_BINARY_DIR}/${FILE} data)
+    string(REPLACE "-lm" "" data ${data})
+    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data})
+  endif()
+
+  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
+          DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+endfunction()
+
+# ##############################################################################
+# WebP source files. Read the Makefile.am to get the source files.
+
+# We expect the Makefiles to define the sources as defined in the first regex.
+# E.g.: libimagedec_la_SOURCES  = image_dec.c image_dec.h
 function(parse_Makefile_am FOLDER VAR SRC_REGEX)
   file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
   string(REGEX MATCHALL "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
-    FILES_PER_LINE ${MAKEFILE_AM}
-  )
+               FILES_PER_LINE ${MAKEFILE_AM})
   set(SRCS ${${VAR}})
   foreach(FILES ${FILES_PER_LINE})
     string(FIND ${FILES} "=" OFFSET)
     math(EXPR OFFSET "${OFFSET} + 2")
     string(SUBSTRING ${FILES} ${OFFSET} -1 FILES)
     if(FILES)
-      string(REGEX MATCHALL "[0-9a-z\\._]+"
-        FILES ${FILES}
-      )
+      string(REGEX MATCHALL "[0-9a-z\\._]+" FILES ${FILES})
       foreach(FILE ${FILES})
         list(APPEND SRCS ${FOLDER}/${FILE})
       endforeach()
@@ -83,16 +223,16 @@
 endfunction()
 
 set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
-parse_Makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "")
-parse_Makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "")
-parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON")
-parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC")
-parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*")
-parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
-parse_Makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
-parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
-parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
-parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
+parse_makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "")
+parse_makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "")
+parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON")
+parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC")
+parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*")
+parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
+parse_makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
+parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
+parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
+parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
 
 # Remove the files specific to SIMD we don't use.
 foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
@@ -100,262 +240,555 @@
   list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE})
 endforeach()
 
-### Define the mandatory libraries.
+# Generate the config.h file.
+configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
+               ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h @ONLY)
+add_definitions(-DHAVE_CONFIG_H)
+
+# Set the version numbers.
+macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
+  file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} SOURCE_FILE)
+  string(REGEX MATCH
+               "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP
+               ${SOURCE_FILE})
+  string(REGEX MATCH "[0-9:]+" TMP ${TMP})
+  string(REGEX REPLACE ":" " " LT_VERSION ${TMP})
+
+  # See the libtool docs for more information:
+  # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
+  #
+  # c=<current>, a=<age>, r=<revision>
+  #
+  # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
+  # passed to libtool.
+  #
+  # We set FULL = [c-a].a.r and MAJOR = [c-a].
+  separate_arguments(LT_VERSION)
+  list(GET LT_VERSION 0 LT_CURRENT)
+  list(GET LT_VERSION 1 LT_REVISION)
+  list(GET LT_VERSION 2 LT_AGE)
+  math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
+
+  set_target_properties(
+    ${TARGET_NAME}
+    PROPERTIES VERSION ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
+               SOVERSION ${LT_CURRENT_MINUS_AGE})
+  if(APPLE)
+    # For compatibility, set MACHO_COMPATIBILITY_VERSION and
+    # MACHO_CURRENT_VERSION to match libtool. These properties were introduced
+    # in 3.17:
+    # https://cmake.org/cmake/help/latest/prop_tgt/MACHO_COMPATIBILITY_VERSION.html
+    math(EXPR LIBWEBP_MACHO_COMPATIBILITY_VERSION "${LT_CURRENT} + 1")
+    set_target_properties(
+      ${TARGET_NAME}
+      PROPERTIES MACHO_COMPATIBILITY_VERSION
+                 ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}
+                 MACHO_CURRENT_VERSION
+                 ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}.${LT_REVISION})
+  endif()
+endmacro()
+
+# ##############################################################################
 # Build the webpdecoder library.
+
+# Creates a source file with an unused stub function in $CMAKE_BINARY_DIR and
+# adds it to the specified target. Currently used only with Xcode.
+#
+# See also:
+# https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
+# "Some native build systems (such as Xcode) may not like targets that have only
+# object files, so consider adding at least one real source file to any target
+# that references $<TARGET_OBJECTS:objlib>."
+function(libwebp_add_stub_file TARGET)
+  set(stub_source_dir "${CMAKE_BINARY_DIR}")
+  set(stub_source_file "${stub_source_dir}/libwebp_${TARGET}_stub.c")
+  set(stub_source_code
+      "// Generated file. DO NOT EDIT!\n"
+      "// C source file created for target ${TARGET}.\n"
+      "void libwebp_${TARGET}_stub_function(void)\;\n"
+      "void libwebp_${TARGET}_stub_function(void) {}\n")
+  file(WRITE "${stub_source_file}" ${stub_source_code})
+
+  target_sources(${TARGET} PRIVATE ${stub_source_file})
+endfunction()
+
+parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS" "")
+add_library(sharpyuv ${WEBP_SHARPYUV_SRCS})
+target_link_libraries(sharpyuv ${SHARPYUV_DEP_LIBRARIES})
+set_version(sharpyuv/Makefile.am sharpyuv sharpyuv)
+target_include_directories(
+  sharpyuv PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                   ${CMAKE_CURRENT_SOURCE_DIR}/src)
+set_target_properties(
+  sharpyuv
+  PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h")
+configure_pkg_config("sharpyuv/libsharpyuv.pc")
+install(
+  TARGETS sharpyuv
+  EXPORT ${PROJECT_NAME}Targets
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp/sharpyuv
+  INCLUDES
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  ${CMAKE_INSTALL_INCLUDEDIR}/webp
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
 if(MSVC)
   # avoid security warnings for e.g., fopen() used in the examples.
   add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 else()
-  add_definitions(-Wall)
+  add_compile_options(-Wall)
 endif()
-include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${WEBP_DEP_INCLUDE_DIRS})
+include_directories(${WEBP_DEP_INCLUDE_DIRS})
 add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
+target_include_directories(webpdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                              ${CMAKE_CURRENT_SOURCE_DIR})
 add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
+target_include_directories(webpdspdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                 ${CMAKE_CURRENT_SOURCE_DIR})
 add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
-  ${WEBP_UTILS_DEC_SRCS})
-add_library(webpdecoder $<TARGET_OBJECTS:webpdecode>
-  $<TARGET_OBJECTS:webpdspdecode> $<TARGET_OBJECTS:webputilsdecode>)
+                                   ${WEBP_UTILS_DEC_SRCS})
+target_include_directories(webputilsdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                   ${CMAKE_CURRENT_SOURCE_DIR})
+add_library(
+  webpdecoder $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdspdecode>
+              $<TARGET_OBJECTS:webputilsdecode>)
+if(XCODE)
+  libwebp_add_stub_file(webpdecoder)
+endif()
 target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
+target_include_directories(
+  webpdecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+  INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+            $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+set_target_properties(
+  webpdecoder
+  PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
+
+configure_pkg_config("src/libwebpdecoder.pc")
 
 # Build the webp library.
 add_library(webpencode OBJECT ${WEBP_ENC_SRCS})
+target_include_directories(
+  webpencode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                     ${CMAKE_CURRENT_SOURCE_DIR}/src)
 add_library(webpdsp OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS}
-  ${WEBP_DSP_ENC_SRCS})
+                           ${WEBP_DSP_ENC_SRCS})
+target_include_directories(webpdsp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                           ${CMAKE_CURRENT_SOURCE_DIR})
 add_library(webputils OBJECT ${WEBP_UTILS_COMMON_SRCS} ${WEBP_UTILS_DEC_SRCS}
-  ${WEBP_UTILS_ENC_SRCS})
+                             ${WEBP_UTILS_ENC_SRCS})
+target_include_directories(webputils PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                             ${CMAKE_CURRENT_SOURCE_DIR})
 add_library(webp $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdsp>
-  $<TARGET_OBJECTS:webpencode> $<TARGET_OBJECTS:webputils>)
+                 $<TARGET_OBJECTS:webpencode> $<TARGET_OBJECTS:webputils>)
+target_link_libraries(webp sharpyuv)
+if(XCODE)
+  libwebp_add_stub_file(webp)
+endif()
 target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
+target_include_directories(
+  webp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+         $<INSTALL_INTERFACE:include>)
+set_target_properties(
+  webp
+  PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
 
-# Make sure the OBJECT libraries are built with position independent code
-# (it is not ON by default).
-set_target_properties(webpdecode webpdspdecode webputilsdecode
-  webpencode webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON)
+# Make sure the OBJECT libraries are built with position independent code (it is
+# not ON by default).
+set_target_properties(webpdecode webpdspdecode webputilsdecode webpencode
+                      webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON)
+configure_pkg_config("src/libwebp.pc")
 
 # Build the webp demux library.
 add_library(webpdemux ${WEBP_DEMUX_SRCS})
 target_link_libraries(webpdemux webp)
+target_include_directories(
+  webpdemux PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+  PUBLIC $<INSTALL_INTERFACE:include>)
+set_target_properties(
+  webpdemux
+  PROPERTIES
+    PUBLIC_HEADER
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
 
-# Set the version numbers.
-function(parse_version FILE NAME VAR)
-  file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
-  string(REGEX MATCH "${NAME}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP
-    ${SOURCE_FILE})
-  string(REGEX MATCH "[0-9:]+" TMP ${TMP})
-  string(REGEX REPLACE ":" "." VERSION ${TMP})
-  set(${VAR} "${VERSION}" PARENT_SCOPE)
-endfunction()
-parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
-set_target_properties(webp PROPERTIES VERSION ${PACKAGE_VERSION}
-  SOVERSION ${WEBP_WEBP_SOVERSION})
-parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
-set_target_properties(webpdecoder PROPERTIES VERSION ${PACKAGE_VERSION}
-  SOVERSION ${WEBP_DECODER_SOVERSION})
-parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
-set_target_properties(webpdemux PROPERTIES VERSION ${PACKAGE_VERSION}
-  SOVERSION ${WEBP_DEMUX_SOVERSION})
+configure_pkg_config("src/demux/libwebpdemux.pc")
+
+set_version(src/Makefile.am webp webp)
+set_version(src/Makefile.am webpdecoder webpdecoder)
+set_version(src/demux/Makefile.am webpdemux webpdemux)
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
+string(REGEX MATCH "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]" TMP ${CONFIGURE_FILE})
+string(REGEX MATCH "[0-9\\.]+" PROJECT_VERSION ${TMP})
 
 # Define the libraries to install.
-set(INSTALLED_LIBRARIES webpdecoder webp webpdemux)
+list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux)
 
-### Deal with SIMD.
-# Change the compile flags for SIMD files we use.
+# Deal with SIMD. Change the compile flags for SIMD files we use.
 list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
 math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
-  "${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1"
-)
+     "${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1")
 
 foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
   list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
   list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
-  set_source_files_properties(${FILE} PROPERTIES
-    COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
-  )
+  set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS
+                                                 ${SIMD_COMPILE_FLAG})
 endforeach()
 
-# Build the executables if asked for.
-if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
-   WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP OR WEBP_BUILD_WEBP_JS)
-  # Example utility library.
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
-    "example_util_[^ ]*")
-  list(APPEND EXAMPLEUTIL_SRCS
-    ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
-  add_library(exampleutil ${EXAMPLEUTIL_SRCS})
+if(NOT WEBP_BUILD_LIBWEBPMUX)
+  set(WEBP_BUILD_GIF2WEBP OFF)
+  set(WEBP_BUILD_IMG2WEBP OFF)
+  set(WEBP_BUILD_WEBPMUX OFF)
+endif()
 
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
-    "imageio_util_[^ ]*")
-  add_library(imageioutil ${IMAGEIOUTILS_SRCS})
+if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
+  set(WEBP_BUILD_GIF2WEBP OFF)
+endif()
+
+if(WEBP_BUILD_ANIM_UTILS AND NOT GIF_FOUND)
+  set(WEBP_BUILD_ANIM_UTILS OFF)
+endif()
+
+# Build the executables if asked for.
+if(WEBP_BUILD_ANIM_UTILS
+   OR WEBP_BUILD_CWEBP
+   OR WEBP_BUILD_DWEBP
+   OR WEBP_BUILD_GIF2WEBP
+   OR WEBP_BUILD_IMG2WEBP
+   OR WEBP_BUILD_VWEBP
+   OR WEBP_BUILD_WEBPMUX
+   OR WEBP_BUILD_WEBPINFO)
+  # Example utility library.
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
+                    "example_util_[^ ]*")
+  list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
+  add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
+  target_include_directories(
+    exampleutil PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
+
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
+                    "imageio_util_[^ ]*")
+  add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
   target_link_libraries(imageioutil webp)
+  target_link_libraries(exampleutil imageioutil)
 
   # Image-decoding utility library.
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
-    "imagedec_[^ ]*")
-  add_library(imagedec ${IMAGEDEC_SRCS})
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
+                    "imagedec_[^ ]*")
+  add_library(imagedec STATIC ${IMAGEDEC_SRCS})
   target_link_libraries(imagedec imageioutil webpdemux webp
-    ${WEBP_DEP_IMG_LIBRARIES})
+                        ${WEBP_DEP_IMG_LIBRARIES})
 
   # Image-encoding utility library.
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
-    "imageenc_[^ ]*")
-  add_library(imageenc ${IMAGEENC_SRCS})
-  target_link_libraries(imageenc webp)
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
+                    "imageenc_[^ ]*")
+  add_library(imageenc STATIC ${IMAGEENC_SRCS})
+  target_link_libraries(imageenc imageioutil webp)
 
-  set_property(TARGET exampleutil imageioutil imagedec imageenc
-    PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  set_property(
+    TARGET exampleutil imageioutil imagedec imageenc
+    PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
+             ${CMAKE_CURRENT_BINARY_DIR}/src)
 endif()
 
 if(WEBP_BUILD_DWEBP)
   # dwebp
-  include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS"
-    "dwebp")
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" "dwebp")
   add_executable(dwebp ${DWEBP_SRCS})
-  target_link_libraries(dwebp exampleutil imagedec imageenc webpdecoder)
-  install(TARGETS dwebp RUNTIME DESTINATION bin)
-  set_property(TARGET dwebp PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_link_libraries(dwebp exampleutil imagedec imageenc)
+  target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
 if(WEBP_BUILD_CWEBP)
   # cwebp
-  include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS"
-    "cwebp")
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp")
   add_executable(cwebp ${CWEBP_SRCS})
   target_link_libraries(cwebp exampleutil imagedec webp)
-  install(TARGETS cwebp RUNTIME DESTINATION bin)
-  set_property(TARGET cwebp PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                           ${CMAKE_CURRENT_SOURCE_DIR})
+  install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
-if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
-  unset(WEBP_BUILD_GIF2WEBP CACHE)
-endif()
-
-if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS"
-    "")
-  add_library(webpmux ${WEBP_MUX_SRCS})
-  target_link_libraries(webpmux webp)
-  parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
-  set_target_properties(webpmux PROPERTIES VERSION ${PACKAGE_VERSION}
-    SOVERSION ${WEBP_MUX_SOVERSION})
-  list(APPEND INSTALLED_LIBRARIES webpmux)
+if(WEBP_BUILD_LIBWEBPMUX)
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
+  add_library(libwebpmux ${WEBP_MUX_SRCS})
+  target_link_libraries(libwebpmux webp)
+  target_include_directories(libwebpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                ${CMAKE_CURRENT_SOURCE_DIR})
+  set_version(src/mux/Makefile.am libwebpmux webpmux)
+  set_target_properties(
+    libwebpmux
+    PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;")
+  set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux)
+  list(APPEND INSTALLED_LIBRARIES libwebpmux)
+  configure_pkg_config("src/mux/libwebpmux.pc")
 endif()
 
 if(WEBP_BUILD_GIF2WEBP)
   # gif2webp
   include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS})
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
-    "gif2webp")
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
+                    "gif2webp")
   add_executable(gif2webp ${GIF2WEBP_SRCS})
-  target_link_libraries(gif2webp exampleutil imageioutil webp webpmux
-    ${WEBP_DEP_GIF_LIBRARIES})
-  install(TARGETS gif2webp RUNTIME DESTINATION bin)
-  set_property(TARGET gif2webp PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_link_libraries(gif2webp exampleutil imageioutil webp libwebpmux
+                        ${WEBP_DEP_GIF_LIBRARIES})
+  target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
 if(WEBP_BUILD_IMG2WEBP)
   # img2webp
   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
-    "img2webp")
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
+                    "img2webp")
   add_executable(img2webp ${IMG2WEBP_SRCS})
-  target_link_libraries(img2webp exampleutil imagedec imageioutil webp webpmux)
-  install(TARGETS img2webp RUNTIME DESTINATION bin)
-  set_property(TARGET img2webp PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_link_libraries(img2webp exampleutil imagedec imageioutil webp
+                        libwebpmux)
+  target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                              ${CMAKE_CURRENT_SOURCE_DIR})
+  install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
-if (WEBP_BUILD_WEBPINFO)
+if(WEBP_BUILD_VWEBP)
+  # vwebp
+  find_package(GLUT)
+  if(GLUT_FOUND)
+    include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
+    parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "VWEBP_SRCS" "vwebp")
+    add_executable(vwebp ${VWEBP_SRCS})
+    target_link_libraries(
+      vwebp
+      ${OPENGL_LIBRARIES}
+      exampleutil
+      GLUT::GLUT
+      imageioutil
+      webp
+      webpdemux)
+    target_include_directories(
+      vwebp PRIVATE ${GLUT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src
+                    ${OPENGL_INCLUDE_DIR})
+    install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+    if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+      check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED)
+      if(HAS_NO_DEPRECATED)
+        target_compile_options(vwebp PRIVATE "-Wno-deprecated-declarations")
+      endif()
+    endif()
+  endif()
+endif()
+
+if(WEBP_BUILD_WEBPINFO)
   # webpinfo
   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
-  parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS"
-    "webpinfo")
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS"
+                    "webpinfo")
   add_executable(webpinfo ${WEBPINFO_SRCS})
   target_link_libraries(webpinfo exampleutil imageioutil)
-  install(TARGETS webpinfo RUNTIME DESTINATION bin)
-  set_property(TARGET webpinfo PROPERTY INCLUDE_DIRECTORIES
-    ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                              ${CMAKE_CURRENT_SOURCE_DIR}/src)
+  install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
+
+if(WEBP_BUILD_WEBPMUX)
+  # webpmux
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPMUX_SRCS"
+                    "webpmux")
+  add_executable(webpmux ${WEBPMUX_SRCS})
+  target_link_libraries(webpmux exampleutil imageioutil libwebpmux webp)
+  target_include_directories(webpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  install(TARGETS webpmux RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
+
+if(WEBP_BUILD_EXTRAS)
+  set(EXTRAS_MAKEFILE "${CMAKE_CURRENT_SOURCE_DIR}/extras")
+  parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_EXTRAS_SRCS" "libwebpextras_la")
+  parse_makefile_am(${EXTRAS_MAKEFILE} "GET_DISTO_SRCS" "get_disto")
+  parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_QUALITY_SRCS" "webp_quality")
+  parse_makefile_am(${EXTRAS_MAKEFILE} "VWEBP_SDL_SRCS" "vwebp_sdl")
+
+  # libextras
+  add_library(extras STATIC ${WEBP_EXTRAS_SRCS})
+  target_include_directories(
+    extras PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                   ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+  # get_disto
+  add_executable(get_disto ${GET_DISTO_SRCS})
+  target_link_libraries(get_disto imagedec)
+  target_include_directories(get_disto PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+                                               ${CMAKE_CURRENT_BINARY_DIR}/src)
+
+  # webp_quality
+  add_executable(webp_quality ${WEBP_QUALITY_SRCS})
+  target_link_libraries(webp_quality exampleutil imagedec extras)
+  target_include_directories(webp_quality PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+                                                  ${CMAKE_CURRENT_BINARY_DIR})
+
+  # vwebp_sdl
+  find_package(SDL)
+  if(WEBP_BUILD_VWEBP AND SDL_FOUND)
+    add_executable(vwebp_sdl ${VWEBP_SDL_SRCS})
+    target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
+    target_include_directories(
+      vwebp_sdl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+                        ${CMAKE_CURRENT_BINARY_DIR}/src ${SDL_INCLUDE_DIR})
+    set(WEBP_HAVE_SDL 1)
+    target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
+  endif()
 endif()
 
 if(WEBP_BUILD_WEBP_JS)
-  # JavaScript version
-  add_executable(webp_js
-                 ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
-  target_link_libraries(webp_js webpdecoder SDL)
-  set(WEBP_HAVE_SDL 1)
-  set_target_properties(webp_js PROPERTIES LINK_FLAGS
-      "-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-       -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
-  set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
-  target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
+  # The default stack size changed from 5MB to 64KB in 3.1.27. See
+  # https://crbug.com/webp/614.
+  if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "3.1.27")
+    # TOTAL_STACK size was renamed to STACK_SIZE in 3.1.27. The old name was
+    # kept for compatibility, but prefer the new one in case it is removed in
+    # the future.
+    set(emscripten_stack_size "-sSTACK_SIZE=5MB")
+  else()
+    set(emscripten_stack_size "-sTOTAL_STACK=5MB")
+  endif()
+  # wasm2js does not support SIMD.
+  if(NOT WEBP_ENABLE_SIMD)
+    # JavaScript version
+    add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
+    target_link_libraries(webp_js webpdecoder SDL)
+    target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+    set(WEBP_HAVE_SDL 1)
+    set_target_properties(
+      webp_js
+      PROPERTIES LINK_FLAGS "-sWASM=0 ${emscripten_stack_size} \
+         -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+         -sEXPORTED_RUNTIME_METHODS=cwrap")
+    set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
+    target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
+  endif()
 
   # WASM version
-  add_executable(webp_wasm
-                 ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
+  add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
   target_link_libraries(webp_wasm webpdecoder SDL)
-  set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
-      "-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
-       -s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-       -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+  target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+  set_target_properties(
+    webp_wasm
+    PROPERTIES LINK_FLAGS "-sWASM=1 ${emscripten_stack_size} \
+       -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+       -sEXPORTED_RUNTIME_METHODS=cwrap")
   target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
 
-  target_compile_definitions(webpdecoder PUBLIC EMSCRIPTEN)
+  target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
 endif()
 
-# Generate the config.h file.
-configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
-  ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
-add_definitions(-DHAVE_CONFIG_H)
-# The webp folder is included as we reference config.h as
-# ../webp/config.h or webp/config.h
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+if(WEBP_BUILD_ANIM_UTILS)
+  # anim_diff
+  include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DIFF_SRCS"
+                    "anim_diff")
+  add_executable(anim_diff ${ANIM_DIFF_SRCS})
+  target_link_libraries(
+    anim_diff
+    exampleutil
+    imagedec
+    imageenc
+    imageioutil
+    webp
+    webpdemux
+    ${WEBP_DEP_GIF_LIBRARIES})
+  target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+
+  # anim_dump
+  include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
+  parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DUMP_SRCS"
+                    "anim_dump")
+  add_executable(anim_dump ${ANIM_DUMP_SRCS})
+  target_link_libraries(
+    anim_dump
+    exampleutil
+    imagedec
+    imageenc
+    imageioutil
+    webp
+    webpdemux
+    ${WEBP_DEP_GIF_LIBRARIES})
+  target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+endif()
 
 # Install the different headers and libraries.
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h
-              ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h
-              ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h
-              ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h
-              ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h
-              ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h
-        DESTINATION include/webp)
-install(TARGETS ${INSTALLED_LIBRARIES}
-        LIBRARY DESTINATION lib
-        ARCHIVE DESTINATION lib)
+install(
+  TARGETS ${INSTALLED_LIBRARIES}
+  EXPORT ${PROJECT_NAME}Targets
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
+  INCLUDES
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/)
+install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME}::
+        DESTINATION ${ConfigPackageLocation})
 
 # Create the CMake version file.
 include(CMakePackageConfigHelpers)
 write_basic_package_version_file(
   "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
-  VERSION ${PACKAGE_VERSION}
-  COMPATIBILITY AnyNewerVersion
-)
+  VERSION ${PACKAGE_VERSION} COMPATIBILITY AnyNewerVersion)
 
 # Create the Config file.
 include(CMakePackageConfigHelpers)
-set(ConfigPackageLocation share/WebP/cmake/)
+# Fix libwebpmux reference. The target name libwebpmux is used for compatibility
+# purposes, but the library mentioned in WebPConfig.cmake should be the
+# unprefixed version. Note string(...) can be replaced with list(TRANSFORM ...)
+# if cmake_minimum_required is >= 3.12.
+string(REGEX REPLACE "libwebpmux" "webpmux" INSTALLED_LIBRARIES
+                     "${INSTALLED_LIBRARIES}")
+
+if(MSVC)
+  # For compatibility with nmake, MSVC builds use a custom prefix (lib) that
+  # needs to be included in the library name.
+  string(REGEX REPLACE "[A-Za-z0-9_]+" "${CMAKE_STATIC_LIBRARY_PREFIX}\\0"
+                       INSTALLED_LIBRARIES "${INSTALLED_LIBRARIES}")
+endif()
+
 configure_package_config_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
   ${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
   INSTALL_DESTINATION ${ConfigPackageLocation}
-)
+  PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
 
 # Install the generated CMake files.
-install(
-  FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
-        "${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake"
-  DESTINATION ${ConfigPackageLocation}
-)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
+              "${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake"
+        DESTINATION ${ConfigPackageLocation})
 
 # Install the man pages.
-set(MAN_PAGES cwebp.1 dwebp.1 gif2webp.1 img2webp.1 vwebp.1 webpmux.1
-  webpinfo.1)
-set(EXEC_BUILDS "CWEBP" "DWEBP" "GIF2WEBP" "IMG2WEBP" "VWEBP" "WEBPMUX"
-  "WEBPINFO")
+set(MAN_PAGES
+    cwebp.1
+    dwebp.1
+    gif2webp.1
+    img2webp.1
+    vwebp.1
+    webpmux.1
+    webpinfo.1)
+set(EXEC_BUILDS
+    "CWEBP"
+    "DWEBP"
+    "GIF2WEBP"
+    "IMG2WEBP"
+    "VWEBP"
+    "WEBPMUX"
+    "WEBPINFO")
 list(LENGTH MAN_PAGES MAN_PAGES_LENGTH)
 math(EXPR MAN_PAGES_RANGE "${MAN_PAGES_LENGTH} - 1")
 
@@ -364,8 +797,6 @@
   if(WEBP_BUILD_${EXEC_BUILD})
     list(GET MAN_PAGES ${I_MAN} MAN_PAGE)
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE}
-      DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1
-      COMPONENT doc
-    )
+            DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
   endif()
 endforeach()
diff --git a/third_party/libwebp/CONTRIBUTING.md b/third_party/libwebp/CONTRIBUTING.md
new file mode 100644
index 0000000..9540f34
--- /dev/null
+++ b/third_party/libwebp/CONTRIBUTING.md
@@ -0,0 +1,78 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement. You (or your employer) retain the copyright to your contribution;
+this simply gives us permission to use and redistribute your contributions as
+part of the project. Head over to <https://cla.developers.google.com/> to see
+your current agreements on file or to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code reviews
+
+All submissions, including submissions by project members, require review. We
+use a [Gerrit](https://www.gerritcodereview.com) instance hosted at
+https://chromium-review.googlesource.com for this purpose.
+
+## Sending patches
+
+The basic git workflow for modifying libwebp code and sending for review is:
+
+1.  Get the latest version of the repository locally:
+
+    ```sh
+    git clone https://chromium.googlesource.com/webm/libwebp && cd libwebp
+    ```
+
+2.  Copy the commit-msg script into ./git/hooks (this will add an ID to all of
+    your commits):
+
+    ```sh
+    curl -Lo .git/hooks/commit-msg https://chromium-review.googlesource.com/tools/hooks/commit-msg && chmod u+x .git/hooks/commit-msg
+    ```
+
+3.  Modify the local copy of libwebp. Make sure the code
+    [builds successfully](https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/building.md#cmake).
+
+4.  Choose a short and representative commit message:
+
+    ```sh
+    git commit -a -m "Set commit message here"
+    ```
+
+5.  Send the patch for review:
+
+    ```sh
+    git push https://chromium-review.googlesource.com/webm/libwebp HEAD:refs/for/main
+    ```
+
+    Go to https://chromium-review.googlesource.com to view your patch and
+    request a review from the maintainers.
+
+See the
+[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/)
+for additional details.
+
+## Code Style
+
+The C code style is based on the
+[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and
+`clang-format --style=Google`, though this project doesn't use the tool to
+enforce the formatting.
+
+CMake files are formatted with
+[cmake-format](https://cmake-format.readthedocs.io/en/latest/). `cmake-format
+-i` can be used to format individual files, it will use the settings from
+`.cmake-format.py`.
+
+## Community Guidelines
+
+This project follows
+[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).
diff --git a/third_party/libwebp/ChangeLog b/third_party/libwebp/ChangeLog
index 9fd9acf..5e85875 100644
--- a/third_party/libwebp/ChangeLog
+++ b/third_party/libwebp/ChangeLog
@@ -1,23 +1,793 @@
+e1adea50 update NEWS
+43393320 enc/*: normalize WebPEncodingSetError() calls
+287fdefe enc/*: add missing WebPEncodingSetError() calls
+c3bd7cff EncodeAlphaInternal: add missing error check
+d49cfbb3 vp8l_enc,WriteImage: add missing error check
+2e5a9ec3 muxread,MuxImageParse: add missing error checks
+ebb6f949 cmake,emscripten: explicitly set stack size
+59a2b1f9 WebPDecodeYUV: check u/v/stride/uv_stride ptrs
+8e965ccb Call png_get_channels() to see if image has alpha
+7f0a3419 update ChangeLog (tag: v1.3.1-rc1)
+bab7efbe update NEWS
+7138bf8f bump version to 1.3.1
+435b4ded update AUTHORS
+47351229 update .mailmap
+ff6c7f4e CONTRIBUTING.md: add C style / cmake-format notes
+dd530437 add .cmake-format.py
+adbe2cb1 cmake,cosmetics: apply cmake-format
+15b36508 doc/webp-container-spec: rm future codec comment
+c369c4bf doc/webp-lossless-bitstream-spec: improve link text
+1de35f47 doc/webp-container-spec: don't use 'currently'
+bb06a16e doc/webp-container-spec: prefer present tense
+9f38b71e doc/webp-lossless-bitstream-spec: prefer present tense
+7acb6b82 doc/webp-container-spec: avoid i.e. & e.g.
+4967e7cd doc/webp-lossless-bitstream-spec: avoid i.e. & e.g.
+e3366659 Merge "Do not find_package image libraries if not needed." into main
+428588ef clarify single leaf node trees and use of canonical prefix coding
+709ec152 Do not find_package image libraries if not needed.
+8dd80ef8 fuzz_utils.h: lower kFuzzPxLimit w/ASan
+8f187b9f Clean message calls in CMake
+cba30078 WebPConfig.cmake.in: use calculated include path
+6cf9a76a Merge "webp-lossless-bitstream-spec: remove use of 'dynamics'" into main
+740943b2 Merge "Specialize and optimize ITransform_SSE2 using do_two" into main
+2d547e24 Compare kFuzzPxLimit to max_num_operations
+ac42dde1 Specialize and optimize ITransform_SSE2 using do_two
+17e0ef1d webp-lossless-bitstream-spec: remove use of 'dynamics'
+ed274371 neon.h,cosmetics: clear a couple lint warnings
+3fb82947 cpu.h,cosmetics: segment defines
+0c496a4f cpu.h: add WEBP_AARCH64
+8151f388 move VP8GetCPUInfo declaration to cpu.c
+916548c2 Make kFuzzPxLimit sanitizer dependent
+4070b271 advanced_api_fuzzer: reduce scaling limit
+761f49c3 Merge "webp-lossless-bitstream-spec: add missing bits to ABNF" into main
+84d04c48 webp-lossless-bitstream-spec: add missing bits to ABNF
+0696e1a7 advanced_api_fuzzer: reduce scaling limit
+93d88aa2 Merge "deps.cmake: remove unneeded header checks" into main
+118e0035 deps.cmake: remove unneeded header checks
+4c3d7018 webp-lossless-bitstream-spec: condense normal-prefix-code
+a6a09b32 webp-lossless-bitstream-spec: fix 2 code typos
+50ac4f7c Merge "cpu.h: enable NEON w/_M_ARM64EC" into main
+4b7d7b4f Add contribution instructions
+0afbd97b cpu.h: enable NEON w/_M_ARM64EC
+349f4353 Merge changes Ibd89e56b,Ic57e7f84,I89096614 into main
+8f7513b7 upsampling_neon.c: fix WEBP_SWAP_16BIT_CSP check
+cbf624b5 advanced_api_fuzzer: reduce scaling limit
+89edfdd1 Skip slow scaling in libwebp advanced_api_fuzzer
+859f19f7 Reduce libwebp advanced_api_fuzzer threshold
+a4f04835 Merge changes Ic389aaa2,I329ccd79 into main
+1275fac8 Makefile.vc: fix img2webp link w/dynamic cfg
+2fe27bb9 img2webp: normalize help output
+24bed3d9 cwebp: reflow -near_lossless help text
+0825faa4 img2webp: add -sharp_yuv/-near_lossless
+d64e6d7d Merge "PaletteSortModifiedZeng: fix leak on error" into main
+0e12a22d Merge "EncodeAlphaInternal: clear result->bw on error" into main
+0edbb6ea PaletteSortModifiedZeng: fix leak on error
+41ffe04e Merge "Update yapf style from "chromium" to "yapf"" into main
+2d9d9265 Update yapf style from "chromium" to "yapf"
+a486d800 EncodeAlphaInternal: clear result->bw on error
+1347a32d Skip big scaled advanced_api_fuzzer
+52b6f067 Fix scaling limit in advanced_api_fuzzer.c
+73618428 Limit scaling in libwebp advanced_api_fuzzer.c
+b54d21a0 Merge "CMakeLists.txt: allow CMAKE_INSTALL_RPATH to be set empty" into main
+31c28db5 libwebp{,demux,mux}.pc.in: Requires -> Requires.private
+d9a505ff CMakeLists.txt: allow CMAKE_INSTALL_RPATH to be set empty
+bdf33d03 Merge tag 'v1.3.0'
+b5577769 update ChangeLog (tag: v1.3.0-rc1, tag: v1.3.0)
+0ba77244 update NEWS
+e763eb1e bump version to 1.3.0
+2a8686fc update AUTHORS
+106a57c1 Merge "*/Android.mk: add a check for NDK_ROOT" into main
+c5e841c4 Merge "extras: WebpToSDL -> WebPToSDL" into main
+dbc30715 Merge "xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION" into main
+6fc1a9f9 */Android.mk: add a check for NDK_ROOT
+d3e151fc doc/api.md,webp_js/README.md: Webp -> WebP
+ed92a626 extras: WebpToSDL -> WebPToSDL
+6eb0189b xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION
+1d58575b CMake: align .pc variables with autoconf
+e5fe2cfc webp-lossless-bitstream-spec,cosmetics: reflow paragraphs
+0ceeeab9 webp-lossless-bitstream-spec: add amendment note
+607611cd Merge "webp-container-spec: normalize section title case" into main
+f853685e lossless: SUBTRACT_GREEN -> SUBTRACT_GREEN_TRANSFORM
+786497e4 webp-lossless-bitstream-spec: fix inv color txfm description
+c6ac672d webp-lossless-bitstream-spec: fix num_code_lengths check
+b5700efb webp-lossless-bitstream-spec,cosmetics: grammar/capitalization
+d8ed8c11 webp-container-spec: normalize section title case
+52ec0b8f Merge changes Ie975dbb5,Ifc8c93af,I6ca7c5d6,I2e8d66f5,I152477b8 into main
+5097ef62 webp-container-spec,cosmetics: grammar/capitalization
+e3ba2b1f webp-lossless-bitstream-spec,cosmetics: reflow abstract
+1e8e3ded webp-lossless-bitstream-spec: reword abstract re alpha
+017cb6fa webp-container-spec,cosmetics: normalize range syntax
+f6a4684b webp-lossless-bitstream-spec,cosmetics: normalize range syntax
+54ebd5a3 webp-lossless-bitstream-spec: limit dist map lut to 69 cols
+44741f9c webp-lossless-bitstream-spec: fix dist mapping example
+fad0ece7 pnmdec.c: use snprintf instead of sprintf
+3f73e8f7 sharpyuv: add SharpYuvGetVersion()
+ce2f2d66 SharpYuvConvert: fix a race on SharpYuvGetCPUInfo
+a458e308 sharpyuv_dsp.h: restore sharpyuv_cpu.h include
+9ba800a7 Merge changes Id72fbf3b,Ic59d23a2 into main
+979c0ebb sharpyuv: add SharpYuvGetCPUInfo
+8bab09a4 Merge "*.pc.in: rename lib_prefix to webp_libname_prefix" into main
+769387c5 cpu.c,cosmetics: fix a typo
+a02978c2 sharpyuv/Makefile.am+cmake: add missing -lm
+28aedcb9 *.pc.in: rename lib_prefix to webp_libname_prefix
+c42e6d5a configure.ac: export an empty lib_prefix variable
+dfc843aa Merge "*.pc.in: add lib prefix to lib names w/MSVC" into main
+2498209b *.pc.in: add lib prefix to lib names w/MSVC
+ac252b61 Merge "analysis_enc.c: fix a dead store warning" into main
+56944762 analysis_enc.c: fix a dead store warning
+d34f9b99 Merge "webp-lossless-bitstream-spec: convert BNF to ABNF" into main
+dc05b4db Merge changes I96bc063c,I45880467,If9e18e5a,I6ee938e4,I0a410b28, ... into main
+83270c7f webp-container-spec: add prose for rendering process
+73b19b64 webp-container-spec: note reserved fields MUST be ignored
+57101d3f webp-lossless-bitstream-spec: improve 'small' color table stmt
+dfd32e45 webp-container-spec: remove redundant sentence
+8a6185dd doc/webp-*: fix some punctuation, grammar
+72776530 webp-lossless-bitstream-spec: convert BNF to ABNF
+d992bb08 cmake: rename cpufeatures target to cpufeatures-webp
+3ed2b275 webp-container-spec: clarify background color note
+951c292d webp-container-spec: come too late -> out of order
+902dd787 webp-container-spec: prefer hex literals
+a8f6b5ee webp-container-spec: change SHOULD to MUST w/ANIM chunk
+1dc59435 webp-container-spec: add unknown fields MUST be ignored
+280a810f webp-container-spec: make padding byte=0 a MUST
+41f0bf68 webp-container-spec: update note on trailing data
+6bdd36db webp-container-spec: clarify Chunk Size is in bytes
+87e36c48 Merge "webp_js/README.md,cosmetics: reflow some lines" into main
+5b01f321 Merge "Update Windows makefile to build libsharpyuv library." into main
+19b1a71c webp_js/README.md,cosmetics: reflow some lines
+780db756 Update Windows makefile to build libsharpyuv library.
+e407d4b3 CMakeLists.txt: replace GLUT_glut_LIBRARY w/GLUT::GLUT
+abf73d62 Merge "WebPConfig.cmake.in: add find_dependency(Threads)" into main
+25807fb4 Merge "cmake: restore compatibility with cmake < 3.12" into main
+5dbc4bfa WebPConfig.cmake.in: add find_dependency(Threads)
+b2a175dd Merge "Update wasm instructions." into main
+cb90f76b Update wasm instructions.
+02d15258 cmake: restore compatibility with cmake < 3.12
+5ba046e2 CMake: add_definitions -> add_compile_options
+e68765af dsp,neon: use vaddv in a few more places
+e8f83de2 Set libsharpyuv include dir to 'webp' subdirectory.
+15a91ab1 cmake,cosmetics: apply cmake-format
+0dd49d1a CMakeLists.txt: set @ONLY in configure_file() calls
+62b1bfe8 Merge changes I2877e7bb,I777cad70,I15af7d1a,I686e6740,If10538a9, ... into main
+95c8fe5f Merge changes Iecea3603,I9dc228ab into main
+e7c805cf picture_csp_enc.c: remove SafeInitSharpYuv
+6af8845a sharpyuv: prefer webp/types.h
+639619ce cmake: fix dll exports
+782ed48c sharpyuv,SharpYuvInit: add mutex protection when available
+cad0d5ad sharyuv_{neon,sse2}.c: merge WEBP_USE_* sections
+ef70ee06 add a few missing <stddef.h> includes for NULL
+f0f9eda4 sharpyuv.h: remove <inttypes.h>
+9b902cba Merge "picture_csp_enc.c,CheckNonOpaque: rm unneeded local" into main
+9c1d457c cmake/cpu.cmake: remove unused variable
+9ac25bcb CMakeLists.txt,win32: match naming convention used by nmake
+76c353ba picture_csp_enc.c,CheckNonOpaque: rm unneeded local
+5000de54 Merge "cwebp: fix WebPPictureHasTransparency call" into main
+e1729309 Merge "WebPPictureHasTransparency: add missing pointer check" into main
+00ff988a vp8l_enc,AddSingleSubGreen: clear int sanitizer warnings
+e2fecc22 dsp/lossless_enc.c: clear int sanitizer warnings
+129cf9e9 dsp/lossless.c: clear int sanitizer warnings
+ad7d1753 dsp/lossless_enc.c: clear int sanitizer warnings
+5037220e VP8LSubtractGreenFromBlueAndRed_C: clear int sanitizer warnings
+2ee786c7 upsampling_sse2.c: clear int sanitizer warnings
+4cc157d4 ParseOptionalChunks: clear int sanitizer warning
+892cf033 BuildHuffmanTable: clear int sanitizer warning
+3a9a4d45 VP8GetSigned: clear int sanitizer warnings
+704a3d0a dsp/lossless.c: quiet int sanitizer warnings
+1a6c109c WebPPictureHasTransparency: add missing pointer check
+c626e7d5 cwebp: fix WebPPictureHasTransparency call
+866e349c Merge tag 'v1.2.4'
+c170df38 Merge "Create libsharpyuv.a in makefile.unix." into main
+9d7ff74a Create libsharpyuv.a in makefile.unix.
+0d1f1254 update ChangeLog (tag: v1.2.4)
+fcbc2d78 Merge "doc/*.txt: restrict code to 69 columns" into main
+4ad0e189 Merge "webp-container-spec.txt: normalize fourcc spelling" into main
+980d2488 update NEWS
+9fde8127 bump version to 1.2.4
+7a0a9935 doc/*.txt: restrict code to 69 columns
+c040a615 webp-container-spec.txt: normalize fourcc spelling
+aff1c546 dsp,x86: normalize types w/_mm_cvtsi128_si32 calls
+ab540ae0 dsp,x86: normalize types w/_mm_cvtsi32_si128 calls
+8980362e dsp,x86: normalize types w/_mm_set* calls (2)
+e626925c lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+83539239 dsp,x86: normalize types w/_mm_set* calls
+8a4576ce webp-container-spec.txt: replace &amp; with &
+db870881 Merge "webp-container-spec.txt: make reserved 0 values a MUST" into main
+01d7d378 webp-lossless-bitstream-spec: number all sections
+337cf69f webp-lossless-bitstream-spec: mv Nomenclature after Intro
+79be856e Merge changes I7111d1f7,I872cd62c into main
+5b87983a webp-container-spec.txt: make reserved 0 values a MUST
+bd939123 Merge changes I7a25b1a6,I51b2c2a0,I87d0cbcf,I6ec60af6,I0a3fe9dc into main
+04764b56 libwebp.pc: add libsharpyuv to requires
+7deee810 libsharpyuv: add pkg-config file
+1a64a7e6 webp-container-spec.txt: clarify some SHOULDs
+bec2c88a webp-container-spec.txt: move ChunkHeader to terminology
+c9359332 webp-container-spec.txt: clarify 'VP8 '/'XMP ' fourccs
+70fe3063 webp-container-spec.txt: rightsize table entries
+ddbf3f3f webp-container-spec.txt: update 'key words' text
+c151e95b utils.h,WEBP_ALIGN: make bitmask unsigned
+748e92bb add WebPInt32ToMem
+3fe15b67 Merge "Build libsharpyuv as a full installable library." into main
+4f402f34 add WebPMemToInt32
+a3b68c19 Build libsharpyuv as a full installable library.
+b4994eaa CMake: set rpath for shared objects
+94cd7117 Merge "CMake: fix dylib versioning" into main
+e91451b6 Fix the lossless specs a bit more.
+231bdfb7 CMake: fix dylib versioning
+bfad7ab5 CMakeLists.txt: correct libwebpmux name in WebPConfig.cmake
+c2e3fd30 Revert "cmake: fix webpmux lib name for cmake linking"
+7366f7f3 Merge "lossless: fix crunch mode w/WEBP_REDUCE_SIZE" into main
+84163d9d lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+d01c1eb3 webp-lossless-bitstream-spec,cosmetics: normalize capitalization
+8813ca8e Merge tag 'v1.2.3'
+3c4a0fbf update ChangeLog (tag: v1.2.3)
+56a480e8 dsp/cpu.h: add missing extern "C"
+62b45bdd update ChangeLog (tag: v1.2.3-rc1)
+8764ec7a Merge changes Idb037953,Id582e395 into 1.2.3
+bcb872c3 vwebp: fix file name display in windows unicode build
+67c44ac5 webpmux: fix -frame option in windows unicode build
+8278825a makefile.unix: add sharpyuv objects to clean target
+14a49e01 update NEWS
+34b1dc33 bump version to 1.2.3
+0b397fda update AUTHORS
+c16488ac update .mailmap
+5a2d929c Merge "unicode.h: set console mode before using wprintf" into main
+169f867f unicode.h: set console mode before using wprintf
+a94b855c Merge "libsharpyuv: add version defines" into main
+f83bdb52 libsharpyuv: add version defines
+bef0d797 unicode_gif.h: fix -Wdeclaration-after-statement
+404c1622 Rename Huffman coding to prefix coding in the bitstream spec
+8895f8a3 Merge "run_static_analysis.sh: fix scan-build archive path" into main
+92a673d2 Merge "Add -fvisibility=hidden flag in CMakeLists." into main
+67c1d722 Merge "add WEBP_MSAN" into main
+1124ff66 Add -fvisibility=hidden flag in CMakeLists.
+e15b3560 add WEBP_MSAN
+ec9e782a sharpyuv: remove minimum image size from sharpyuv library
+7bd07f3b run_static_analysis.sh: fix scan-build archive path
+5ecee06f Merge "sharpyuv: increase precision of gamma<->linear conversion" into main
+f81dd7d6 Merge changes I3d17d529,I53026880,I1bd61639,I6bd4b25d,Icfec8fba into main
+2d607ee6 sharpyuv: increase precision of gamma<->linear conversion
+266cbbc5 sharpyuv: add 32bit version of SharpYuvFilterRow.
+9fc12274 CMake: add src to webpinfo includes
+7d18f40a CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
+11309aa5 CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
+4bc762f7 CMake: link imageioutil to exampleutil after defined
+0d1b9bc4 WEBP_DEP_LIBRARIES: use Threads::Threads
+20ef48f0 Merge "sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv." into main
+93c54371 sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv.
+53cf2b49 normalize WebPValidatePicture declaration w/definition
+d3006f4b sharpyuv: slightly improve precision
+ea967098 Merge changes Ia01bd397,Ibf3771af into main
+11bc8410 Merge changes I2d317c4b,I9e77f6db into main
+30453ea4 Add an internal WebPValidatePicture.
+6c43219a Some renamings for consistency.
+4f59fa73 update .mailmap
+e74f8a62 webp-lossless-bitstream-spec,cosmetics: normalize range syntax
+5a709ec0 webp-lossless-bitstream-spec,cosmetics: fix code typo
+a2093acc webp-lossless-bitstream-spec: add amendment note
+86c66930 webp-lossless-bitstream-spec: fix BNF
+232f22da webp-lossless-bitstream-spec: fix 'simple code' snippet
+44dd765d webp-lossless-bitstream-spec: fix ColorTransform impl
+7a7e33e9 webp-lossless-bitstream-spec: fix TR-pixel right border note
+86f94ee0 Update lossless spec with Huffman codes.
+a3927cc8 sharpyuv.c,cosmetics: fix indent
+6c45cef7 Make sure the stride has a minimum value in the importer.
+0c8b0e67 sharpyuv: cleanup/cosmetic changes
+dc3841e0 {histogram,predictor}_enc: quiet int -> float warnings
+a19a25bb Replace doubles by floats in lossless misc cost estimations.
+42888f6c Add an option to enable static builds.
+7efcf3cc Merge "Fix typo in color constants: Marix -> Matrix" into main
+8f4b5c62 Fix typo in color constants: Marix -> Matrix
+90084d84 Merge "demux,IsValidExtendedFormat: remove unused variable" into main
+ed643f61 Merge changes I452d2485,Ic6d75475 into main
+8fa053d1 Rename SharpYUV to SharpYuv for consistency.
+99a87562 SharpYuvComputeConversionMatrix: quiet int->float warnings
+deb426be Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
+779597d4 demux,IsValidExtendedFormat: remove unused variable
+40e8aa57 Merge "libsharpyuv: add colorspace utilities" into main
+01a05de1 libsharpyuv: add colorspace utilities
+2de4b05a Merge changes Id9890a60,I376d81e6,I1c958838 into main
+b8bca81f Merge "configure.ac: use LT_INIT if available" into main
+e8e77b9c Merge changes I479bc487,I39864691,I5d486c2c,I186d13be into main
+7e7d5d50 Merge ".gitignore: add Android Studio & VS code dirs" into main
+10c50848 normalize label indent
+89f774e6 mux{edit,internal}: fix leaks on error
+2d3293ad ExUtilInitCommandLineArguments: fix leak on error
+ec34fd70 anim_util: fix leaks on error
+e4717287 gif2webp: fix segfault on OOM
+e3cfafaf GetBackwardReferences: fail on alloc error
+a828a59b BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
+fe153fae VP8LEncodeStream: fix segfault on OOM
+919acc0e .gitignore: add Android Studio & VS code dirs
+efa0731b configure.ac: use LT_INIT if available
+0957fd69 tiffdec: add grayscale support
+e685feef Merge "Make libsharpyuv self-contained by removing dependency on cpu.c" into main
+841960b6 Make libsharpyuv self-contained by removing dependency on cpu.c
+617cf036 image_dec: add WebPGetEnabledInputFileFormats()
+7a68afaa Let SharpArgbToYuv caller pass in an RGB>YUV conversion matrix.
+34bb332c man/cwebp.1: add note about crop/resize order
+f0e9351c webp-lossless-bitstream-spec,cosmetics: fix some typos
+5ccbd6ed vp8l_dec.c,cosmetics: fix a few typos
+c3d0c2d7 fix ios build scripts after sharpyuv dep added
+d0d2292e Merge "Make libwebp depend on libsharpyuv." into main
+03d12190 alpha_processing_neon.c: fix 0x01... typo
+d55d447c Make libwebp depend on libsharpyuv.
+e4cbcdd2 Fix lossless encoding for MIPS.
+924e7ca6 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
+0fa0ea54 Makefile.vc: use /MANIFEST:EMBED
+29cc95ce Basic version of libsharpyuv in libwebp, in C.
+a30f2190 examples/webpmux.c: fix a couple of typos
+66b3ce23 Fix bad overflow check in ReadTIFF()
+54e61a38 Markdownify libwebp docs and reorganize them.
+b4533deb CMakeLists.txt,cosmetics: break long line
+b9d2f9cd quant_enc.c: use WEBP_RESTRICT qualifier
+ec178f2c Add progress hook granularity in lossless
+26139c73 Rename MAX_COST to MAX_BIT_COST in histogram_enc.c
+13b82816 cmake: fix webpmux lib name for cmake linking
+88b6a396 webp-container-spec.txt,cosmetics: normalize formatting
+6f496540 Merge tag 'v1.2.2'
+4074acf8 dsp.h: bump msvc arm64 version requirement to 16.6
+b0a86089 update ChangeLog (tag: v1.2.2)
+6db8248c libwebp: Fix VP8EncTokenLoop() progress
+827a307f BMP enc: fix the transparency case
+db25f1b4 libwebp: Fix VP8EncTokenLoop() progress
+286e7fce libwebp: do not destroy jpeg codec twice on error
+6e8a4126 libwebp: do not destroy jpeg codec twice on error
+faf21968 Merge "BMP enc: fix the transparency case" into main
+480cd51d BMP enc: fix the transparency case
+9195ea05 update ChangeLog (tag: v1.2.2-rc2)
+4acae017 update NEWS
+883f0633 man/img2webp.1: update date
+567e1f44 Reword img2webp synopsis command line
+1b0c15db man/img2webp.1: update date
+17bade38 Merge "Reword img2webp synopsis command line" into main
+a80954a1 Reword img2webp synopsis command line
+f084244d anim_decode: fix alpha blending with big-endian
+b217b4ff webpinfo: fix fourcc comparison w/big-endian
+ec497b75 Merge "anim_decode: fix alpha blending with big-endian" into main
+e4886716 anim_decode: fix alpha blending with big-endian
+e3cb052c webpinfo: fix fourcc comparison w/big-endian
+a510fedb patch-check: detect duplicated files
+f035d2e4 update ChangeLog (tag: v1.2.2-rc1)
+7031946a update NEWS
+973390b6 bump version to 1.2.2
+abd6664f update AUTHORS
+5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
+02ca04c3 add missing USE_{MSA,NEON} checks in headers
+e94716e2 xcframeworkbuild.sh: place headers in a subdir
+c846efd8 patch-check: commit subject length check
+b6f756e8 update http links
+8f5cb4c1 update rfc links
+8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
+6b1d18c3 webpmux: fix the -bgcolor description
+3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
+f213abf6 webpinfo: print the number of warnings
+50c97c30 webpmux: add "-set bgcolor A,R,G,B"
+2c206aaf Remove CMakeLists.txt check in compile.sh
+96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
+0e0f74b7 infra/common.sh: add shard_should_run()
+35b7436a Jenkins scripts port: update shell function comments
+21d24b4c webp-container-spec.txt: remove 'experimental' markers
+cdcf8902 Merge "Port Jenkins script: compile" into main
+dc683cde Jenkins scripts port: static analysis
+0858494e Port Jenkins script: compile
+c2cf6a93 Jenkins scripts port: android compilation
+df0e808f presubmit: Add pylint-2.7 and .pylintrc
+676c57db patch-check: shfmt
+7bb7f747 patch-check: Add shellcheck
+abcd1797 Reformat docstrings and imports
+edaf0895 Port Jenkins scripts: compile js
+b9622063 Set CheckPatchFormatted flags to fail on diffs
+e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
+3875c7de CMakeLists.txt: set minimum version to 3.7
+1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
+93480160 Speed up TrellisQuantizeBlock
+45eaacc9 Convert deprecated uint32 to uint32_t.
+42592af8 webp,cmake: Remove unnecessary include dirs
+e298e05f Add patch-check steps in PRESUBMIT.py
+29148919 Merge tag 'v1.2.1'
+9ce5843d update ChangeLog (tag: v1.2.1)
+d9191588 fuzzer/*: normalize src/ includes
+c5bc3624 fuzzer/*: normalize src/ includes
+53b6f762 fix indent
+d2caaba4 fix indent
+731246ba update ChangeLog (tag: v1.2.1-rc2)
+d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
+1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
+3a4d3ecd update NEWS
+b2bc8093 bump version to 1.2.1
+e542fc7a update AUTHORS
+e0241154 Merge "libwebp/CMake: Add <BUILD_INTERFACE> to webp incl" into main
+edea6444 libwebp/CMake: Add <BUILD_INTERFACE> to webp incl
+ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
+a89a3230 wicdec: support alpha from WebP WIC decoder
+26f4aa01 Merge "alpha_processing: fix visual studio warnings" into main
+8f594663 alpha_processing: fix visual studio warnings
+46d844e6 Merge "cpu.cmake: fix compiler flag detection w/3.17.0+" into main
+298d26ea Merge changes I593adf92,If20675e7,Ifac68eac into main
+a1e5dae0 alpha_processing*: use WEBP_RESTRICT qualifier
+327ef24f cpu.cmake: fix compiler flag detection w/3.17.0+
+f70819de configure: enable libwebpmux by default
+dc7e2b42 configure: add informational notices when disabling binaries
+9df23ddd configure: move lib flag checks before binaries
+a2e18f10 Merge "WebPConfig.config.in: correct WEBP_INCLUDE_DIRS" into main
+e1a8d4f3 Merge "bit_reader_inl_utils: uniformly apply WEBP_RESTRICT" into main
+4de35f43 rescaler.c: fix alignment
+0f13eec7 bit_reader_inl_utils: uniformly apply WEBP_RESTRICT
+277d3074 Fix size_t overflow in  WebPRescalerInit
+97adbba5 WebPConfig.config.in: correct WEBP_INCLUDE_DIRS
+b60d4603 advanced_api_fuzzer: add extreme config value coverage
+72fe52f6 anim_encode.c,cosmetics: normalize indent
+116d235c anim_encode: Fix encoded_frames_[] overflow
+6f445b3e CMake: set CMP0072 to NEW
+b1cf887f define WEBP_RESTRICT for MSVC
+3e265136 Add WEBP_RESTRICT & use it in VP8BitReader
+f6d29247 vp8l_dec::ProcessRows: fix int overflow in multiply
+de3b4ba8 CMake: add WEBP_BUILD_LIBWEBPMUX
+7f09d3d1 CMakeLists.txt: rm libwebpmux dep from anim_{diff,dump}
+4edea4a6 Init{RGB,YUV}Rescaler: fix a few more int overflows
+c9e26bdb rescaler_utils: set max valid scaled w/h to INT_MAX/2
+28d488e6 utils.h: add SizeOverflow()
+695bdaa2 Export/EmitRescaledRowsRGBA: fix pointer offset int overflow
+685d073e Init{RGB,YUV}Rescaler: fix int overflows in multiplication
+d38bd0dd WebPFlipBuffer: fix integer overflow
+109ff0f1 utils: allow MALLOC_LIMIT to indicate a max
+a2fce867 WebPRescalerImportRowExpand_C: promote some vals before multiply
+776983d4 AllocateBuffer: fix int multiplication overflow check
+315abbd6 Merge "Revert "Do not use a palette for one color images.""
+eae815d0 Merge changes Ica3bbf75,I82f82954
+afbca5a1 Require Emscripten 2.0.18
+3320416b CMakeLists,emscripten: use EXPORTED_RUNTIME_METHODS
+29145ed6 Update README instructions for using Emscripten
+1f579139 cosmetics: remove use of 'sanity' / 'master'
+29b6129c WebPAnimEncoderNewInternal: remove some unnecessary inits
+b60869a1 Revert "Do not use a palette for one color images."
+6fb4cddc demux: move padded size calc post unpadded validation
+05b72d42 vp8l_enc.c: normalize index types
+b6513fba Do not use a palette for one color images.
+98bbe35b Fix multi-threading with palettes.
+b1674240 Add modified Zeng's method to palette sorting.
+88c90c45 add CONTRIBUTING.md
+6a9916d7 WebPRescalerInit: add missing int64_t promotion
+b6cf52d5 WebPIoInitFromOptions: treat use_scaling as a bool
+3b12b7f4 WebPIoInitFromOptions: treat use_cropping as a bool
+595fa13f add WebPCheckCropDimensions()
+8fdaecb0 Disable cross-color when palette is used.
+8933bac2 WebPIoInitFromOptions: respect incoming bypass_filtering val
+7d416ff0 webpdec,cosmetics: match error text to function call
+ec6cfeb5 Fix typo on WebPPictureAlloc() in README
+7e58a1a2 *.cmake: add license header
+5651a6b2 cmake: fix .so versioning
+25ae67b3 xcframeworkbuild.sh: add arm64 simulator target
+5d4ee4c3 cosmetics: remove use of the term 'dummy'
+01b38ee1 faster CollectColorXXXTransforms_SSE41
+652aa344 Merge "Use BitCtz for FastSLog2Slow_C"
+0320e1e3 add the missing default BitsCtz() code
+8886f620 Use BitCtz for FastSLog2Slow_C
+fae41617 faster CombinedShannonEntropy_SSE2
+5bd2704e Introduce the BitCtz() function.
+fee64287 Merge "wicdec,icc: treat unsupported op as non-fatal"
+33ddb894 lossless_sse{2,41}: remove some unneeded includes
+b27ea852 wicdec,icc: treat unsupported op as non-fatal
+b78494a9 Merge "Fix undefined signed shift."
+e79974cd Fix undefined signed shift.
+a8853394 SSE4.1 versions of BGRA to RGB/BGR color-space conversions
+a09a6472 SSE4.1 version of TransformColorInverse
+401da22b Merge "pngdec: check version before using png_get_chunk_malloc_max"
+26907822 pngdec: check version before using png_get_chunk_malloc_max
+06c1e72e Code cleanup
+8f0d41aa Merge changes Id135bbf4,I99e59797
+373eb170 gif2webp: don't store loop-count if there's only 1 frame
+759b9d5a cmake: add WEBP_USE_THREAD option
+926ce921 cmake: don't install binaries from extras/
+9c367bc6 WebPAnimDecoderNewInternal: validate bitstream before alloc
+47f64f6e filters_sse2: import Chromium change
+cc3577e9 fuzzer/*: use src/ based include paths
+004d77ff Merge tag 'v1.2.0'
+fedac6cc update ChangeLog (tag: v1.2.0-rc3, tag: v1.2.0)
+170a8712 Fix check_c_source_compiles with pthread.
+ceddb5fc Fix check_c_source_compiles with pthread.
+85995719 disable CombinedShannonEntropy_SSE2 on x86
+289757fe TiffDec: enforce stricter mem/dimension limit on tiles
+8af7436f Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0
+e56c3c5b pngdec: raise memory limit if needed
+8696147d pngdec: raise memory limit if needed
+13b8e9fe {ios,xcframework}build.sh: make min version(s) more visible
+a9225410 animdecoder_fuzzer: fix memory leak
+d6c2285d update gradle to 6.1.1
+8df77fb1 animdecoder_fuzzer: fix memory leak
+52ce6333 update NEWS
+28c49820 bump version to 1.2.0
+7363dff2 webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
+826aafa5 update AUTHORS
+63258823 animdecoder_fuzzer: validate canvas size
+9eb26381 CMake: remove duplicate "include(GNUInstallDirs)"
+2e7bed79 WebPPicture: clarify the ownership of user-owned data.
+cccf5e33 webpmux: add an '-set loop <value>' option
+c9a3f6a1 Merge changes Ie29f9867,I289c54c4
+319f56f1 iosbuild.sh: sync some aspects of xcframeworkbuild.sh
+e8e8db98 add xcframeworkbuild.sh
+ae545534 dsp.h: allow config.h to override MSVC SIMD autodetection
+fef789f3 Merge "cmake: fix per-file assembly flags"
+fc14fc03 Have C encoding predictors use decoding predictors.
+7656f0b3 README,cosmetics: fix a couple typos
+d2e245ea cmake: disable webp.js if WEBP_ENABLE_SIMD=1
+96099a79 cmake: fix per-file assembly flags
+5abb5582 Merge "cmake: fix compilation w/Xcode generator"
+8484a120 cmake: fix compilation w/Xcode generator
+d7bf01c9 Merge changes Ifcae0f38,Iee2d7401
+36c81ff6 WASM-SIMD: port 2 patches from rreverser@'s tree
+988b02ab Merge "Couple of fixes to allow SIMD on Emscripten"
+26faf770 wicdec: fail with animated images
+ab2d08a8 [cd]webp: document lack of animated webp support
+52273943 Couple of fixes to allow SIMD on Emscripten
+8870ba7f Fix skia bug #10952
+4b3c6953 Detect if StoreFrame read more than anmf_payload_size bytes
+17fd4ba8 webp/decode.h,cosmetics: normalize 'flip' comment
+411d3677 remove some unreachable break statements
+3700ffd7 WebPPictureHasTransparency: remove unreachable return
+83604bf3 {animencoder,enc_dec}_fuzzer: convert some abort()s to returns
+eb44119c Merge changes I8ae09473,I678c8b1e
+9f6055fc fuzz_utils.h: rename max() to Max()
+695788e7 fuzz_utils.h: make functions WEBP_INLINE
+906c1fcd make ImgIoUtilReadFile use WebPMalloc instead of malloc
+8cb7e536 rename demux_api_fuzzer.c -> mux_demux_api_fuzzer.c
+443db47d add animdecoder_fuzzer.cc
+36a6eea3 Merge "import fuzzers from oss-fuzz/chromium"
+ec5f12c1 Makefile.vc: remove deprecated /Gm option
+64425a08 picture_tools_enc: fix windows build warning
+bd94090a import fuzzers from oss-fuzz/chromium
+cf847cba use WEBP_DSP_INIT_FUNC for Init{GammaTables*,GetCoeffs}
+55a080e5 Add WebPReplaceTransparentPixels() in dsp
+84739717 GetBackgroundColorGIF: promote to uint32_t before << 24
+def64e92 cwebp: Fix -print_psnr for near_lossless
+cf2f88b3 Add palette and spatial for q >= 75 and -m 5
+f0110bae Add no-color cache configuration to the cruncher
+749a8b99 Better estimate of the cache cost.
+4f9f00cc Use spatial predictors on top of palette no matter what.
+7658c686 Add spatial prediction on top of palette in cruncher.
+133ff0e3 webp_js: force WASM=0 option explicitly
+e3c259a2 Fix integer overflow in EmitFancyRGB.
+b3ff0bde man/{gif2,img2}webp,webpmux: normalize some wording
+f9b30586 fix ABI breakage introduced by 6a0ff358
+1d58dcfc README.webp_js: update note about emscripten version
+44070266 README.webp_js: s/fastcomp/upstream/
+2565fa8f README.webp_js: update cmake command
+47309ef5 webp: WEBP_OFFSET_PTR()
+687ab00e DC{4,8,16}_NEON: replace vmovl w/vaddl
+1b92fe75 DC16_NEON,aarch64: use vaddlv
+53f3d8cf dec_neon,DC8_NEON: use vaddlv instead of movl+vaddv
+27d08240 Fix integer overflow in WebPAnimDecoderGetNext()
+69776e38 Merge "remove call to MBAnalyzeBestIntra4Mode for method >= 5"
+a99078c1 remove call to MBAnalyzeBestIntra4Mode for method >= 5
+22e404cc CMakeLists.txt: fix set(CACHE) argument order
+71690b52 fix MSVC warning
+6a0ff358 Enc: add a qmin / qmax range for quality factor
+0fa56f30 Merge tag 'v1.1.0'
+6cf504d0 PNM decoding: handle max_value != 255
+d7844e97 update ChangeLog (tag: v1.1.0-rc2, tag: v1.1.0)
+7f006436 Makefile.vc: fix webp_quality.exe link
+cf047e83 Makefile.vc: fix webp_quality.exe link
+c074c653 update NEWS
+30f09551 bump version to 1.1.0
+a76694a1 update AUTHORS
+6e3ef7b3 extras: fix WEBP_SWAP_16BIT_CSP check
+47178dbd extras: add WebPUnmultiplyARGB() convenience function
+22cbae33 idec_dec: fix 0 offset of NULL pointer
+290dd0b4 muxread: fix 0 offset of NULL pointer
+0df474ac Merge "lossless_(enc_|)sse2: avoid offsetting a NULL pointer"
+c6b75a19 lossless_(enc_|)sse2: avoid offsetting a NULL pointer
+295e5e38 fix UBSAN warning
+e2575e05 DC8_NEON,aarch64: use vaddv
+b0e09e34 dec_neon: Fix build failure under some toolchains
+cf0e903c dsp/lossless: Fix non gcc ARM builds
+bb7bc40b Remove ubsan errors.
+78881b76 CMake: fix GLUT library link
+9f750f7a cmake: fix BUILD_SHARED_LIBS build on mac
+17850e74 libwebp: Remove char-subscripts warning in pnmdec.c
+2fa2552d Merge "Expose WebPMalloc() in addition to WebPFree()"
+a4df4aae Expose WebPMalloc() in addition to WebPFree()
+853ea3d8 imageio/tiff: Return error before allocating bad tile size
+af650c0b Fix a Wxor-used-as-pow false positive
+601ef17c libwebp.py: update to swig 3.0.12
+0e48d889 bugfix: last alpha rows were incorrectly decoded
+24d2ccb4 webp: Fix imageio ReadPNM() TUPLTYPE
+fab8f9cf cosmetics: normalize '*' association
+94138e0e update .gitignore
+0fe1a89d update ChangeLog (tag: v1.0.3-rc1, tag: v1.0.3)
+2ad0916d update NEWS
+1287362b bump version to 1.0.3
+7b968cc2 update AUTHORS
+9d6988f4 Fix the oscillating prediction problem at low quality
+312f74d0 makefile.unix: allow *_LIBS to be overridden w/EXTRA_LIBS
+92dbf237 filters_sse2,cosmetics: shorten some long lines
+a277d197 filters_sse2.c: quiet integer sanitizer warnings
+804540f1 Fix cpufeatures in CMake.
+bf00c15b Add CMake option for bittrace.
+a788b498 filters_sse2.c: quiet integer sanitizer warnings
+e6a92c5e filters.c: quiet integer sanitizer warnings
+ec1cc40a lossless.c: remove U32 -> S8 conversion warnings
+1106478f remove conversion U32 -> S8 warnings
+812a6b49 lossless_enc: fix some conversion warning
+4627c1c9 lossless_enc,TransformColorBlue: quiet uint32_t conv warning
+c84673a6 lossless_enc_sse{2,41}: quiet signed conv warnings
+776a7757 dec_sse2: quiet signed conv warnings
+bd39c063 Merge "thread_utils: release mutex before signaling"
+0550576f Merge "(alpha_processing,enc}_sse2: quiet signed conv warnings"
+6682f2c4 thread_utils: release mutex before signaling
+e78dea75 (alpha_processing,enc}_sse2: quiet signed conv warnings
+9acf18ba iosbuild.sh: add WebP{Demux,Mux}.framework
+b9be7e65 vwebp: remove the -fit option (and make it default)
+1394a2bb Merge "README.webp_js: update Emscripten.cmake note"
+dd3e7f8a README.webp_js: update Emscripten.cmake note
+32cf8801 predictor_enc,GetBestGreenRedToBlue: quiet implicit conv warnings
+e1c8acb5 Merge "vwebp: add a -fit option"
+cbd23dd5 vwebp: add a -fit option
+2e672351 bit_writer_utils,Flush: quiet implicit conversion warnings
+1326988d swig: update libwebp_python_wrap.c
+0e7f8548 update generated swig files
+17ed1438 Merge "PutLE{16,24}: quiet implicit conversion warnings"
+24686538 PutLE{16,24}: quiet implicit conversion warnings
+153bb3a0 fix some clang-7 warnings:
+ab2dc893 Rescaler: fix rounding error
+aa65f89a HistogramCombineStochastic: fix free of uninit value
+af0bac64 Merge "encode.h: mention 'exact' default in WebPEncodeLossless*"
+6d2e11ec encode.h: mention 'exact' default in WebPEncodeLossless*
+8c3f04fe AndroidCPUInfo: reorder terms in conditional
+fcfd9c71 BitTrace: if BITTRACE is > 0, record and print syntax bits used
+067031ea Speedups for unused Huffman groups.
+01ac46ba libwebp: Display "libjpeg error:" in imageio/jpegdec
+d9a662e1 WebPRescalerGetScaledDimensions: round scaled dimension up
+62eb3f08 libwebp: Fix missing '{' in README
+e05f785a Merge "unicode,INIT_WARGV: add missing cast"
+63c9a69f tag the VP8LHashPix() function for potential uint roll-over
+2b7214ab unicode,INIT_WARGV: add missing cast
+bf424b46 tag the GetPixPairHash64() function for potential uint roll-over
+7d05d6ca Have the color cache computation be u32-bit only.
+6bcf8769 Remove BINARYEN_METHOD in wasm settings.
+2b98df90 update ChangeLog (tag: v1.0.2-rc1, tag: v1.0.2)
+61e372b7 update NEWS
+7ae658a0 bump version to 1.0.2
+51c4907d update AUTHORS
+666bd6c6 man/cwebp.1: refine near-lossless text
+561cdce5 Clarify the doc about GetFeatures.
+aec2cf02 near_lossless: fix fuzzing-detected integer overflow
+928a75de webp: Fix VP8LBitWriterClone() bug
+5173d4ee neon IsFlat
+5b081219 IsFlat: inline when possible
+381b7b54 IsFlat: use int for thresh
+6ed15ea1 fix unprobable leak in webp_sdl.c
+22bbb24e Merge "IsFlat: return int"
+8b3fb238 Merge tag 'v1.0.1'
+f435de95 IsFlat: return int
+41521aed utils.h: only define WEBP_NEED_LOG_TABLE_8BIT when needed
+9f4d4a3f neon: GetResidualCost
+0fd7514b neon: SetResidualCoeffs
+f95a996c Simpler histogram clustering.
+e85d3313 update ChangeLog (tag: v1.0.1-rc2, tag: v1.0.1)
+fa8210e4 Fix pair update in stochastic entropy merging.
+fd198f73 add codereview.settings
+825389ac README.mux: add a reference to the AnimDecoder API
+3be698c3 CMake: fix webp_js compilation
+485ff86f Fix pair update in stochastic entropy merging.
+4cd0582d CMake: fix webp_js compilation
+4cbb4caf update NEWS
+f5a5918d bump version to 1.0.1
+d61385db Speed-up: Make sure we only initialize histograms when needed.
+6752904b Speed-up: Make sure we only initialize histograms when needed.
+0c570316 update AUTHORS
+301a2dda img2webp: add help note about arguments from a file
+f0abab92 Speedups for empty histograms.
+f2dfd925 Split HistogramAdd to only have the high level logic in C.
+06b7bc7d Fix compilation on windows and clang-cl+ninja.
+b6284d82 img2webp: add help note about arguments from a file
+decf6f6b Speedups for empty histograms.
+dea3e899 Split HistogramAdd to only have the high level logic in C.
+632798ae Merge "Fix compilation on windows and clang-cl+ninja."
+dc1a9518 Merge "libwebp: Unicode command tools on Windows"
+9cf9841b libwebp: Unicode command tools on Windows
+98179495 remove some minor TODOs
+a376e7b9 Fix compilation on windows and clang-cl+ninja.
+cbf82cc0 Remove AVX2 files.
+5030e902 Merge "TIFF decoder: remove unused KINV definition"
+ac543311 Remove a few more useless #defines
+123d3306 TIFF decoder: remove unused KINV definition
+ef1094b0 Merge "- install pkg-config files during the CMake build"
+b911fbc9 libwebp: Remove duplicate GIFDisplayError in anim_util
+eee00b66 - install pkg-config files during the CMake build
+ac3ec8c9 Merge "Clean-up the common sources in dsp."
+3e13da7b Clean-up the common sources in dsp.
+5c395f1d libwebp: cmake-format all
+e7a69729 libwebp: Add extras targets in CMakeLists.txt
+e52485d6 libwebp: Rename macros in webpmux.c
+92dc0f09 clean-up MakeInputImageCopy()
+39952de2 VP8IteratorImport: add missing 'const'
+382af7a2 clean-up WebPBlendAlpha
+14d020f6 libwebp: Use ExUtilGet*() in anim_diff
+0d92ff25 libwebp: remove useless variable in gif2webp
+556cb1b4 Merge "CMake: Set WEBP_BUILD_GIF2WEBP to off"
+da26ee49 CMake: Set WEBP_BUILD_GIF2WEBP to off
+b2a867c0 cwebp: Don't premultiply during -resize if -exact
+637141bc pngdec: fix build w/libpng < 1.4.x
+bc5092b1 pngdec: set memory functions
+50d8345a Fix CMake math library.
+6aa3e8aa Fix math library on Visual Studio.
+d71df4e2 Fix math library finding in CMake.
+de08d727 cosmetics: normalize include guard comment
+009562b4 vwebp: Fix bug when Dispose then NoBlend frames
+423f2579 Fix up CMake to create targets.
+907208f9 Wait for all threads to be done in DecodeRemaining.
+4649b3c4 vwebp: Add background color display option
+78ad57a3 Fix bad glClearColor parameters
+da96d8d9 Allow for a non-initialized alpha decompressor in DoRemap.
+2563db47 fix rescaling rounding inaccuracy
+211f37ee fix endian problems in pattern copy
+5f0f5c07 Make sure partition #0 is read before VP8 data in IDecode.
+de98732b fix GetColorf() bug
+4338cd36 misc fixes in libwebpmux
+e00af13e fix signatures after a9ceda7ff1
+a9ceda7f Speed-up chunk list operations.
+2281bbf6 Merge "Better handling of bogus Huffman codes."
+39cb9aad Better handling of bogus Huffman codes.
+89cc9d37 Merge "fix read-overflow while parsing VP8X chunk"
+95fd6507 fix read-overflow while parsing VP8X chunk
+9e729fe1 Fix VP8IoTeardownHook being called twice on worker sync failure
+29fb8562 Merge "muxread,anmf: fail on multiple image chunks"
+eb82ce76 muxread,anmf: fail on multiple image chunks
+1344a2e9 fix alpha-filtering crash when image width is larger than radius
+be738c6d muxread,ChunkVerifyAndAssign: validate chunk_size
+2c70ad76 muxread,CreateInternal: fix riff size checks
+569001f1 Fix for thread race heap-use-after-free
+c56a02d9 Android.mk: use LOCAL_EXPORT_C_INCLUDES w/public libs
+15795596 CMakeLists.txt,cosmetics: normalize if() formatting
+1a44c233 Merge "cmake: add support for webpmux"
+e9569ad7 Merge "configure,*am,cosmetics: s/WANT_/BUILD_/"
+35c7de6f cmake: add support for webpmux
+0f25e61c WebpToSDL(): fix the return value in case of error
+5d8985de configure,*am,cosmetics: s/WANT_/BUILD_/
+895fd28f Merge "man/Makefile.am: add img2webp.1"
+5cf3e2af man/Makefile.am: add img2webp.1
+2a9de5b9 Add build rules for anim_diff & anim_dump utils.
+71ed73cf fix invalid check for buffer size
+af0e4fbb gif2webp: fix transcode of loop count=65535
+dce5d764 Limit memory allocation when reading invalid Huffman codes.
+f9df0081 Merge "cmake: quiet glut deprecation warnings on OS X"
+dc39b16f webpmux.1: correct grammar
+c7aa1264 cwebp.c: fix a missing \n
+53aa51e9 Merge tag 'v1.0.0'
+698b8844 update ChangeLog (tag: v1.0.0)
 8d510751 webp-container-spec: correct frame duration=0 note
 e6b2164e vwebp: Copy Chrome's behavior w/frame duration == 0
+094b3b28 cmake: quiet glut deprecation warnings on OS X
+71c39a06 webp-container-spec: correct frame duration=0 note
+fd3d5756 vwebp: Copy Chrome's behavior w/frame duration == 0
+b0c966fb Build vwebp from CMake.
 d20b7707 update ChangeLog (tag: v1.0.0-rc3)
 0d5fad46 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
+d77bf512 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
 c1cb86af fix 16b overflow in SSE2
 e577feb7 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
 99be34b3 cwebp,get_disto: fix bpp output
+e122e511 cwebp,get_disto: fix bpp output
 f5565ca8 cmake: Make sure we use near-lossless by default.
 d898dc14 fix bug in WebPImport565: alpha value was not set
+1c8f358d Fix CMake with WASM.
+a0215fb7 webp_js: fix webp_js demo html
 882784b0 update ChangeLog (tag: v1.0.0-rc2)
 2f930e08 Revert "Use proper targets for CMake."
 8165e8fb Use proper targets for CMake.
 3f157dd5 Remove some very hard TODOs.
+abb47760 Merge "Use proper targets for CMake."
 cd758a17 {de,}mux/Makefile.am: add missing headers
+e155dda0 Use proper targets for CMake.
 b892b8ba makefile.unix,dist: use ascii for text output
 64a57d05 add -version option to anim_dump,anim_diff and img2webp
+994be82d Merge "Remove some very hard TODOs."
+4033e1d7 Remove some very hard TODOs.
 fc1b8e3a webp_js: fix webp_js demo html
 15aa48d9 update ChangeLog (tag: v1.0.0-rc1)
 e607dabc update AUTHORS
 38410c08 [CFI] Remove function pointer casts
+978eec25 [CFI] Remove function pointer casts
 c57b2736 bump version to 1.0.0
 cba28853 update NEWS
 c909d531 Merge "remove some deprecation warning on MacOSX"
@@ -362,7 +1132,7 @@
 6524fcd6 vwebp_sdl: simple viewer based on SDL
 6cf24a24 get_disto: fix reference file read
 43d472aa Merge tag 'v0.6.0'
-50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0, 0.6.0)
+50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0)
 20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
 415f3ffe update ChangeLog (tag: v0.6.0-rc3)
 3c6d1224 update NEWS
@@ -439,7 +1209,7 @@
 f04eb376 Merge tag 'v0.5.2'
 341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
 abb54827 remove Clang warnings with unused arch arguments.
-ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2, 0.5.2)
+ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2)
 aa7744ca anim_util: quiet implicit conv warnings in 32-bit
 d9120271 jpegdec: correct ContextFill signature
 24eb3940 Remove some errors when compiling the code as C++.
@@ -726,7 +1496,7 @@
 c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
 48bf5ed1 build.gradle: remove tab
 bfef6c9f Merge tag 'v0.5.1'
-3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1, 0.5.1)
+3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1)
 deb54d91 Clarify the expected 'config' lifespan in WebPIDecode()
 435308e0 Add MSA optimized encoder transform functions
 dce64bfa Add MSA optimized alpha filter functions
@@ -920,7 +1690,7 @@
 6c1d7631 avoid Yoda style for comparison
 8ce975ac SSE optimization for vector mismatch.
 7db53831 Merge tag 'v0.5.0'
-37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0, 0.5.0)
+37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0)
 7e7b6ccc faster rgb565/rgb4444/argb output
 4c7f565f update NEWS
 1f62b6b2 update AUTHORS
@@ -1704,7 +2474,7 @@
 0524d9e5 dsp: detect mips64 & disable mips32 code
 d3485d96 cwebp.1: fix quality description placement
 29a9fe22 Merge tag 'v0.4.1'
-8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1, 0.4.1)
+8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1)
 e09e9ff6 Record & log the image pre-processing time.
 f59c0b4b iosbuild.sh: specify optimization flags
 8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
@@ -2089,7 +2859,7 @@
 effcb0fd Merge tag 'v0.4.0'
 7c76255d autoconf: update ax_pthread.m4
 fff2a11b make -short work with -print_ssim, -print_psnr, etc.
-68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0, 0.4.0)
+68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0)
 256e4333 update NEWS description with new general features
 29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
 3b9f9dd0 gif2webp: don't use C99 %zu
@@ -2865,7 +3635,7 @@
 a0770727 mux struct naming
 6c66dde8 Merge "Tune Lossless encoder"
 ab5ea217 Tune Lossless encoder
-74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0)
+74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0)
 92f8059c Rename some chunks:
 3bb4bbeb Merge "Mux API change:"
 d0c79f05 Mux API change:
diff --git a/third_party/libwebp/METADATA b/third_party/libwebp/METADATA
index 51d741c..28bfad1 100644
--- a/third_party/libwebp/METADATA
+++ b/third_party/libwebp/METADATA
@@ -11,11 +11,11 @@
     type: GIT
     value: "https://chromium.googlesource.com/webm/libwebp"
   }
-  version: "698b8844e38a0c5ca50bb20f866e71291bfc3b36"
+  version: "v1.3.1"
   last_upgrade_date {
-    year: 2018
-    month: 4
-    day: 21
+    year: 2023
+    month: 7
+    day: 6
   }
   license_type: NOTICE
 }
diff --git a/third_party/libwebp/Makefile.am b/third_party/libwebp/Makefile.am
index 3f73b13..e1c1dd4 100644
--- a/third_party/libwebp/Makefile.am
+++ b/third_party/libwebp/Makefile.am
@@ -1,8 +1,8 @@
 ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src imageio man
+SUBDIRS = sharpyuv src imageio man
 EXTRA_DIST = COPYING autogen.sh
 
-if WANT_EXTRAS
+if BUILD_EXTRAS
   SUBDIRS += extras
 endif
 
diff --git a/third_party/libwebp/Makefile.vc b/third_party/libwebp/Makefile.vc
index 5d1bf86..cb6b7a9 100644
--- a/third_party/libwebp/Makefile.vc
+++ b/third_party/libwebp/Makefile.vc
@@ -5,6 +5,7 @@
 LIBWEBP_BASENAME = libwebp
 LIBWEBPMUX_BASENAME = libwebpmux
 LIBWEBPDEMUX_BASENAME = libwebpdemux
+LIBSHARPYUV_BASENAME = libsharpyuv
 
 !IFNDEF ARCH
 !IF ! [ cl 2>&1 | find "x86" > NUL ]
@@ -28,15 +29,14 @@
 
 NOLOGO     = /nologo
 CCNODBG    = cl.exe $(NOLOGO) /O2 /DNDEBUG
-CCDEBUG    = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
+CCDEBUG    = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
 CFLAGS     = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
 CFLAGS     = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
-LDFLAGS    = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
+LDFLAGS    = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
 LDFLAGS    = $(LDFLAGS) $(PLATFORM_LDFLAGS)
 LNKDLL     = link.exe /DLL $(NOLOGO)
 LNKEXE     = link.exe $(NOLOGO)
 LNKLIB     = lib.exe $(NOLOGO)
-MT         = mt.exe $(NOLOGO)
 RCNODBG    = rc.exe $(NOLOGO) /l"0x0409"  # 0x409 = U.S. English
 RCDEBUG    = $(RCNODBG) /D_DEBUG
 
@@ -53,11 +53,6 @@
 OUTDIR = $(OBJDIR)
 !ENDIF
 
-!IF "$(HAVE_AVX2)" == "1"
-CFLAGS = $(CFLAGS) /DWEBP_HAVE_AVX2
-AVX2_FLAGS = /arch:AVX2
-!ENDIF
-
 ##############################################################
 # Runtime library configuration
 !IF "$(RTLIBCFG)" == "static"
@@ -87,6 +82,7 @@
               $(DIROBJ)\extras \
               $(DIROBJ)\imageio \
               $(DIROBJ)\mux \
+              $(DIROBJ)\sharpyuv \
               $(DIROBJ)\utils \
 
 # Target configuration
@@ -101,6 +97,7 @@
 LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
 LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
 LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
 !ELSE IF "$(CFG)" == "release-dynamic"
 CC        = $(CCNODBG)
 RC        = $(RCNODBG)
@@ -114,6 +111,7 @@
 LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
 LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
 LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
 !ENDIF
 
 !IF "$(STATICLIBBUILD)" == "TRUE"
@@ -123,23 +121,28 @@
 LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib
 LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME).lib
 LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME).lib
 !ELSE IF "$(DLLBUILD)" == "TRUE"
-DLLINC = webp_dll.h
-CC     = $(CC) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL
+CC     = $(CC) /I$(DIROBJ) $(RTLIB) /DWEBP_DLL
 LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib
 LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib
 LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib
 LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME)_dll.lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME)_dll.lib
 LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
 CFGSET = TRUE
 !ENDIF
 
+!IF "$(UNICODE)" == "1"
+CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
+!ENDIF
+
 #######################
 # Usage
 #
 !IF "$(CFGSET)" == "FALSE"
 !MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
-!MESSAGE .          [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [<target>]
+!MESSAGE .          [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>]
 !MESSAGE
 !MESSAGE where <config> is one of:
 !MESSAGE -  release-static                - release static library
@@ -175,6 +178,15 @@
 # A config was provided, so the library can be built.
 #
 
+SHARPYUV_OBJS = \
+    $(DIROBJ)\sharpyuv\sharpyuv.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_cpu.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_csp.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_neon.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \
+
 DEC_OBJS = \
     $(DIROBJ)\dec\alpha_dec.obj \
     $(DIROBJ)\dec\buffer_dec.obj \
@@ -216,6 +228,7 @@
     $(DIROBJ)\dsp\lossless_msa.obj \
     $(DIROBJ)\dsp\lossless_neon.obj \
     $(DIROBJ)\dsp\lossless_sse2.obj \
+    $(DIROBJ)\dsp\lossless_sse41.obj \
     $(DIROBJ)\dsp\rescaler.obj \
     $(DIROBJ)\dsp\rescaler_mips32.obj \
     $(DIROBJ)\dsp\rescaler_mips_dsp_r2.obj \
@@ -239,9 +252,9 @@
     $(DIROBJ)\dsp\cost.obj \
     $(DIROBJ)\dsp\cost_mips32.obj \
     $(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
+    $(DIROBJ)\dsp\cost_neon.obj \
     $(DIROBJ)\dsp\cost_sse2.obj \
     $(DIROBJ)\dsp\enc.obj \
-    $(DIROBJ)\dsp\enc_avx2.obj \
     $(DIROBJ)\dsp\enc_mips32.obj \
     $(DIROBJ)\dsp\enc_mips_dsp_r2.obj \
     $(DIROBJ)\dsp\enc_msa.obj \
@@ -335,12 +348,13 @@
     $(DIROBJ)\utils\quant_levels_utils.obj \
 
 LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
-               $(UTILS_ENC_OBJS) $(DLL_OBJS)
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
+               $(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS)
 LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
 LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
 
-OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP)
+OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP) $(LIBSHARPYUV)
 !IF "$(ARCH)" == "ARM"
 ex: $(OUT_LIBS)
 all: ex
@@ -368,7 +382,7 @@
 $(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
 $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
+$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX) $(LIBSHARPYUV)
 $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
 $(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
@@ -386,13 +400,19 @@
 $(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
 $(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
+$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP) $(LIBSHARPYUV)
 $(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
 $(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
 $(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
 $(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
 $(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
+$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS)
+# EXTRA_OBJS requires private symbols from dsp. Explicitly add those when
+# building libwebp as a dll.
+!IF "$(DLLBUILD)" == "TRUE"
+$(DIRBIN)\webp_quality.exe: $(DSP_DEC_OBJS)
+!ENDIF
+$(DIRBIN)\webp_quality.exe: $(LIBWEBP)
 $(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
 $(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
@@ -403,17 +423,16 @@
 $(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
 !ENDIF  # ARCH == ARM
 
+$(LIBSHARPYUV): $(LIBSHARPYUV_OBJS)
 $(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
-$(LIBWEBP): $(LIBWEBP_OBJS)
+$(LIBWEBP): $(LIBWEBP_OBJS) $(LIBSHARPYUV)
 $(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
 $(LIBWEBPDEMUX): $(LIBWEBPDEMUX_OBJS)
 
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): $(OUTPUT_DIRS)
+$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS) $(LIBSHARPYUV_OBJS): \
+    $(OUTPUT_DIRS)
 
 !IF "$(DLLBUILD)" == "TRUE"
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \
-    $(DIROBJ)\$(DLLINC)
-
 {$(DIROBJ)}.c{$(DIROBJ)}.obj:
 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@  $<
 
@@ -423,20 +442,20 @@
 	$(RC) /fo$@ $<
 {src\mux}.rc{$(DIROBJ)\mux}.res:
 	$(RC) /fo$@ $<
+{sharpyuv}.rc{$(DIROBJ)\sharpyuv}.res:
+	$(RC) /fo$@ $<
 
-$(LIBWEBP): $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
+$(LIBSHARPYUV): $(DIROBJ)\sharpyuv\$(LIBSHARPYUV_BASENAME:_debug=).res
+$(LIBWEBP): $(LIBSHARPYUV) $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
 $(LIBWEBPDECODER): $(DIROBJ)\$(LIBWEBPDECODER_BASENAME:_debug=).res
 $(LIBWEBPMUX): $(LIBWEBP) $(DIROBJ)\mux\$(LIBWEBPMUX_BASENAME:_debug=).res
 $(LIBWEBPDEMUX): $(LIBWEBP) $(DIROBJ)\demux\$(LIBWEBPDEMUX_BASENAME:_debug=).res
 
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
 	$(LNKDLL) /out:$(DIRBIN)\$(@B:_dll=.dll) /implib:$@ $(LFLAGS) $**
 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
-
-clean::
-	@-erase /s $(DIROBJ)\$(DLLINC) 2> NUL
 !ELSE
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
 	$(LNKLIB) /out:$@ $**
 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
 !ENDIF
@@ -444,19 +463,9 @@
 $(OUTPUT_DIRS):
 	@if not exist "$(@)" mkdir "$(@)"
 
-# generate a helper include to define WEBP_EXTERN suitable for the DLL build
-$(DIROBJ)\$(DLLINC):
-	@echo #ifndef WEBP_DLL_H_ > $@
-	@echo #define WEBP_DLL_H_ >> $@
-	@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
-	@echo #endif  /* WEBP_DLL_H_ */ >> $@
-
 .SUFFIXES: .c .obj .res .exe
 # File-specific flag builds. Note batch rules take precedence over wildcards,
 # so for now name each file individually.
-$(DIROBJ)\dsp\enc_avx2.obj: src\dsp\enc_avx2.c
-	$(CC) $(CFLAGS) $(AVX2_FLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ \
-	  src\dsp\$(@B).c
 $(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c
@@ -479,6 +488,8 @@
 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
 {imageio}.c{$(DIROBJ)\imageio}.obj::
 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
+{sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj::
+	$(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
 {src\dec}.c{$(DIROBJ)\dec}.obj::
 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
 {src\demux}.c{$(DIROBJ)\demux}.obj::
@@ -492,17 +503,16 @@
 {src\utils}.c{$(DIROBJ)\utils}.obj::
 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
 
+LNKLIBS     = ole32.lib windowscodecs.lib shlwapi.lib
+!IF "$(UNICODE)" == "1"
+LNKLIBS     = $(LNKLIBS) Shell32.lib
+!ENDIF
+
 {$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe:
-	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
-	    ole32.lib windowscodecs.lib shlwapi.lib
-	$(MT) -manifest $@.manifest -outputresource:$@;1
-	del $@.manifest
+	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
 
 {$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe:
-	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
-	    ole32.lib windowscodecs.lib shlwapi.lib
-	$(MT) -manifest $@.manifest -outputresource:$@;1
-	del $@.manifest
+	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
 
 clean::
 	@-erase /s $(DIROBJ)\*.dll 2> NUL
diff --git a/third_party/libwebp/NEWS b/third_party/libwebp/NEWS
index 480cb7d..2111d33 100644
--- a/third_party/libwebp/NEWS
+++ b/third_party/libwebp/NEWS
@@ -1,3 +1,115 @@
+- 6/23/2023: version 1.3.1
+  This is a binary compatible release.
+  * security fixes for lossless encoder (#603, chromium: #1420107, #1455619,
+    CVE-2023-1999)
+  * improve error reporting through WebPPicture error codes
+  * fix upsampling for RGB565 and RGBA4444 in NEON builds
+  * img2webp: add -sharp_yuv & -near_lossless
+  * Windows builds:
+    - fix compatibility with clang-cl (#607)
+    - improve Arm64 performance with cl.exe
+    - add Arm64EC support
+  * fix webp_js with emcc >= 3.1.27 (stack size change, #614)
+  * CMake fixes (#592, #610, #612)
+  * further updates to the container and lossless bitstream docs (#581, #611)
+
+- 12/16/2022: version 1.3.0
+  This is a binary compatible release.
+  * add libsharpyuv, which exposes -sharp_yuv/config.use_sharp_yuv
+    functionality to other libraries; libwebp now depends on this library
+  * major updates to the container and lossless bitstream docs (#448, #546,
+    #551)
+  * miscellaneous warning, bug & build fixes (#576, #583, #584)
+
+- 8/4/2022: version 1.2.4
+  This is a binary compatible release.
+  * restore CMake libwebpmux target name for compatibility with 1.2.2 (#575)
+  * fix lossless crunch mode encoding with WEBP_REDUCE_SIZE
+    (chromium: #1345547, #1345595, #1345772, #1345804)
+
+- 6/30/2022: version 1.2.3
+  This is a binary compatible release.
+  * security fix for lossless encoder (#565, chromium:1313709)
+  * improved progress granularity in WebPReportProgress() when using lossless
+  * improved precision in Sharp YUV (-sharp_yuv) conversion
+  * many corrections to webp-lossless-bitstream-spec.txt (#551)
+  * crash/leak fixes on error/OOM and other bug fixes (#558, #563, #569, #573)
+
+- 1/11/2022: version 1.2.2
+  This is a binary compatible release.
+  * webpmux: add "-set bgcolor A,R,G,B"
+  * add ARM64 NEON support for MSVC builds (#539)
+  * fix duplicate include error in Xcode when using multiple XCFrameworks in a
+    project (#542)
+  * doc updates and bug fixes (#538, #544, #548, #550)
+
+- 7/20/2021: version 1.2.1
+  This is a binary compatible release.
+  * minor lossless encoder improvements and x86 color conversion speed up
+  * add ARM64 simulator support to xcframeworkbuild.sh (#510)
+  * further security related hardening in libwebp & examples
+    (issues: #497, #508, #518)
+    (chromium: #1196480, #1196773, #1196775, #1196777, #1196778, #1196850)
+    (oss-fuzz: #28658, #28978)
+  * toolchain updates and bug fixes (#498, #501, #502, #504, #505, #506, #509,
+                                     #533)
+  * use more inclusive language within the source (#507)
+
+- 12/23/2020: version 1.2.0
+  * API changes:
+    - libwebp:
+      encode.h: add a qmin / qmax range for quality factor (cwebp adds -qrange)
+  * lossless encoder improvements
+  * SIMD support for Wasm builds
+  * add xcframeworkbuild.sh, supports Mac Catalyst builds
+  * import fuzzers from oss-fuzz & chromium (#409)
+  * webpmux: add an '-set loop <value>' option (#494)
+  * toolchain updates and bug fixes (#449, #463, #470, #475, #477, #478, #479,
+    #488, #491)
+
+- 12/18/2019: version 1.1.0
+  * API changes:
+    - libwebp:
+      WebPMalloc (issue #442)
+    - extras:
+      WebPUnmultiplyARGB
+  * alpha decode fix (issue #439)
+  * toolchain updates and bug fixes
+    (chromium: #1026858, #1027136, #1027409, #1028620, #1028716, #995200)
+    (oss-fuzz: #19430, #19447)
+
+- 7/4/2019: version 1.0.3
+  This is a binary compatible release.
+  * resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
+    odd sizes (issues #418, #434)
+  * lossless encode/decode performance improvements
+  * lossy compression performance improvement at low quality levels with flat
+    content (issue #432)
+  * python swig files updated to support python 3
+  Tool updates:
+    vwebp will now preserve the aspect ratio of images that exceed monitor
+    resolution by scaling the image to fit (issue #433)
+
+- 1/14/2019: version 1.0.2
+  This is a binary compatible release.
+  * (Windows) unicode file support in the tools (linux and mac already had
+    support, issue #398)
+  * lossless encoder speedups
+  * lossy encoder speedup on ARM
+  * lossless multi-threaded security fix (chromium:917029)
+
+- 11/2/2018: version 1.0.1
+  This is a binary compatible release.
+  * lossless encoder speedups
+  * big-endian fix for alpha decoding (issue #393)
+  * gif2webp fix for loop count=65535 transcode (issue #382)
+  * further security related hardening in libwebp & libwebpmux
+    (issues #383, #385, #386, #387, #388, #391)
+    (oss-fuzz #9099, #9100, #9105, #9106, #9111, #9112, #9119, #9123, #9170,
+              #9178, #9179, #9183, #9186, #9191, #9364, #9417, #9496, #10349,
+              #10423, #10634, #10700, #10838, #10922, #11021, #11088, #11152)
+  * miscellaneous bug & build fixes (issues #381, #394, #396, #397, #400)
+
 - 4/2/2018: version 1.0.0
   This is a binary compatible release.
   * lossy encoder improvements to avoid chroma shifts in various circumstances
diff --git a/third_party/libwebp/PRESUBMIT.py b/third_party/libwebp/PRESUBMIT.py
new file mode 100644
index 0000000..91ad12e
--- /dev/null
+++ b/third_party/libwebp/PRESUBMIT.py
@@ -0,0 +1,245 @@
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Top-level presubmit script for libwebp.
+
+See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
+details on the presubmit API built into depot_tools.
+"""
+
+import re
+import subprocess2
+
+USE_PYTHON3 = True
+_BASH_INDENTATION = "2"
+_GIT_COMMIT_SUBJECT_LENGTH = 65
+_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
+_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
+_INCLUDE_SOURCE_FILES_ONLY = [r".*\.[ch]$"]
+_LIBWEBP_MAX_LINE_LENGTH = 80
+
+
+def _CheckCommitSubjectLength(input_api, output_api):
+  """Ensures commit's subject length is no longer than 65 chars."""
+  name = "git-commit subject"
+  cmd = ["git", "log", "-1", "--pretty=%s"]
+  start = input_api.time.time()
+  proc = subprocess2.Popen(
+      cmd,
+      stderr=subprocess2.PIPE,
+      stdout=subprocess2.PIPE,
+      universal_newlines=True)
+
+  stdout, _ = proc.communicate()
+  duration = input_api.time.time() - start
+
+  if not re.match(r"^Revert",
+                  stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
+    failure_msg = (
+        "The commit subject: %s is too long (%d chars)\n"
+        "Try to keep this to 50 or less (up to 65 is permitted for "
+        "non-reverts).\n"
+        "https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
+        "Project#_commit_guidelines") % (stdout, len(stdout) - 1)
+    return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
+                                     (name, duration, failure_msg))
+
+  return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
+
+
+def _CheckDuplicateFiles(input_api, output_api):
+  """Ensures there are not repeated filenames."""
+  all_files = []
+  for f in input_api.change.AllFiles():
+    for include_file in _INCLUDE_SOURCE_FILES_ONLY:
+      if re.match(include_file, f):
+        all_files.append(f)
+        break
+
+  basename_to_path = {}
+  for f in all_files:
+    basename_file = input_api.basename(f)
+    if basename_file in basename_to_path:
+      basename_to_path[basename_file].append(f)
+    else:
+      basename_to_path[basename_file] = [f]
+
+  dupes = []
+  for files in basename_to_path.values():
+    if len(files) > 1:
+      dupes.extend(files)
+
+  if dupes:
+    return output_api.PresubmitError(
+        "Duplicate source files, rebase or rename some to make them unique:\n%s"
+        % dupes)
+  return output_api.PresubmitResult("No duplicates, success\n")
+
+
+def _GetFilesToSkip(input_api):
+  return list(input_api.DEFAULT_FILES_TO_SKIP) + [
+      r"swig/.*\.py$",
+      r"\.pylintrc$",
+  ]
+
+
+def _RunManCmd(input_api, output_api, man_file):
+  """man command wrapper."""
+  cmd = ["man", "--warnings", "-EUTF-8", "-l", "-Tutf8", "-Z", man_file]
+  name = "Check %s file." % man_file
+  start = input_api.time.time()
+  output, _ = subprocess2.communicate(
+      cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
+  duration = input_api.time.time() - start
+  if output[1]:
+    return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
+                                     (name, " ".join(cmd), duration, output[1]))
+  return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
+                                    (name, " ".join(cmd), duration))
+
+
+def _RunShellCheckCmd(input_api, output_api, bash_file):
+  """shellcheck command wrapper."""
+  cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
+  name = "Check %s file." % bash_file
+  start = input_api.time.time()
+  output, rc = subprocess2.communicate(
+      cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
+  duration = input_api.time.time() - start
+  if rc == 0:
+    return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
+                                      (name, " ".join(cmd), duration))
+  return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
+                                   (name, " ".join(cmd), duration, output[1]))
+
+
+def _RunShfmtCheckCmd(input_api, output_api, bash_file):
+  """shfmt command wrapper."""
+  cmd = [
+      "shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
+      bash_file
+  ]
+  name = "Check %s file." % bash_file
+  start = input_api.time.time()
+  output, rc = subprocess2.communicate(
+      cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
+  duration = input_api.time.time() - start
+  if rc == 0:
+    return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
+                                      (name, " ".join(cmd), duration))
+  return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
+                                   (name, " ".join(cmd), duration, output[1]))
+
+
+def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
+  """Ensure that libwebp/ files are clean."""
+  file_filter = lambda x: input_api.FilterSourceFile(
+      x, files_to_check=files_to_check, files_to_skip=None)
+
+  affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
+  results = [
+      run_cmd(input_api, output_api, f.AbsoluteLocalPath())
+      for f in affected_files
+  ]
+  return results
+
+
+def _CommonChecks(input_api, output_api):
+  """Ensures this patch does not have trailing spaces, extra EOLs,
+     or long lines.
+  """
+  results = []
+  results.extend(
+      input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
+          input_api, output_api))
+  results.extend(
+      input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
+  results.extend(
+      input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
+          input_api, output_api))
+  results.append(_CheckCommitSubjectLength(input_api, output_api))
+  results.append(_CheckDuplicateFiles(input_api, output_api))
+
+  source_file_filter = lambda x: input_api.FilterSourceFile(
+      x, files_to_skip=_GetFilesToSkip(input_api))
+  results.extend(
+      input_api.canned_checks.CheckLongLines(
+          input_api,
+          output_api,
+          maxlen=_LIBWEBP_MAX_LINE_LENGTH,
+          source_file_filter=source_file_filter))
+
+  results.extend(
+      input_api.canned_checks.CheckPatchFormatted(
+          input_api,
+          output_api,
+          check_clang_format=False,
+          check_python=True,
+          result_factory=output_api.PresubmitError))
+  results.extend(
+      _RunCmdOnCheckedFiles(input_api, output_api, _RunManCmd,
+                            _INCLUDE_MAN_FILES_ONLY))
+  # Run pylint.
+  results.extend(
+      input_api.canned_checks.RunPylint(
+          input_api,
+          output_api,
+          files_to_skip=_GetFilesToSkip(input_api),
+          pylintrc=".pylintrc",
+          version="2.7"))
+
+  # Binaries shellcheck and shfmt are not installed in depot_tools.
+  # Installation is needed
+  try:
+    subprocess2.communicate(["shellcheck", "--version"])
+    results.extend(
+        _RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd,
+                              _INCLUDE_BASH_FILES_ONLY))
+    print("shfmt")
+    subprocess2.communicate(["shfmt", "-version"])
+    results.extend(
+        _RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd,
+                              _INCLUDE_BASH_FILES_ONLY))
+  except OSError as os_error:
+    results.append(
+        output_api.PresubmitPromptWarning(
+            "%s\nPlease install missing binaries locally." % os_error.args[0]))
+  return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  results = []
+  results.extend(_CommonChecks(input_api, output_api))
+  return results
+
+
+def CheckChangeOnCommit(input_api, output_api):
+  results = []
+  results.extend(_CommonChecks(input_api, output_api))
+  return results
diff --git a/third_party/libwebp/README b/third_party/libwebp/README
deleted file mode 100644
index a76b378..0000000
--- a/third_party/libwebp/README
+++ /dev/null
@@ -1,782 +0,0 @@
-          __   __  ____  ____  ____
-         /  \\/  \/  _ \/  _ )/  _ \
-         \       /   __/  _  \   __/
-          \__\__/\____/\_____/__/ ____  ___
-                / _/ /    \    \ /  _ \/ _/
-               /  \_/   / /   \ \   __/  \__
-               \____/____/\_____/_____/____/v1.0.0
-
-Description:
-============
-
-WebP codec: library to encode and decode images in WebP format. This package
-contains the library that can be used in other programs to add WebP support,
-as well as the command line tools 'cwebp' and 'dwebp'.
-
-See http://developers.google.com/speed/webp
-
-The latest source tree is available at
-https://chromium.googlesource.com/webm/libwebp
-
-It is released under the same license as the WebM project.
-See http://www.webmproject.org/license/software/ or the
-"COPYING" file for details. An additional intellectual
-property rights grant can be found in the file PATENTS.
-
-Building:
-=========
-
-Windows build:
---------------
-
-By running:
-
-  nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
-
-the directory output\release-static\(x64|x86)\bin will contain the tools
-cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
-contain the libwebp static library.
-The target architecture (x86/x64) is detected by Makefile.vc from the Visual
-Studio compiler (cl.exe) available in the system path.
-
-Unix build using makefile.unix:
--------------------------------
-
-On platforms with GNU tools installed (gcc and make), running
-
-  make -f makefile.unix
-
-will build the binaries examples/cwebp and examples/dwebp, along
-with the static library src/libwebp.a. No system-wide installation
-is supplied, as this is a simple alternative to the full installation
-system based on the autoconf tools (see below).
-Please refer to makefile.unix for additional details and customizations.
-
-Using autoconf tools:
----------------------
-Prerequisites:
-A compiler (e.g., gcc), make, autoconf, automake, libtool.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install gcc make autoconf automake libtool
-
-When building from git sources, you will need to run autogen.sh to generate the
-configure script.
-
-./configure
-make
-make install
-
-should be all you need to have the following files
-
-/usr/local/include/webp/decode.h
-/usr/local/include/webp/encode.h
-/usr/local/include/webp/types.h
-/usr/local/lib/libwebp.*
-/usr/local/bin/cwebp
-/usr/local/bin/dwebp
-
-installed.
-
-Note: A decode-only library, libwebpdecoder, is available using the
-'--enable-libwebpdecoder' flag. The encode library is built separately and can
-be installed independently using a minor modification in the corresponding
-Makefile.am configure files (see comments there). See './configure --help' for
-more options.
-
-Building for MIPS Linux:
-------------------------
-MIPS Linux toolchain stable available releases can be found at:
-https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
-
-# Add toolchain to PATH
-export PATH=$PATH:/path/to/toolchain/bin
-
-# 32-bit build for mips32r5 (p5600)
-HOST=mips-mti-linux-gnu
-MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
-  -msched-weight -mload-store-pairs -fPIE"
-MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
-
-# 64-bit build for mips64r6 (i6400)
-HOST=mips-img-linux-gnu
-MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
-  -msched-weight -mload-store-pairs -fPIE"
-MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
-
-./configure --host=${HOST} --build=`config.guess` \
-  CC="${HOST}-gcc -EL" \
-  CFLAGS="$MIPS_CFLAGS" \
-  LDFLAGS="$MIPS_LDFLAGS"
-make
-make install
-
-CMake:
-------
-With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo
-and the JS bindings.
-
-Prerequisites:
-A compiler (e.g., gcc with autotools) and CMake.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install build-essential cmake
-
-When building from git sources, you will need to run cmake to generate the
-makefiles.
-
-mkdir build && cd build && cmake ../
-make
-make install
-
-If you also want any of the executables, you will need to enable them through
-CMake, e.g.:
-
-cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
-
-or through your favorite interface (like ccmake or cmake-qt-gui).
-
-Finally, once installed, you can also use WebP in your CMake project by doing:
-
-find_package(WebP)
-
-which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
-
-Gradle:
--------
-The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
-dwebp and webpmux_example.
-
-Prerequisites:
-A compiler (e.g., gcc with autotools) and gradle.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install build-essential gradle
-
-When building from git sources, you will need to run the Gradle wrapper with the
-appropriate target, e.g. :
-
-./gradlew buildAllExecutables
-
-SWIG bindings:
---------------
-
-To generate language bindings from swig/libwebp.swig at least swig-1.3
-(http://www.swig.org) is required.
-
-Currently the following functions are mapped:
-Decode:
-  WebPGetDecoderVersion
-  WebPGetInfo
-  WebPDecodeRGBA
-  WebPDecodeARGB
-  WebPDecodeBGRA
-  WebPDecodeBGR
-  WebPDecodeRGB
-
-Encode:
-  WebPGetEncoderVersion
-  WebPEncodeRGBA
-  WebPEncodeBGRA
-  WebPEncodeRGB
-  WebPEncodeBGR
-  WebPEncodeLosslessRGBA
-  WebPEncodeLosslessBGRA
-  WebPEncodeLosslessRGB
-  WebPEncodeLosslessBGR
-
-See swig/README for more detailed build instructions.
-
-Java bindings:
-
-To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
-is necessary for enum support. The output is intended to be a shared object /
-DLL that can be loaded via System.loadLibrary("webp_jni").
-
-Python bindings:
-
-To build the swig-generated Python extension code at least Python 2.6 is
-required. Python < 2.6 may build with some minor changes to libwebp.swig or the
-generated code, but is untested.
-
-Encoding tool:
-==============
-
-The examples/ directory contains tools for encoding (cwebp) and
-decoding (dwebp) images.
-
-The easiest use should look like:
-  cwebp input.png -q 80 -o output.webp
-which will convert the input file to a WebP file using a quality factor of 80
-on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
-value is 75).
-You might want to try the -lossless flag too, which will compress the source
-(in RGBA format) without any loss. The -q quality parameter will in this case
-control the amount of processing time spent trying to make the output file as
-small as possible.
-
-A longer list of options is available using the -longhelp command line flag:
-
-> cwebp -longhelp
-Usage:
- cwebp [-preset <...>] [options] in_file [-o out_file]
-
-If input size (-s) for an image is not specified, it is
-assumed to be a PNG, JPEG, TIFF or WebP file.
-
-Options:
-  -h / -help ............. short help
-  -H / -longhelp ......... long help
-  -q <float> ............. quality factor (0:small..100:big), default=75
-  -alpha_q <int> ......... transparency-compression quality (0..100),
-                           default=100
-  -preset <string> ....... preset setting, one of:
-                            default, photo, picture,
-                            drawing, icon, text
-     -preset must come first, as it overwrites other parameters
-  -z <int> ............... activates lossless preset with given
-                           level in [0:fast, ..., 9:slowest]
-
-  -m <int> ............... compression method (0=fast, 6=slowest), default=4
-  -segments <int> ........ number of segments to use (1..4), default=4
-  -size <int> ............ target size (in bytes)
-  -psnr <float> .......... target PSNR (in dB. typically: 42)
-
-  -s <int> <int> ......... input size (width x height) for YUV
-  -sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
-  -f <int> ............... filter strength (0=off..100), default=60
-  -sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
-  -strong ................ use strong filter instead of simple (default)
-  -nostrong .............. use simple filter instead of strong
-  -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
-  -partition_limit <int> . limit quality to fit the 512k limit on
-                           the first partition (0=no degradation ... 100=full)
-  -pass <int> ............ analysis pass number (1..10)
-  -crop <x> <y> <w> <h> .. crop picture with the given rectangle
-  -resize <w> <h> ........ resize picture (after any cropping)
-  -mt .................... use multi-threading if available
-  -low_memory ............ reduce memory usage (slower encoding)
-  -map <int> ............. print map of extra info
-  -print_psnr ............ prints averaged PSNR distortion
-  -print_ssim ............ prints averaged SSIM distortion
-  -print_lsim ............ prints local-similarity distortion
-  -d <file.pgm> .......... dump the compressed output (PGM file)
-  -alpha_method <int> .... transparency-compression method (0..1), default=1
-  -alpha_filter <string> . predictive filtering for alpha plane,
-                           one of: none, fast (default) or best
-  -exact ................. preserve RGB values in transparent area, default=off
-  -blend_alpha <hex> ..... blend colors against background color
-                           expressed as RGB values written in
-                           hexadecimal, e.g. 0xc0e0d0 for red=0xc0
-                           green=0xe0 and blue=0xd0
-  -noalpha ............... discard any transparency information
-  -lossless .............. encode image losslessly, default=off
-  -near_lossless <int> ... use near-lossless image
-                           preprocessing (0..100=off), default=100
-  -hint <string> ......... specify image characteristics hint,
-                           one of: photo, picture or graph
-
-  -metadata <string> ..... comma separated list of metadata to
-                           copy from the input to the output if present.
-                           Valid values: all, none (default), exif, icc, xmp
-
-  -short ................. condense printed message
-  -quiet ................. don't print anything
-  -version ............... print version number and exit
-  -noasm ................. disable all assembly optimizations
-  -v ..................... verbose, e.g. print encoding/decoding times
-  -progress .............. report encoding progress
-
-Experimental Options:
-  -jpeg_like ............. roughly match expected JPEG size
-  -af .................... auto-adjust filter strength
-  -pre <int> ............. pre-processing filter
-
-The main options you might want to try in order to further tune the
-visual quality are:
- -preset
- -sns
- -f
- -m
-
-Namely:
-  * 'preset' will set up a default encoding configuration targeting a
-     particular type of input. It should appear first in the list of options,
-     so that subsequent options can take effect on top of this preset.
-     Default value is 'default'.
-  * 'sns' will progressively turn on (when going from 0 to 100) some additional
-     visual optimizations (like: segmentation map re-enforcement). This option
-     will balance the bit allocation differently. It tries to take bits from the
-     "easy" parts of the picture and use them in the "difficult" ones instead.
-     Usually, raising the sns value (at fixed -q value) leads to larger files,
-     but with better quality.
-     Typical value is around '75'.
-  * 'f' option directly links to the filtering strength used by the codec's
-     in-loop processing. The higher the value, the smoother the
-     highly-compressed area will look. This is particularly useful when aiming
-     at very small files. Typical values are around 20-30. Note that using the
-     option -strong/-nostrong will change the type of filtering. Use "-f 0" to
-     turn filtering off.
-  * 'm' controls the trade-off between encoding speed and quality. Default is 4.
-     You can try -m 5 or -m 6 to explore more (time-consuming) encoding
-     possibilities. A lower value will result in faster encoding at the expense
-     of quality.
-
-Decoding tool:
-==============
-
-There is a decoding sample in examples/dwebp.c which will take
-a .webp file and decode it to a PNG image file (amongst other formats).
-This is simply to demonstrate the use of the API. You can verify the
-file test.webp decodes to exactly the same as test_ref.ppm by using:
-
- cd examples
- ./dwebp test.webp -ppm -o test.ppm
- diff test.ppm test_ref.ppm
-
-The full list of options is available using -h:
-
-> dwebp -h
-Usage: dwebp in_file [options] [-o out_file]
-
-Decodes the WebP image file to PNG format [Default]
-Use following options to convert into alternate image formats:
-  -pam ......... save the raw RGBA samples as a color PAM
-  -ppm ......... save the raw RGB samples as a color PPM
-  -bmp ......... save as uncompressed BMP format
-  -tiff ........ save as uncompressed TIFF format
-  -pgm ......... save the raw YUV samples as a grayscale PGM
-                 file with IMC4 layout
-  -yuv ......... save the raw YUV samples in flat layout
-
- Other options are:
-  -version ..... print version number and exit
-  -nofancy ..... don't use the fancy YUV420 upscaler
-  -nofilter .... disable in-loop filtering
-  -nodither .... disable dithering
-  -dither <d> .. dithering strength (in 0..100)
-  -alpha_dither  use alpha-plane dithering if needed
-  -mt .......... use multi-threading
-  -crop <x> <y> <w> <h> ... crop output with the given rectangle
-  -resize <w> <h> ......... scale the output (*after* any cropping)
-  -flip ........ flip the output vertically
-  -alpha ....... only save the alpha plane
-  -incremental . use incremental decoding (useful for tests)
-  -h ........... this help message
-  -v ........... verbose (e.g. print encoding/decoding times)
-  -quiet ....... quiet mode, don't print anything
-  -noasm ....... disable all assembly optimizations
-
-WebP file analysis tool:
-========================
-
-'webpinfo' can be used to print out the chunk level structure and bitstream
-header information of WebP files. It can also check if the files are of valid
-WebP format.
-
-Usage: webpinfo [options] in_files
-Note: there could be multiple input files;
-      options must come before input files.
-Options:
-  -version ........... Print version number and exit.
-  -quiet ............. Do not show chunk parsing information.
-  -diag .............. Show parsing error diagnosis.
-  -summary ........... Show chunk stats summary.
-  -bitstream_info .... Parse bitstream header.
-
-Visualization tool:
-===================
-
-There's a little self-serve visualization tool called 'vwebp' under the
-examples/ directory. It uses OpenGL to open a simple drawing window and show
-a decoded WebP file. It's not yet integrated in the automake build system, but
-you can try to manually compile it using the recommendations below.
-
-Usage: vwebp in_file [options]
-
-Decodes the WebP image file and visualize it using OpenGL
-Options are:
-  -version ..... print version number and exit
-  -noicc ....... don't use the icc profile if present
-  -nofancy ..... don't use the fancy YUV420 upscaler
-  -nofilter .... disable in-loop filtering
-  -dither <int>  dithering strength (0..100), default=50
-  -noalphadither disable alpha plane dithering
-  -mt .......... use multi-threading
-  -info ........ print info
-  -h ........... this help message
-
-Keyboard shortcuts:
-  'c' ................ toggle use of color profile
-  'i' ................ overlay file information
-  'd' ................ disable blending & disposal (debug)
-  'q' / 'Q' / ESC .... quit
-
-Building:
----------
-
-Prerequisites:
-1) OpenGL & OpenGL Utility Toolkit (GLUT)
-  Linux:
-    $ sudo apt-get install freeglut3-dev mesa-common-dev
-  Mac + XCode:
-    - These libraries should be available in the OpenGL / GLUT frameworks.
-  Windows:
-    http://freeglut.sourceforge.net/index.php#download
-
-2) (Optional) qcms (Quick Color Management System)
-  i. Download qcms from Mozilla / Chromium:
-    http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
-    http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
-  ii. Build and archive the source files as libqcms.a / qcms.lib
-  iii. Update makefile.unix / Makefile.vc
-    a) Define WEBP_HAVE_QCMS
-    b) Update include / library paths to reference the qcms directory.
-
-Build using makefile.unix / Makefile.vc:
-$ make -f makefile.unix examples/vwebp
-> nmake /f Makefile.vc CFG=release-static \
-    ../obj/x64/release-static/bin/vwebp.exe
-
-Animation creation tool:
-========================
-The utility 'img2webp' can turn a sequence of input images (PNG, JPEG, ...)
-into an animated WebP file. It offers fine control over duration, encoding
-modes, etc.
-
-Usage:
-
-  img2webp [file-level options] [image files...] [per-frame options...]
-
-File-level options (only used at the start of compression):
- -min_size ............ minimize size
- -loop <int> .......... loop count (default: 0, = infinite loop)
- -kmax <int> .......... maximum number of frame between key-frames
-                        (0=only keyframes)
- -kmin <int> .......... minimum number of frame between key-frames
-                        (0=disable key-frames altogether)
- -mixed ............... use mixed lossy/lossless automatic mode
- -v ................... verbose mode
- -h ................... this help
- -version ............. print version number and exit
-
-Per-frame options (only used for subsequent images input):
- -d <int> ............. frame duration in ms (default: 100)
- -lossless  ........... use lossless mode (default)
- -lossy ... ........... use lossy mode
- -q <float> ........... quality
- -m <int> ............. method to use
-
-example: img2webp -loop 2 in0.png -lossy in1.jpg
-                  -d 80 in2.tiff -o out.webp
-
-Animated GIF conversion:
-========================
-Animated GIF files can be converted to WebP files with animation using the
-gif2webp utility available under examples/. The files can then be viewed using
-vwebp.
-
-Usage:
- gif2webp [options] gif_file -o webp_file
-Options:
-  -h / -help ............. this help
-  -lossy ................. encode image using lossy compression
-  -mixed ................. for each frame in the image, pick lossy
-                           or lossless compression heuristically
-  -q <float> ............. quality factor (0:small..100:big)
-  -m <int> ............... compression method (0=fast, 6=slowest)
-  -min_size .............. minimize output size (default:off)
-                           lossless compression by default; can be
-                           combined with -q, -m, -lossy or -mixed
-                           options
-  -kmin <int> ............ min distance between key frames
-  -kmax <int> ............ max distance between key frames
-  -f <int> ............... filter strength (0=off..100)
-  -metadata <string> ..... comma separated list of metadata to
-                           copy from the input to the output if present
-                           Valid values: all, none, icc, xmp (default)
-  -loop_compatibility .... use compatibility mode for Chrome
-                           version prior to M62 (inclusive)
-  -mt .................... use multi-threading if available
-
-  -version ............... print version number and exit
-  -v ..................... verbose
-  -quiet ................. don't print anything
-
-Building:
----------
-With the libgif development files installed, gif2webp can be built using
-makefile.unix:
-$ make -f makefile.unix examples/gif2webp
-
-or using autoconf:
-$ ./configure --enable-everything
-$ make
-
-Comparison of animated images:
-==============================
-Test utility anim_diff under examples/ can be used to compare two animated
-images (each can be GIF or WebP).
-
-Usage: anim_diff <image1> <image2> [options]
-
-Options:
-  -dump_frames <folder> dump decoded frames in PAM format
-  -min_psnr <float> ... minimum per-frame PSNR
-  -raw_comparison ..... if this flag is not used, RGB is
-                        premultiplied before comparison
-  -max_diff <int> ..... maximum allowed difference per channel
-                        between corresponding pixels in subsequent
-                        frames
-  -h .................. this help
-  -version ............ print version number and exit
-
-Building:
----------
-With the libgif development files and a C++ compiler installed, anim_diff can
-be built using makefile.unix:
-$ make -f makefile.unix examples/anim_diff
-
-or using autoconf:
-$ ./configure --enable-everything
-$ make
-
-Encoding API:
-=============
-
-The main encoding functions are available in the header src/webp/encode.h
-The ready-to-use ones are:
-size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
-                     float quality_factor, uint8_t** output);
-size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
-                     float quality_factor, uint8_t** output);
-size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
-                      float quality_factor, uint8_t** output);
-size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
-                      float quality_factor, uint8_t** output);
-
-They will convert raw RGB samples to a WebP data. The only control supplied
-is the quality factor.
-
-There are some variants for using the lossless format:
-
-size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
-                             int stride, uint8_t** output);
-size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
-                             int stride, uint8_t** output);
-size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
-                              int stride, uint8_t** output);
-size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
-                              int stride, uint8_t** output);
-
-Of course in this case, no quality factor is needed since the compression
-occurs without loss of the input values, at the expense of larger output sizes.
-
-Advanced encoding API:
-----------------------
-
-A more advanced API is based on the WebPConfig and WebPPicture structures.
-
-WebPConfig contains the encoding settings and is not tied to a particular
-picture.
-WebPPicture contains input data, on which some WebPConfig will be used for
-compression.
-The encoding flow looks like:
-
--------------------------------------- BEGIN PSEUDO EXAMPLE
-
-#include <webp/encode.h>
-
-  // Setup a config, starting form a preset and tuning some additional
-  // parameters
-  WebPConfig config;
-  if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
-    return 0;   // version error
-  }
-  // ... additional tuning
-  config.sns_strength = 90;
-  config.filter_sharpness = 6;
-  config_error = WebPValidateConfig(&config);  // not mandatory, but useful
-
-  // Setup the input data
-  WebPPicture pic;
-  if (!WebPPictureInit(&pic)) {
-    return 0;  // version error
-  }
-  pic.width = width;
-  pic.height = height;
-  // allocated picture of dimension width x height
-  if (!WebPPictureAllocate(&pic)) {
-    return 0;   // memory error
-  }
-  // at this point, 'pic' has been initialized as a container,
-  // and can receive the Y/U/V samples.
-  // Alternatively, one could use ready-made import functions like
-  // WebPPictureImportRGB(), which will take care of memory allocation.
-  // In any case, past this point, one will have to call
-  // WebPPictureFree(&pic) to reclaim memory.
-
-  // Set up a byte-output write method. WebPMemoryWriter, for instance.
-  WebPMemoryWriter wrt;
-  WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
-
-  pic.writer = MyFileWriter;
-  pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
-
-  // Compress!
-  int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
-  WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
-
-  // output data should have been handled by the writer at that point.
-  // -> compressed data is the memory buffer described by wrt.mem / wrt.size
-
-  // deallocate the memory used by compressed data
-  WebPMemoryWriterClear(&wrt);
-
--------------------------------------- END PSEUDO EXAMPLE
-
-Decoding API:
-=============
-
-This is mainly just one function to call:
-
-#include "webp/decode.h"
-uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
-                       int* width, int* height);
-
-Please have a look at the file src/webp/decode.h for the details.
-There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
-decoding to raw Y'CbCr samples. One can also decode the image directly into a
-pre-allocated buffer.
-
-To detect a WebP file and gather the picture's dimensions, the function:
-  int WebPGetInfo(const uint8_t* data, size_t data_size,
-                  int* width, int* height);
-is supplied. No decoding is involved when using it.
-
-Incremental decoding API:
-=========================
-
-In the case when data is being progressively transmitted, pictures can still
-be incrementally decoded using a slightly more complicated API. Decoder state
-is stored into an instance of the WebPIDecoder object. This object can be
-created with the purpose of decoding either RGB or Y'CbCr samples.
-For instance:
-
-  WebPDecBuffer buffer;
-  WebPInitDecBuffer(&buffer);
-  buffer.colorspace = MODE_BGR;
-  ...
-  WebPIDecoder* idec = WebPINewDecoder(&buffer);
-
-As data is made progressively available, this incremental-decoder object
-can be used to decode the picture further. There are two (mutually exclusive)
-ways to pass freshly arrived data:
-
-either by appending the fresh bytes:
-
-  WebPIAppend(idec, fresh_data, size_of_fresh_data);
-
-or by just mentioning the new size of the transmitted data:
-
-  WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
-
-Note that 'buffer' can be modified between each call to WebPIUpdate, in
-particular when the buffer is resized to accommodate larger data.
-
-These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
-decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
-status is an error condition.
-
-The 'idec' object must always be released (even upon an error condition) by
-calling: WebPDelete(idec).
-
-To retrieve partially decoded picture samples, one must use the corresponding
-method: WebPIDecGetRGB or WebPIDecGetYUVA.
-It will return the last displayable pixel row.
-
-Lastly, note that decoding can also be performed into a pre-allocated pixel
-buffer. This buffer must be passed when creating a WebPIDecoder, calling
-WebPINewRGB() or WebPINewYUVA().
-
-Please have a look at the src/webp/decode.h header for further details.
-
-Advanced Decoding API:
-======================
-
-WebP decoding supports an advanced API which provides on-the-fly cropping and
-rescaling, something of great usefulness on memory-constrained environments like
-mobile phones. Basically, the memory usage will scale with the output's size,
-not the input's, when one only needs a quick preview or a zoomed in portion of
-an otherwise too-large picture. Some CPU can be saved too, incidentally.
-
--------------------------------------- BEGIN PSEUDO EXAMPLE
-     // A) Init a configuration object
-     WebPDecoderConfig config;
-     CHECK(WebPInitDecoderConfig(&config));
-
-     // B) optional: retrieve the bitstream's features.
-     CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
-
-     // C) Adjust 'config' options, if needed
-     config.options.no_fancy_upsampling = 1;
-     config.options.use_scaling = 1;
-     config.options.scaled_width = scaledWidth();
-     config.options.scaled_height = scaledHeight();
-     // etc.
-
-     // D) Specify 'config' output options for specifying output colorspace.
-     // Optionally the external image decode buffer can also be specified.
-     config.output.colorspace = MODE_BGRA;
-     // Optionally, the config.output can be pointed to an external buffer as
-     // well for decoding the image. This externally supplied memory buffer
-     // should be big enough to store the decoded picture.
-     config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
-     config.output.u.RGBA.stride = scanline_stride;
-     config.output.u.RGBA.size = total_size_of_the_memory_buffer;
-     config.output.is_external_memory = 1;
-
-     // E) Decode the WebP image. There are two variants w.r.t decoding image.
-     // The first one (E.1) decodes the full image and the second one (E.2) is
-     // used to incrementally decode the image using small input buffers.
-     // Any one of these steps can be used to decode the WebP image.
-
-     // E.1) Decode full image.
-     CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
-
-     // E.2) Decode image incrementally.
-     WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
-     CHECK(idec != NULL);
-     while (bytes_remaining > 0) {
-       VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
-       if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
-         bytes_remaining -= bytes_read;
-       } else {
-         break;
-       }
-     }
-     WebPIDelete(idec);
-
-     // F) Decoded image is now in config.output (and config.output.u.RGBA).
-     // It can be saved, displayed or otherwise processed.
-
-     // G) Reclaim memory allocated in config's object. It's safe to call
-     // this function even if the memory is external and wasn't allocated
-     // by WebPDecode().
-     WebPFreeDecBuffer(&config.output);
-
--------------------------------------- END PSEUDO EXAMPLE
-
-Bugs:
-=====
-
-Please report all bugs to the issue tracker:
-    https://bugs.chromium.org/p/webp
-Patches welcome! See this page to get started:
-    http://www.webmproject.org/code/contribute/submitting-patches/
-
-Discuss:
-========
-
-Email: webp-discuss@webmproject.org
-Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/third_party/libwebp/README.md b/third_party/libwebp/README.md
new file mode 100644
index 0000000..a877320
--- /dev/null
+++ b/third_party/libwebp/README.md
@@ -0,0 +1,53 @@
+# WebP Codec
+
+```
+      __   __  ____  ____  ____
+     /  \\/  \/  _ \/  _ )/  _ \
+     \       /   __/  _  \   __/
+      \__\__/\____/\_____/__/ ____  ___
+            / _/ /    \    \ /  _ \/ _/
+           /  \_/   / /   \ \   __/  \__
+           \____/____/\_____/_____/____/v1.3.1
+```
+
+WebP codec is a library to encode and decode images in WebP format. This package
+contains the library that can be used in other programs to add WebP support, as
+well as the command line tools 'cwebp' and 'dwebp' to compress and decompress
+images respectively.
+
+See https://developers.google.com/speed/webp for details on the image format.
+
+The latest source tree is available at
+https://chromium.googlesource.com/webm/libwebp
+
+It is released under the same license as the WebM project. See
+https://www.webmproject.org/license/software/ or the "COPYING" file for details.
+An additional intellectual property rights grant can be found in the file
+PATENTS.
+
+## Building
+
+See the [building documentation](doc/building.md).
+
+## Encoding and Decoding Tools
+
+The examples/ directory contains tools to encode and decode images and
+animations, view information about WebP images, and more. See the
+[tools documentation](doc/tools.md).
+
+## APIs
+
+See the [APIs documentation](doc/api.md), and API usage examples in the
+`examples/` directory.
+
+## Bugs
+
+Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp
+
+Patches welcome! See [how to contribute](CONTRIBUTING.md).
+
+## Discuss
+
+Email: webp-discuss@webmproject.org
+
+Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/third_party/libwebp/README.mux b/third_party/libwebp/README.mux
deleted file mode 100644
index bd4f92f..0000000
--- a/third_party/libwebp/README.mux
+++ /dev/null
@@ -1,227 +0,0 @@
-          __   __  ____  ____  ____  __ __  _     __ __
-         /  \\/  \/  _ \/  _ \/  _ \/  \  \/ \___/_ / _\
-         \       /   __/  _  \   __/      /  /  (_/  /__
-          \__\__/\_____/_____/__/  \__//_/\_____/__/___/v1.0.0
-
-
-Description:
-============
-
-WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
-manipulation of an extended format WebP file, which can have features like
-color profile, metadata and animation. Reference command-line tools 'webpmux'
-and 'vwebp' as well as the WebP container specification
-'doc/webp-container-spec.txt' are also provided in this package.
-
-WebP Mux tool:
-==============
-
-The examples/ directory contains a tool (webpmux) for manipulating WebP
-files. The webpmux tool can be used to create an extended format WebP file and
-also to extract or strip relevant data from such a file.
-
-A list of options is available using the -help command line flag:
-
-> webpmux -help
-Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
-       webpmux -set SET_OPTIONS INPUT -o OUTPUT
-       webpmux -duration DURATION_OPTIONS [-duration ...]
-               INPUT -o OUTPUT
-       webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
-       webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
-               [-bgcolor BACKGROUND_COLOR] -o OUTPUT
-       webpmux -info INPUT
-       webpmux [-h|-help]
-       webpmux -version
-       webpmux argument_file_name
-
-GET_OPTIONS:
- Extract relevant data:
-   icc       get ICC profile
-   exif      get EXIF metadata
-   xmp       get XMP metadata
-   frame n   get nth frame
-
-SET_OPTIONS:
- Set color profile/metadata:
-   icc  file.icc     set ICC profile
-   exif file.exif    set EXIF metadata
-   xmp  file.xmp     set XMP metadata
-   where:    'file.icc' contains the ICC profile to be set,
-             'file.exif' contains the EXIF metadata to be set
-             'file.xmp' contains the XMP metadata to be set
-
-DURATION_OPTIONS:
- Set duration of selected frames:
-   duration            set duration for each frames
-   duration,frame      set duration of a particular frame
-   duration,start,end  set duration of frames in the
-                        interval [start,end])
-   where: 'duration' is the duration in milliseconds
-          'start' is the start frame index
-          'end' is the inclusive end frame index
-           The special 'end' value '0' means: last frame.
-
-STRIP_OPTIONS:
- Strip color profile/metadata:
-   icc       strip ICC profile
-   exif      strip EXIF metadata
-   xmp       strip XMP metadata
-
-FRAME_OPTIONS(i):
- Create animation:
-   file_i +di+[xi+yi[+mi[bi]]]
-   where:    'file_i' is the i'th animation frame (WebP format),
-             'di' is the pause duration before next frame,
-             'xi','yi' specify the image offset for this frame,
-             'mi' is the dispose method for this frame (0 or 1),
-             'bi' is the blending method for this frame (+b or -b)
-
-LOOP_COUNT:
- Number of times to repeat the animation.
- Valid range is 0 to 65535 [Default: 0 (infinite)].
-
-BACKGROUND_COLOR:
- Background color of the canvas.
-  A,R,G,B
-  where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
-            the Alpha, Red, Green and Blue component values respectively
-            [Default: 255,255,255,255]
-
-INPUT & OUTPUT are in WebP format.
-
-Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
-valid.
-
-Note: if a single file name is passed as the argument, the arguments will be
-tokenized from this file. The file name must not start with the character '-'.
-
-Visualization tool:
-===================
-
-The examples/ directory also contains a tool (vwebp) for viewing WebP files.
-It decodes the image and visualizes it using OpenGL. See the libwebp README
-for details on building and running this program.
-
-Mux API:
-========
-The Mux API contains methods for adding data to and reading data from WebP
-files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
-Other features may be added in subsequent releases.
-
-Example#1 (pseudo code): Creating a WebPMux object with image data, color
-profile and XMP metadata.
-
-  int copy_data = 0;
-  WebPMux* mux = WebPMuxNew();
-  // ... (Prepare image data).
-  WebPMuxSetImage(mux, &image, copy_data);
-  // ... (Prepare ICC profile data).
-  WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
-  // ... (Prepare XMP metadata).
-  WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
-  // Get data from mux in WebP RIFF format.
-  WebPMuxAssemble(mux, &output_data);
-  WebPMuxDelete(mux);
-  // ... (Consume output_data; e.g. write output_data.bytes to file).
-  WebPDataClear(&output_data);
-
-
-Example#2 (pseudo code): Get image and color profile data from a WebP file.
-
-  int copy_data = 0;
-  // ... (Read data from file).
-  WebPMux* mux = WebPMuxCreate(&data, copy_data);
-  WebPMuxGetFrame(mux, 1, &image);
-  // ... (Consume image; e.g. call WebPDecode() to decode the data).
-  WebPMuxGetChunk(mux, "ICCP", &icc_profile);
-  // ... (Consume icc_profile).
-  WebPMuxDelete(mux);
-  free(data);
-
-
-For a detailed Mux API reference, please refer to the header file
-(src/webp/mux.h).
-
-Demux API:
-==========
-The Demux API enables extraction of images and extended format data from
-WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
-profile and animated images. Other features may be added in subsequent
-releases.
-
-Code example: Demuxing WebP data to extract all the frames, ICC profile
-and EXIF/XMP metadata.
-
-  WebPDemuxer* demux = WebPDemux(&webp_data);
-  uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
-  uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
-  // ... (Get information about the features present in the WebP file).
-  uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
-
-  // ... (Iterate over all frames).
-  WebPIterator iter;
-  if (WebPDemuxGetFrame(demux, 1, &iter)) {
-    do {
-      // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
-      // ... and get other frame properties like width, height, offsets etc.
-      // ... see 'struct WebPIterator' below for more info).
-    } while (WebPDemuxNextFrame(&iter));
-    WebPDemuxReleaseIterator(&iter);
-  }
-
-  // ... (Extract metadata).
-  WebPChunkIterator chunk_iter;
-  if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
-  // ... (Consume the ICC profile in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
-  // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
-  // ... (Consume the XMP metadata in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  WebPDemuxDelete(demux);
-
-
-For a detailed Demux API reference, please refer to the header file
-(src/webp/demux.h).
-
-AnimEncoder API:
-================
-The AnimEncoder API can be used to create animated WebP images.
-
-Code example:
-
-  WebPAnimEncoderOptions enc_options;
-  WebPAnimEncoderOptionsInit(&enc_options);
-  // ... (Tune 'enc_options' as needed).
-  WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
-  while(<there are more frames>) {
-    WebPConfig config;
-    WebPConfigInit(&config);
-    // ... (Tune 'config' as needed).
-    WebPAnimEncoderAdd(enc, frame, duration, &config);
-  }
-  WebPAnimEncoderAssemble(enc, webp_data);
-  WebPAnimEncoderDelete(enc);
-  // ... (Write the 'webp_data' to a file, or re-mux it further).
-
-
-For a detailed AnimEncoder API reference, please refer to the header file
-(src/webp/mux.h).
-
-
-Bugs:
-=====
-
-Please report all bugs to the issue tracker:
-    https://bugs.chromium.org/p/webp
-Patches welcome! See this page to get started:
-    http://www.webmproject.org/code/contribute/submitting-patches/
-
-Discuss:
-========
-
-Email: webp-discuss@webmproject.org
-Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/third_party/libwebp/README.webp_js b/third_party/libwebp/README.webp_js
deleted file mode 100644
index 2805354..0000000
--- a/third_party/libwebp/README.webp_js
+++ /dev/null
@@ -1,76 +0,0 @@
-     __   __ ____ ____ ____     __  ____
-    /  \\/  \  _ \  _ \  _ \   (__)/  __\
-    \       /  __/ _  \  __/   _)  \_   \
-     \__\__/_____/____/_/     /____/____/
-
-Description:
-============
-
-This file describes the compilation of libwebp into a JavaScript decoder
-using Emscripten and CMake.
-
- - install the Emscripten SDK following the procedure described at:
-   https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
-   After installation, you should have some global variable positioned to the
-   location of the SDK. In particular, $EMSCRIPTEN should point to the
-   top-level directory containing Emscripten tools.
-
- - make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is
-   accessible. This is the toolchain file used by CMake to invoke Emscripten.
-
- - configure the project 'WEBP_JS' with CMake using:
-
- cd webp_js && \
- cmake -DWEBP_BUILD_WEBP_JS=ON \
-       -DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=1 \
-       -DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
-       ../
-
- - compile webp.js using 'make'.
-
- - that's it! Upon completion, you should have the webp.js and
-   webp.js.mem files generated.
-
-The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
-bitstream into a canvas. See webp_js/index.html for a simple usage sample
-(see below for instructions).
-
-Demo HTML page:
-===============
-
-   The HTML page webp_js/index.html requires an HTTP server to serve the WebP
-   image example. It's easy to just use Python for that.
-
-cd webp_js && python -m SimpleHTTPServer 8080
-
-and then navigate to http://localhost:8080 in your favorite browser.
-
-
-Web-Assembly (WASM) version:
-============================
-
-  CMakeLists.txt is configured to build the WASM version when using
-  the option WEBP_BUILD_WEBP_JS=ON. The compilation step will assemble
-  the files 'webp_wasm.js', 'webp_wasm.wasm' in the webp_js/ directory.
-  See webp_js/index_wasm.html for a simple demo page using the WASM version
-  of the library.
-
-  You will need a fairly recent version of Emscripten (at least 1.37.8) and of
-  your WASM-enabled browser to run this version. Consider it very experimental!
-
-Caveat:
-=======
-
-  - First decoding using the library is usually slower, due to just-in-time
-    compilation.
-
-  - Some versions of llvm produce the following compile error when SSE2 is
-    enabled.
-
-"Unsupported:   %516 = bitcast <8 x i16> %481 to i128
- LLVM ERROR: BitCast Instruction not yet supported for integer types larger than 64 bits"
-
-    The corresponding Emscripten bug is at:
-    https://github.com/kripken/emscripten/issues/3788
-
-    Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
diff --git a/third_party/libwebp/build.gradle b/third_party/libwebp/build.gradle
index 88ad129..c25314c 100644
--- a/third_party/libwebp/build.gradle
+++ b/third_party/libwebp/build.gradle
@@ -105,6 +105,14 @@
       sources {
         c {
           source {
+            srcDir "sharpyuv"
+            include "sharpyuv.c"
+            include "sharpyuv_cpu.c"
+            include "sharpyuv_csp.c"
+            include "sharpyuv_dsp.c"
+            include "sharpyuv_gamma.c"
+            include "sharpyuv_neon.c"
+            include "sharpyuv_sse2.c"
             srcDir "src/dec"
             include "alpha_dec.c"
             include "buffer_dec.c"
@@ -141,6 +149,7 @@
             include "lossless_msa.c"
             include "lossless_neon.$NEON"
             include "lossless_sse2.c"
+            include "lossless_sse41.c"
             include "rescaler.c"
             include "rescaler_mips32.c"
             include "rescaler_mips_dsp_r2.c"
@@ -173,9 +182,9 @@
             include "cost.c"
             include "cost_mips32.c"
             include "cost_mips_dsp_r2.c"
+            include "cost_neon.$NEON"
             include "cost_sse2.c"
             include "enc.c"
-            include "enc_avx2.c"
             include "enc_mips32.c"
             include "enc_mips_dsp_r2.c"
             include "enc_msa.c"
@@ -432,8 +441,3 @@
     }
   }
 }
-
-// Task to generate the wrapper.
-task wrapper(type: Wrapper) {
-  gradleVersion = '2.13'
-}
diff --git a/third_party/libwebp/cmake/WebPConfig.cmake.in b/third_party/libwebp/cmake/WebPConfig.cmake.in
index ef3df2f..8c883fe 100644
--- a/third_party/libwebp/cmake/WebPConfig.cmake.in
+++ b/third_party/libwebp/cmake/WebPConfig.cmake.in
@@ -1,6 +1,18 @@
+set(WebP_VERSION @PROJECT_VERSION@)
+set(WEBP_VERSION ${WebP_VERSION})
+
 @PACKAGE_INIT@
 
-set(WebP_INCLUDE_DIRS "webp")
+if(@WEBP_USE_THREAD@)
+  include(CMakeFindDependencyMacro)
+  find_dependency(Threads REQUIRED)
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+
+set_and_check(WebP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
 set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
 set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
 set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
+
+check_required_components(WebP)
diff --git a/third_party/libwebp/cmake/config.h.in b/third_party/libwebp/cmake/config.h.in
index ec84acd..fe1c53a 100644
--- a/third_party/libwebp/cmake/config.h.in
+++ b/third_party/libwebp/cmake/config.h.in
@@ -16,48 +16,18 @@
 /* Define to 1 if you have the <cpu-features.h> header file. */
 #cmakedefine HAVE_CPU_FEATURES_H 1
 
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H 1
-
 /* Define to 1 if you have the <GLUT/glut.h> header file. */
 #cmakedefine HAVE_GLUT_GLUT_H 1
 
 /* Define to 1 if you have the <GL/glut.h> header file. */
 #cmakedefine HAVE_GL_GLUT_H 1
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H 1
-
 /* Define to 1 if you have the <OpenGL/glut.h> header file. */
 #cmakedefine HAVE_OPENGL_GLUT_H 1
 
-/* Have PTHREAD_PRIO_INHERIT. */
-#cmakedefine HAVE_PTHREAD_PRIO_INHERIT @HAVE_PTHREAD_PRIO_INHERIT@
-
 /* Define to 1 if you have the <shlwapi.h> header file. */
 #cmakedefine HAVE_SHLWAPI_H 1
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H 1
-
 /* Define to 1 if you have the <unistd.h> header file. */
 #cmakedefine HAVE_UNISTD_H 1
 
@@ -93,19 +63,9 @@
 /* Define to the version of this package. */
 #cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
 
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-#cmakedefine PTHREAD_CREATE_JOINABLE 1
-
-/* Define to 1 if you have the ANSI C header files. */
-#cmakedefine STDC_HEADERS 1
-
 /* Version number of package */
 #cmakedefine VERSION "@VERSION@"
 
-/* Set to 1 if AVX2 is supported */
-#cmakedefine WEBP_HAVE_AVX2 1
-
 /* Set to 1 if GIF library is installed */
 #cmakedefine WEBP_HAVE_GIF 1
 
diff --git a/third_party/libwebp/cmake/cpu.cmake b/third_party/libwebp/cmake/cpu.cmake
index 5aa1bfd..7513ca8 100644
--- a/third_party/libwebp/cmake/cpu.cmake
+++ b/third_party/libwebp/cmake/cpu.cmake
@@ -1,4 +1,12 @@
-## Check for SIMD extensions.
+#  Copyright (c) 2021 Google LLC.
+#
+#  Use of this source code is governed by a BSD-style license
+#  that can be found in the LICENSE file in the root of the source
+#  tree. An additional intellectual property rights grant can be found
+#  in the file PATENTS.  All contributing project authors may
+#  be found in the AUTHORS file in the root of the source tree.
+
+# Check for SIMD extensions.
 include(CMakePushCheckState)
 
 function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
@@ -10,7 +18,8 @@
   unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
   cmake_push_check_state()
   set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
-  check_c_source_compiles("
+  check_c_source_compiles(
+    "
       #include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
       int main(void) {
         #if !defined(WEBP_USE_${WEBP_SIMD_FLAG})
@@ -18,8 +27,8 @@
         #endif
         return 0;
       }
-    " WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
-  )
+    "
+    WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
   cmake_pop_check_state()
   if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
     set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
@@ -29,28 +38,34 @@
 endfunction()
 
 # those are included in the names of WEBP_USE_* in c++ code.
-set(WEBP_SIMD_FLAGS "SSE2;SSE41;AVX2;MIPS32;MIPS_DSP_R2;NEON;MSA")
-set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
-if(MSVC)
-  # MSVC does not have a SSE4 flag but AVX2 support implies
-  # SSE4 support.
-  set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2;;;;")
+set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
+set(WEBP_SIMD_FILE_EXTENSIONS
+    "_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
+if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
+  # With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
+  # or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
+  # flag, but an AVX one. Using that with SSE4 code risks generating illegal
+  # instructions when used on machines with SSE4 only. The flags are left for
+  # older (untested) versions to avoid any potential compatibility issues.
+  if(MSVC_VERSION GREATER_EQUAL 1800 AND NOT CMAKE_C_FLAGS MATCHES "/arch:")
+    set(SIMD_ENABLE_FLAGS)
+  else()
+    set(SIMD_ENABLE_FLAGS "/arch:AVX;/arch:SSE2;;;;")
+  endif()
   set(SIMD_DISABLE_FLAGS)
 else()
-  set(SIMD_ENABLE_FLAGS "-msse2;-msse4.1;-mavx2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
-  set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2;;-mno-dspr2;;-mno-msa")
+  set(SIMD_ENABLE_FLAGS "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
+  set(SIMD_DISABLE_FLAGS "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
 endif()
 
-set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
 set(WEBP_SIMD_FILES_TO_INCLUDE)
 set(WEBP_SIMD_FLAGS_TO_INCLUDE)
 
 if(${ANDROID})
   if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
-    # This is because Android studio uses the configuration
-    # "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
-    # that does not trigger neon optimizations but should
-    # (as this configuration does not exist anymore).
+    # This is because Android studio uses the configuration "-march=armv7-a
+    # -mfloat-abi=softfp -mfpu=vfpv3-d16" that does not trigger neon
+    # optimizations but should (as this configuration does not exist anymore).
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
   endif()
 endif()
@@ -59,6 +74,12 @@
 math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
 
 foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
+  # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the source
+  # will fail to compile.
+  if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
+    break()
+  endif()
+
   list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG)
 
   # First try with no extra flag added as the compiler might have default flags
@@ -69,16 +90,24 @@
   webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
   if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
     list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
+    if(EMSCRIPTEN)
+      set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
+    endif()
     set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
     webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
   else()
-    set(SIMD_COMPILE_FLAG " ")
+    if(MSVC AND SIMD_ENABLE_FLAGS)
+      # The detection for SSE2/SSE4 support under MSVC is based on the compiler
+      # version so e.g., clang-cl will require flags to enable the assembly.
+      list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
+    else()
+      set(SIMD_COMPILE_FLAG " ")
+    endif()
   endif()
   # Check which files we should include or not.
   list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
   file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
-    "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}"
-  )
+       "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
   if(WEBP_HAVE_${WEBP_SIMD_FLAG})
     # Memorize the file and flags.
     foreach(FILE ${SIMD_FILES})
@@ -95,6 +124,12 @@
       list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
       include(CheckCCompilerFlag)
       if(SIMD_COMPILE_FLAG)
+        # Between 3.17.0 and 3.18.2 check_cxx_compiler_flag() sets a normal
+        # variable at parent scope while check_cxx_source_compiles() continues
+        # to set an internal cache variable, so we unset both to avoid the
+        # failure / success state persisting between checks. See
+        # https://gitlab.kitware.com/cmake/cmake/-/issues/21207.
+        unset(HAS_COMPILE_FLAG)
         unset(HAS_COMPILE_FLAG CACHE)
         check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG)
         if(HAS_COMPILE_FLAG)
@@ -106,12 +141,11 @@
             set(COMMON_PATTERNS)
           endif()
           set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
-          check_c_source_compiles("int main(void) {return 0;}"
-            FLAG_${SIMD_COMPILE_FLAG}
-            FAIL_REGEX "warning: argument unused during compilation:"
-            ${COMMON_PATTERNS}
-          )
+          check_c_source_compiles(
+            "int main(void) {return 0;}" FLAG_${SIMD_COMPILE_FLAG} FAIL_REGEX
+            "warning: argument unused during compilation:" ${COMMON_PATTERNS})
           if(NOT FLAG_${SIMD_COMPILE_FLAG})
+            unset(HAS_COMPILE_FLAG)
             unset(HAS_COMPILE_FLAG CACHE)
           endif()
         endif()
diff --git a/third_party/libwebp/cmake/deps.cmake b/third_party/libwebp/cmake/deps.cmake
index 3d5d10a..0760ba9 100644
--- a/third_party/libwebp/cmake/deps.cmake
+++ b/third_party/libwebp/cmake/deps.cmake
@@ -1,130 +1,137 @@
+#  Copyright (c) 2021 Google LLC.
+#
+#  Use of this source code is governed by a BSD-style license
+#  that can be found in the LICENSE file in the root of the source
+#  tree. An additional intellectual property rights grant can be found
+#  in the file PATENTS.  All contributing project authors may
+#  be found in the AUTHORS file in the root of the source tree.
+
 # Generate the config.h to compile with specific intrinsics / libs.
 
-## Check for compiler options.
+# Check for compiler options.
 include(CheckCSourceCompiles)
-check_c_source_compiles("
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap16(0);
       return 0;
     }
   "
-  HAVE_BUILTIN_BSWAP16
-)
-check_c_source_compiles("
+  HAVE_BUILTIN_BSWAP16)
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap32(0);
       return 0;
     }
   "
-  HAVE_BUILTIN_BSWAP32
-)
-check_c_source_compiles("
+  HAVE_BUILTIN_BSWAP32)
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap64(0);
       return 0;
     }
   "
-  HAVE_BUILTIN_BSWAP64
-)
+  HAVE_BUILTIN_BSWAP64)
 
-## Check for libraries.
-find_package(Threads)
-if(Threads_FOUND)
-  if(CMAKE_USE_PTHREADS_INIT)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
+# Check for libraries.
+if(WEBP_USE_THREAD)
+  find_package(Threads)
+  if(Threads_FOUND)
+    # work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
+    if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
+      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
+    endif()
+    list(APPEND WEBP_DEP_LIBRARIES Threads::Threads)
   endif()
-  foreach(PTHREAD_TEST HAVE_PTHREAD_PRIO_INHERIT PTHREAD_CREATE_UNDETACHED)
-    check_c_source_compiles("
-        #include <pthread.h>
-        int main (void) {
-          int attr = ${PTHREAD_TEST};
-          return attr;
-        }
-      " ${PTHREAD_TEST}
-    )
-  endforeach()
-  list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+  set(WEBP_USE_THREAD ${Threads_FOUND})
 endif()
-set(WEBP_USE_THREAD ${Threads_FOUND})
 
 # TODO: this seems unused, check with autotools.
 set(LT_OBJDIR ".libs/")
 
 # Only useful for vwebp, so useless for now.
-# find_package(OpenGL)
-# set(WEBP_HAVE_GL ${OPENGL_FOUND})
-# set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS})
-# set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} ${OPENGL_LIBRARIES})
+find_package(OpenGL)
+set(WEBP_HAVE_GL ${OPENGL_FOUND})
 
-# Find the standard C math library.
-find_library(MATH_LIBRARY NAMES m)
-if(MATH_LIBRARY)
-  list(APPEND WEBP_DEP_LIBRARIES ${MATH_LIBRARY})
+# Check if we need to link to the C math library. We do not look for it as it is
+# not found when cross-compiling, while it is here.
+check_c_source_compiles(
+  "
+    #include <math.h>
+    int main(int argc, char** argv) {
+      return (int)pow(argc, 2.5);
+    }
+  "
+  HAVE_MATH_LIBRARY)
+if(NOT HAVE_MATH_LIBRARY)
+  message(STATUS "Adding -lm flag.")
+  list(APPEND SHARPYUV_DEP_LIBRARIES m)
+  list(APPEND WEBP_DEP_LIBRARIES m)
 endif()
 
 # Find the standard image libraries.
 set(WEBP_DEP_IMG_LIBRARIES)
 set(WEBP_DEP_IMG_INCLUDE_DIRS)
-foreach(I_LIB PNG JPEG TIFF)
-  find_package(${I_LIB})
-  set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
-  if(${I_LIB}_FOUND)
-    list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
-    list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS
-         ${${I_LIB}_INCLUDE_DIR} ${${I_LIB}_INCLUDE_DIRS})
+if(WEBP_FIND_IMG_LIBS)
+  foreach(I_LIB PNG JPEG TIFF)
+    # Disable tiff when compiling in static mode as it is failing on Ubuntu.
+    if(WEBP_LINK_STATIC AND ${I_LIB} STREQUAL "TIFF")
+      message(STATUS "TIFF is disabled when statically linking.")
+      continue()
+    endif()
+    find_package(${I_LIB})
+    set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
+    if(${I_LIB}_FOUND)
+      list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
+      list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
+           ${${I_LIB}_INCLUDE_DIRS})
+    endif()
+  endforeach()
+  if(WEBP_DEP_IMG_INCLUDE_DIRS)
+    list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
   endif()
-endforeach()
-if(WEBP_DEP_IMG_INCLUDE_DIRS)
-  list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
-endif()
 
-# GIF detection, gifdec isn't part of the imageio lib.
-include(CMakePushCheckState)
-set(WEBP_DEP_GIF_LIBRARIES)
-set(WEBP_DEP_GIF_INCLUDE_DIRS)
-find_package(GIF)
-set(WEBP_HAVE_GIF ${GIF_FOUND})
-if(GIF_FOUND)
-  # GIF find_package only locates the header and library, it doesn't fail
-  # compile tests when detecting the version, but falls back to 3 (as of at
-  # least cmake 3.7.2). Make sure the library links to avoid incorrect
-  # detection when cross compiling.
-  cmake_push_check_state()
-  set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
-  set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
-  check_c_source_compiles("
+  # GIF detection, gifdec isn't part of the imageio lib.
+  include(CMakePushCheckState)
+  set(WEBP_DEP_GIF_LIBRARIES)
+  set(WEBP_DEP_GIF_INCLUDE_DIRS)
+  find_package(GIF)
+  set(WEBP_HAVE_GIF ${GIF_FOUND})
+  if(GIF_FOUND)
+    # GIF find_package only locates the header and library, it doesn't fail
+    # compile tests when detecting the version, but falls back to 3 (as of at
+    # least cmake 3.7.2). Make sure the library links to avoid incorrect
+    # detection when cross compiling.
+    cmake_push_check_state()
+    set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
+    set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
+    check_c_source_compiles(
+      "
       #include <gif_lib.h>
       int main(void) {
         (void)DGifOpenFileHandle;
         return 0;
       }
-      " GIF_COMPILES
-  )
-  cmake_pop_check_state()
-  if(GIF_COMPILES)
-    list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
-    list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
-  else()
-    unset(GIF_FOUND)
+      "
+      GIF_COMPILES)
+    cmake_pop_check_state()
+    if(GIF_COMPILES)
+      list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
+      list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
+    else()
+      unset(GIF_FOUND)
+    endif()
   endif()
 endif()
 
-## Check for specific headers.
+# Check for specific headers.
 include(CheckIncludeFiles)
-check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
-check_include_files(dlfcn.h HAVE_DLFCN_H)
 check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
 check_include_files(GL/glut.h HAVE_GL_GLUT_H)
-check_include_files(inttypes.h HAVE_INTTYPES_H)
-check_include_files(memory.h HAVE_MEMORY_H)
 check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
 check_include_files(shlwapi.h HAVE_SHLWAPI_H)
-check_include_files(stdint.h HAVE_STDINT_H)
-check_include_files(stdlib.h HAVE_STDLIB_H)
-check_include_files(strings.h HAVE_STRINGS_H)
-check_include_files(string.h HAVE_STRING_H)
-check_include_files(sys/stat.h HAVE_SYS_STAT_H)
-check_include_files(sys/types.h HAVE_SYS_TYPES_H)
 check_include_files(unistd.h HAVE_UNISTD_H)
 check_include_files(wincodec.h HAVE_WINCODEC_H)
 check_include_files(windows.h HAVE_WINDOWS_H)
@@ -134,18 +141,17 @@
   list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs)
 endif()
 
-## Check for SIMD extensions.
+# Check for SIMD extensions.
 include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
 
-## Define extra info.
+# Define extra info.
 set(PACKAGE ${PROJECT_NAME})
 set(PACKAGE_NAME ${PROJECT_NAME})
 
 # Read from configure.ac.
 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC)
-string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]"
-  CONFIGURE_AC_PACKAGE_INFO ${CONFIGURE_AC}
-)
+string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]" CONFIGURE_AC_PACKAGE_INFO
+             ${CONFIGURE_AC})
 function(strip_bracket VAR)
   string(LENGTH ${${VAR}} TMP_LEN)
   math(EXPR TMP_LEN ${TMP_LEN}-2)
diff --git a/third_party/libwebp/configure.ac b/third_party/libwebp/configure.ac
index 896e5ff..a999e0c 100644
--- a/third_party/libwebp/configure.ac
+++ b/third_party/libwebp/configure.ac
@@ -1,6 +1,6 @@
-AC_INIT([libwebp], [1.0.0],
+AC_INIT([libwebp], [1.3.1],
         [https://bugs.chromium.org/p/webp],,
-        [http://developers.google.com/speed/webp])
+        [https://developers.google.com/speed/webp])
 AC_CANONICAL_HOST
 AC_PREREQ([2.60])
 AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
@@ -9,7 +9,8 @@
 dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL).
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 
-AC_PROG_LIBTOOL
+dnl === AC_PROG_LIBTOOL is deprecated.
+m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL])
 AC_PROG_SED
 AM_PROG_CC_C_O
 
@@ -27,11 +28,46 @@
               AS_HELP_STRING([--enable-everything],
                              [Enable all optional targets. These can still be
                               disabled with --disable-target]),
-              [SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
+              [SET_IF_UNSET([enable_libsharpyuv], [$enableval])
+               SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
                SET_IF_UNSET([enable_libwebpdemux], [$enableval])
                SET_IF_UNSET([enable_libwebpextras], [$enableval])
                SET_IF_UNSET([enable_libwebpmux], [$enableval])])
 
+dnl === Check whether libwebpmux should be built
+AC_MSG_CHECKING(whether libwebpmux is to be built)
+AC_ARG_ENABLE([libwebpmux],
+              AS_HELP_STRING([--disable-libwebpmux],
+                             [Disable libwebpmux @<:@default=no@:>@]),
+              [], [enable_libwebpmux=yes])
+AC_MSG_RESULT(${enable_libwebpmux-no})
+AM_CONDITIONAL([BUILD_MUX], [test "$enable_libwebpmux" = "yes"])
+
+dnl === Check whether libwebpdemux should be built
+AC_MSG_CHECKING(whether libwebpdemux is to be built)
+AC_ARG_ENABLE([libwebpdemux],
+              AS_HELP_STRING([--disable-libwebpdemux],
+                             [Disable libwebpdemux @<:@default=no@:>@]),
+              [], [enable_libwebpdemux=yes])
+AC_MSG_RESULT(${enable_libwebpdemux-no})
+AM_CONDITIONAL([BUILD_DEMUX], [test "$enable_libwebpdemux" = "yes"])
+
+dnl === Check whether decoder library should be built.
+AC_MSG_CHECKING(whether decoder library is to be built)
+AC_ARG_ENABLE([libwebpdecoder],
+              AS_HELP_STRING([--enable-libwebpdecoder],
+                             [Build libwebpdecoder @<:@default=no@:>@]))
+AC_MSG_RESULT(${enable_libwebpdecoder-no})
+AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
+
+dnl === Check whether libwebpextras should be built
+AC_MSG_CHECKING(whether libwebpextras is to be built)
+AC_ARG_ENABLE([libwebpextras],
+              AS_HELP_STRING([--enable-libwebpextras],
+                             [Build libwebpextras @<:@default=no@:>@]))
+AC_MSG_RESULT(${enable_libwebpextras-no})
+AM_CONDITIONAL([BUILD_EXTRAS], [test "$enable_libwebpextras" = "yes"])
+
 dnl === If --enable-asserts is not defined, define NDEBUG
 
 AC_MSG_CHECKING(whether asserts are enabled)
@@ -80,6 +116,7 @@
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef])
+TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code-aggressive])
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
 TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
@@ -122,31 +159,6 @@
 AC_SUBST([AM_CFLAGS])
 
 dnl === Check for machine specific flags
-AC_ARG_ENABLE([avx2],
-              AS_HELP_STRING([--disable-avx2],
-                             [Disable detection of AVX2 support
-                              @<:@default=auto@:>@]))
-
-AS_IF([test "x$enable_avx2" != "xno" -a "x$enable_sse4_1" != "xno" \
-         -a "x$enable_sse2" != "xno"], [
-  AVX2_CFLAGS="$INTRINSICS_CFLAGS $AVX2_FLAGS"
-  TEST_AND_ADD_CFLAGS([AVX2_FLAGS], [-mavx2])
-  AS_IF([test -n "$AVX2_FLAGS"], [
-    SAVED_CFLAGS=$CFLAGS
-    CFLAGS="$CFLAGS $AVX2_FLAGS"
-    AC_CHECK_HEADER([immintrin.h],
-                    [AC_DEFINE(WEBP_HAVE_AVX2, [1],
-                     [Set to 1 if AVX2 is supported])],
-                    [AVX2_FLAGS=""],
-                    dnl it's illegal to directly include avx2intrin.h, but it's
-                    dnl included conditionally in immintrin.h, tricky!
-                    [#ifndef __AVX2__
-                     #error avx2 is not enabled
-                     #endif
-                    ])
-    CFLAGS=$SAVED_CFLAGS])
-  AC_SUBST([AVX2_FLAGS])])
-
 AC_ARG_ENABLE([sse4.1],
               AS_HELP_STRING([--disable-sse4.1],
                              [Disable detection of SSE4.1 support
@@ -249,6 +261,9 @@
         *android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
       esac
       ;;
+    aarch64*|arm64*)
+      AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported])
+      ;;
   esac
   AC_SUBST([NEON_FLAGS])])
 
@@ -433,6 +448,10 @@
 
   if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
     build_vwebp=yes
+  else
+    AC_MSG_NOTICE(
+      m4_normalize([Not building vwebp.
+                    OpenGL libraries and --enable-libwebpdemux are required.]))
   fi
 ])
 AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
@@ -492,7 +511,7 @@
   if test x"$sdl_support" = "xyes"; then
     build_vwebp_sdl=yes
   else
-    AC_MSG_WARN(Optional SDL library not found)
+    AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.])
   fi
 ])
 
@@ -616,11 +635,17 @@
   if test "$gif_support" = "yes" -a \
           "$enable_libwebpdemux" = "yes"; then
     build_anim_diff=yes
+  else
+    AC_MSG_NOTICE(
+      [Not building anim_diff. libgif and --enable-libwebpdemux are required.])
   fi
 
   if test "$gif_support" = "yes" -a \
           "$enable_libwebpmux" = "yes"; then
     build_gif2webp=yes
+  else
+    AC_MSG_NOTICE(
+      [Not building gif2webp. libgif and --enable-libwebpmux are required.])
   fi
 ])
 AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"])
@@ -628,11 +653,17 @@
 
 if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
   build_img2webp=yes
+else
+  AC_MSG_NOTICE(
+    m4_normalize([Not building img2webp.
+                  --enable-libwebpdemux & --enable-libwebpmux are required.]))
 fi
 AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
 
 if test "$enable_libwebpmux" = "yes"; then
   build_webpinfo=yes
+else
+  AC_MSG_NOTICE([Not building webpinfo. --enable-libwebpdemux is required.])
 fi
 AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
 
@@ -716,45 +747,15 @@
   AC_MSG_RESULT([no])
 fi
 
-dnl === Check whether libwebpmux should be built
-AC_MSG_CHECKING(whether libwebpmux is to be built)
-AC_ARG_ENABLE([libwebpmux],
-              AS_HELP_STRING([--enable-libwebpmux],
-                             [Build libwebpmux @<:@default=no@:>@]))
-AC_MSG_RESULT(${enable_libwebpmux-no})
-AM_CONDITIONAL([WANT_MUX], [test "$enable_libwebpmux" = "yes"])
-
-dnl === Check whether libwebpdemux should be built
-AC_MSG_CHECKING(whether libwebpdemux is to be built)
-AC_ARG_ENABLE([libwebpdemux],
-              AS_HELP_STRING([--disable-libwebpdemux],
-                             [Disable libwebpdemux @<:@default=no@:>@]),
-              [], [enable_libwebpdemux=yes])
-AC_MSG_RESULT(${enable_libwebpdemux-no})
-AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
-
-dnl === Check whether decoder library should be built.
-AC_MSG_CHECKING(whether decoder library is to be built)
-AC_ARG_ENABLE([libwebpdecoder],
-              AS_HELP_STRING([--enable-libwebpdecoder],
-                             [Build libwebpdecoder @<:@default=no@:>@]))
-AC_MSG_RESULT(${enable_libwebpdecoder-no})
-AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
-
-dnl === Check whether libwebpextras should be built
-AC_MSG_CHECKING(whether libwebpextras is to be built)
-AC_ARG_ENABLE([libwebpextras],
-              AS_HELP_STRING([--enable-libwebpextras],
-                             [Build libwebpextras @<:@default=no@:>@]))
-AC_MSG_RESULT(${enable_libwebpextras-no})
-AM_CONDITIONAL([WANT_EXTRAS], [test "$enable_libwebpextras" = "yes"])
-
 dnl =========================
 
+dnl Add an empty webp_libname_prefix variable for use in *.pc.in.
+AC_SUBST([webp_libname_prefix])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([src/webp/config.h])
 AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
                  examples/Makefile extras/Makefile imageio/Makefile \
+                 sharpyuv/Makefile sharpyuv/libsharpyuv.pc \
                  src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
                  src/demux/Makefile src/mux/Makefile \
                  src/utils/Makefile \
diff --git a/third_party/libwebp/doc/README b/third_party/libwebp/doc/README
deleted file mode 100644
index 7f23e0c..0000000
--- a/third_party/libwebp/doc/README
+++ /dev/null
@@ -1,29 +0,0 @@
-
-Generate libwebp Container Spec Docs from Text Source
-=====================================================
-
-HTML generation requires kramdown [1], easily installed as a
-rubygem [2].  Rubygems installation should satisfy dependencies
-automatically.
-
-[1]: http://kramdown.rubyforge.org/
-[2]: http://rubygems.org/
-
-HTML generation can then be done from the project root:
-
-$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
-  doc/output/webp-container-spec.html
-
-kramdown can optionally syntax highlight code blocks, using CodeRay [3],
-a dependency of kramdown that rubygems will install automatically.  The
-following will apply inline CSS styling; an external stylesheet is not
-needed.
-
-$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
-  doc/template.html --coderay-css style --coderay-line-numbers ' ' \
-  --coderay-default-lang c > \
-  doc/output/webp-lossless-bitstream-spec.html
-
-Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
-
-[3]: http://coderay.rubychan.de/
diff --git a/third_party/libwebp/doc/api.md b/third_party/libwebp/doc/api.md
new file mode 100644
index 0000000..c613ed3
--- /dev/null
+++ b/third_party/libwebp/doc/api.md
@@ -0,0 +1,385 @@
+# WebP APIs
+
+## Encoding API
+
+The main encoding functions are available in the header src/webp/encode.h
+
+The ready-to-use ones are:
+
+```c
+size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+```
+
+They will convert raw RGB samples to a WebP data. The only control supplied is
+the quality factor.
+
+There are some variants for using the lossless format:
+
+```c
+size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
+                              int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
+                              int stride, uint8_t** output);
+```
+
+Of course in this case, no quality factor is needed since the compression occurs
+without loss of the input values, at the expense of larger output sizes.
+
+### Advanced encoding API
+
+A more advanced API is based on the WebPConfig and WebPPicture structures.
+
+WebPConfig contains the encoding settings and is not tied to a particular
+picture. WebPPicture contains input data, on which some WebPConfig will be used
+for compression. The encoding flow looks like:
+
+```c
+#include <webp/encode.h>
+
+// Setup a config, starting form a preset and tuning some additional
+// parameters
+WebPConfig config;
+if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
+  return 0;   // version error
+}
+// ... additional tuning
+config.sns_strength = 90;
+config.filter_sharpness = 6;
+config_error = WebPValidateConfig(&config);  // not mandatory, but useful
+
+// Setup the input data
+WebPPicture pic;
+if (!WebPPictureInit(&pic)) {
+  return 0;  // version error
+}
+pic.width = width;
+pic.height = height;
+// allocated picture of dimension width x height
+if (!WebPPictureAlloc(&pic)) {
+  return 0;   // memory error
+}
+// at this point, 'pic' has been initialized as a container,
+// and can receive the Y/U/V samples.
+// Alternatively, one could use ready-made import functions like
+// WebPPictureImportRGB(), which will take care of memory allocation.
+// In any case, past this point, one will have to call
+// WebPPictureFree(&pic) to reclaim memory.
+
+// Set up a byte-output write method. WebPMemoryWriter, for instance.
+WebPMemoryWriter wrt;
+WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
+
+pic.writer = MyFileWriter;
+pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
+
+// Compress!
+int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
+WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
+
+// output data should have been handled by the writer at that point.
+// -> compressed data is the memory buffer described by wrt.mem / wrt.size
+
+// deallocate the memory used by compressed data
+WebPMemoryWriterClear(&wrt);
+```
+
+## Decoding API
+
+This is mainly just one function to call:
+
+```c
+#include "webp/decode.h"
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+                       int* width, int* height);
+```
+
+Please have a look at the file src/webp/decode.h for the details. There are
+variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw
+Y'CbCr samples. One can also decode the image directly into a pre-allocated
+buffer.
+
+To detect a WebP file and gather the picture's dimensions, the function:
+
+```c
+int WebPGetInfo(const uint8_t* data, size_t data_size,
+                int* width, int* height);
+```
+
+is supplied. No decoding is involved when using it.
+
+### Incremental decoding API
+
+In the case when data is being progressively transmitted, pictures can still be
+incrementally decoded using a slightly more complicated API. Decoder state is
+stored into an instance of the WebPIDecoder object. This object can be created
+with the purpose of decoding either RGB or Y'CbCr samples. For instance:
+
+```c
+WebPDecBuffer buffer;
+WebPInitDecBuffer(&buffer);
+buffer.colorspace = MODE_BGR;
+...
+WebPIDecoder* idec = WebPINewDecoder(&buffer);
+```
+
+As data is made progressively available, this incremental-decoder object can be
+used to decode the picture further. There are two (mutually exclusive) ways to
+pass freshly arrived data:
+
+either by appending the fresh bytes:
+
+```c
+WebPIAppend(idec, fresh_data, size_of_fresh_data);
+```
+
+or by just mentioning the new size of the transmitted data:
+
+```c
+WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
+```
+
+Note that 'buffer' can be modified between each call to WebPIUpdate, in
+particular when the buffer is resized to accommodate larger data.
+
+These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
+decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
+status is an error condition.
+
+The 'idec' object must always be released (even upon an error condition) by
+calling: WebPDelete(idec).
+
+To retrieve partially decoded picture samples, one must use the corresponding
+method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable
+pixel row.
+
+Lastly, note that decoding can also be performed into a pre-allocated pixel
+buffer. This buffer must be passed when creating a WebPIDecoder, calling
+WebPINewRGB() or WebPINewYUVA().
+
+Please have a look at the src/webp/decode.h header for further details.
+
+### Advanced Decoding API
+
+WebP decoding supports an advanced API which provides on-the-fly cropping and
+rescaling, something of great usefulness on memory-constrained environments like
+mobile phones. Basically, the memory usage will scale with the output's size,
+not the input's, when one only needs a quick preview or a zoomed in portion of
+an otherwise too-large picture. Some CPU can be saved too, incidentally.
+
+```c
+// A) Init a configuration object
+WebPDecoderConfig config;
+CHECK(WebPInitDecoderConfig(&config));
+
+// B) optional: retrieve the bitstream's features.
+CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+// C) Adjust 'config' options, if needed
+config.options.no_fancy_upsampling = 1;
+config.options.use_scaling = 1;
+config.options.scaled_width = scaledWidth();
+config.options.scaled_height = scaledHeight();
+// etc.
+
+// D) Specify 'config' output options for specifying output colorspace.
+// Optionally the external image decode buffer can also be specified.
+config.output.colorspace = MODE_BGRA;
+// Optionally, the config.output can be pointed to an external buffer as
+// well for decoding the image. This externally supplied memory buffer
+// should be big enough to store the decoded picture.
+config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
+config.output.u.RGBA.stride = scanline_stride;
+config.output.u.RGBA.size = total_size_of_the_memory_buffer;
+config.output.is_external_memory = 1;
+
+// E) Decode the WebP image. There are two variants w.r.t decoding image.
+// The first one (E.1) decodes the full image and the second one (E.2) is
+// used to incrementally decode the image using small input buffers.
+// Any one of these steps can be used to decode the WebP image.
+
+// E.1) Decode full image.
+CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+// E.2) Decode image incrementally.
+WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
+CHECK(idec != NULL);
+while (bytes_remaining > 0) {
+  VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
+  if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
+    bytes_remaining -= bytes_read;
+  } else {
+    break;
+  }
+}
+WebPIDelete(idec);
+
+// F) Decoded image is now in config.output (and config.output.u.RGBA).
+// It can be saved, displayed or otherwise processed.
+
+// G) Reclaim memory allocated in config's object. It's safe to call
+// this function even if the memory is external and wasn't allocated
+// by WebPDecode().
+WebPFreeDecBuffer(&config.output);
+```
+
+## WebP Mux
+
+WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
+manipulation of an extended format WebP file, which can have features like color
+profile, metadata and animation. Reference command-line tools `webpmux` and
+`vwebp` as well as the WebP container specification
+'doc/webp-container-spec.txt' are also provided in this package, see the
+[tools documentation](tools.md).
+
+### Mux API
+
+The Mux API contains methods for adding data to and reading data from WebP
+files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
+Other features may be added in subsequent releases.
+
+Example#1 (pseudo code): Creating a WebPMux object with image data, color
+profile and XMP metadata.
+
+```c
+int copy_data = 0;
+WebPMux* mux = WebPMuxNew();
+// ... (Prepare image data).
+WebPMuxSetImage(mux, &image, copy_data);
+// ... (Prepare ICC profile data).
+WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+// ... (Prepare XMP metadata).
+WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+// Get data from mux in WebP RIFF format.
+WebPMuxAssemble(mux, &output_data);
+WebPMuxDelete(mux);
+// ... (Consume output_data; e.g. write output_data.bytes to file).
+WebPDataClear(&output_data);
+```
+
+Example#2 (pseudo code): Get image and color profile data from a WebP file.
+
+```c
+int copy_data = 0;
+// ... (Read data from file).
+WebPMux* mux = WebPMuxCreate(&data, copy_data);
+WebPMuxGetFrame(mux, 1, &image);
+// ... (Consume image; e.g. call WebPDecode() to decode the data).
+WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+// ... (Consume icc_profile).
+WebPMuxDelete(mux);
+free(data);
+```
+
+For a detailed Mux API reference, please refer to the header file
+(src/webp/mux.h).
+
+### Demux API
+
+The Demux API enables extraction of images and extended format data from WebP
+files. This API currently supports reading of XMP/EXIF metadata, ICC profile and
+animated images. Other features may be added in subsequent releases.
+
+Code example: Demuxing WebP data to extract all the frames, ICC profile and
+EXIF/XMP metadata.
+
+```c
+WebPDemuxer* demux = WebPDemux(&webp_data);
+uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+// ... (Get information about the features present in the WebP file).
+uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+// ... (Iterate over all frames).
+WebPIterator iter;
+if (WebPDemuxGetFrame(demux, 1, &iter)) {
+  do {
+    // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+    // ... and get other frame properties like width, height, offsets etc.
+    // ... see 'struct WebPIterator' below for more info).
+  } while (WebPDemuxNextFrame(&iter));
+  WebPDemuxReleaseIterator(&iter);
+}
+
+// ... (Extract metadata).
+WebPChunkIterator chunk_iter;
+if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+// ... (Consume the ICC profile in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+// ... (Consume the XMP metadata in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+WebPDemuxDelete(demux);
+```
+
+For a detailed Demux API reference, please refer to the header file
+(src/webp/demux.h).
+
+## AnimEncoder API
+
+The AnimEncoder API can be used to create animated WebP images.
+
+Code example:
+
+```c
+WebPAnimEncoderOptions enc_options;
+WebPAnimEncoderOptionsInit(&enc_options);
+// ... (Tune 'enc_options' as needed).
+WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+while(<there are more frames>) {
+  WebPConfig config;
+  WebPConfigInit(&config);
+  // ... (Tune 'config' as needed).
+  WebPAnimEncoderAdd(enc, frame, duration, &config);
+}
+WebPAnimEncoderAssemble(enc, webp_data);
+WebPAnimEncoderDelete(enc);
+// ... (Write the 'webp_data' to a file, or re-mux it further).
+```
+
+For a detailed AnimEncoder API reference, please refer to the header file
+(src/webp/mux.h).
+
+## AnimDecoder API
+
+This AnimDecoder API allows decoding (possibly) animated WebP images.
+
+Code Example:
+
+```c
+WebPAnimDecoderOptions dec_options;
+WebPAnimDecoderOptionsInit(&dec_options);
+// Tune 'dec_options' as needed.
+WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
+WebPAnimInfo anim_info;
+WebPAnimDecoderGetInfo(dec, &anim_info);
+for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
+  while (WebPAnimDecoderHasMoreFrames(dec)) {
+    uint8_t* buf;
+    int timestamp;
+    WebPAnimDecoderGetNext(dec, &buf, &timestamp);
+    // ... (Render 'buf' based on 'timestamp').
+    // ... (Do NOT free 'buf', as it is owned by 'dec').
+  }
+  WebPAnimDecoderReset(dec);
+}
+const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
+// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
+WebPAnimDecoderDelete(dec);
+```
+
+For a detailed AnimDecoder API reference, please refer to the header file
+(src/webp/demux.h).
diff --git a/third_party/libwebp/doc/building.md b/third_party/libwebp/doc/building.md
new file mode 100644
index 0000000..5efeab9
--- /dev/null
+++ b/third_party/libwebp/doc/building.md
@@ -0,0 +1,213 @@
+# Building
+
+## Windows build
+
+By running:
+
+```batch
+nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
+```
+
+the directory `output\release-static\(x64|x86)\bin` will contain the tools
+cwebp.exe and dwebp.exe. The directory `output\release-static\(x64|x86)\lib`
+will contain the libwebp static library. The target architecture (x86/x64) is
+detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in
+the system path.
+
+## Unix build using makefile.unix
+
+On platforms with GNU tools installed (gcc and make), running
+
+```shell
+make -f makefile.unix
+```
+
+will build the binaries examples/cwebp and examples/dwebp, along with the static
+library src/libwebp.a. No system-wide installation is supplied, as this is a
+simple alternative to the full installation system based on the autoconf tools
+(see below). Please refer to makefile.unix for additional details and
+customizations.
+
+## Using autoconf tools
+
+Prerequisites: a compiler (e.g., gcc), make, autoconf, automake, libtool.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install gcc make autoconf automake libtool
+```
+
+When building from git sources, you will need to run autogen.sh to generate the
+configure script.
+
+```shell
+./configure
+make
+make install
+```
+
+should be all you need to have the following files
+
+```
+/usr/local/include/webp/decode.h
+/usr/local/include/webp/encode.h
+/usr/local/include/webp/types.h
+/usr/local/lib/libwebp.*
+/usr/local/bin/cwebp
+/usr/local/bin/dwebp
+```
+
+installed.
+
+Note: A decode-only library, libwebpdecoder, is available using the
+`--enable-libwebpdecoder` flag. The encode library is built separately and can
+be installed independently using a minor modification in the corresponding
+Makefile.am configure files (see comments there). See `./configure --help` for
+more options.
+
+## Building for MIPS Linux
+
+MIPS Linux toolchain stable available releases can be found at:
+https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
+
+```shell
+# Add toolchain to PATH
+export PATH=$PATH:/path/to/toolchain/bin
+
+# 32-bit build for mips32r5 (p5600)
+HOST=mips-mti-linux-gnu
+MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
+  -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
+
+# 64-bit build for mips64r6 (i6400)
+HOST=mips-img-linux-gnu
+MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
+  -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
+
+./configure --host=${HOST} --build=`config.guess` \
+  CC="${HOST}-gcc -EL" \
+  CFLAGS="$MIPS_CFLAGS" \
+  LDFLAGS="$MIPS_LDFLAGS"
+make
+make install
+```
+
+## CMake
+
+With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
+and the JS bindings.
+
+Prerequisites: a compiler (e.g., gcc with autotools) and CMake.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install build-essential cmake
+```
+
+When building from git sources, you will need to run cmake to generate the
+makefiles.
+
+```shell
+mkdir build && cd build && cmake ../
+make
+make install
+```
+
+If you also want any of the executables, you will need to enable them through
+CMake, e.g.:
+
+```shell
+cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
+```
+
+or through your favorite interface (like ccmake or cmake-qt-gui).
+
+Use option `-DWEBP_UNICODE=ON` for Unicode support on Windows (with chcp 65001).
+
+Finally, once installed, you can also use WebP in your CMake project by doing:
+
+```cmake
+find_package(WebP)
+```
+
+which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
+
+## Gradle
+
+The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
+dwebp and webpmux_example.
+
+Prerequisites: a compiler (e.g., gcc with autotools) and gradle.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install build-essential gradle
+```
+
+When building from git sources, you will need to run the Gradle wrapper with the
+appropriate target, e.g. :
+
+```shell
+./gradlew buildAllExecutables
+```
+
+## SWIG bindings
+
+To generate language bindings from swig/libwebp.swig at least swig-1.3
+(http://www.swig.org) is required.
+
+Currently the following functions are mapped:
+
+Decode:
+
+```
+WebPGetDecoderVersion
+WebPGetInfo
+WebPDecodeRGBA
+WebPDecodeARGB
+WebPDecodeBGRA
+WebPDecodeBGR
+WebPDecodeRGB
+```
+
+Encode:
+
+```
+WebPGetEncoderVersion
+WebPEncodeRGBA
+WebPEncodeBGRA
+WebPEncodeRGB
+WebPEncodeBGR
+WebPEncodeLosslessRGBA
+WebPEncodeLosslessBGRA
+WebPEncodeLosslessRGB
+WebPEncodeLosslessBGR
+```
+
+See also the [swig documentation](../swig/README.md) for more detailed build
+instructions and usage examples.
+
+### Java bindings
+
+To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is
+necessary for enum support. The output is intended to be a shared object / DLL
+that can be loaded via `System.loadLibrary("webp_jni")`.
+
+### Python bindings
+
+To build the swig-generated Python extension code at least Python 2.6 is
+required. Python < 2.6 may build with some minor changes to libwebp.swig or the
+generated code, but is untested.
+
+## Javascript decoder
+
+Libwebp can be compiled into a JavaScript decoder using Emscripten and CMake.
+See the [corresponding documentation](../README.md)
diff --git a/third_party/libwebp/doc/specs_generation.md b/third_party/libwebp/doc/specs_generation.md
new file mode 100644
index 0000000..0380d66
--- /dev/null
+++ b/third_party/libwebp/doc/specs_generation.md
@@ -0,0 +1,26 @@
+# Generate libwebp Container Spec Docs from Text Source
+
+HTML generation requires [kramdown](https://kramdown.gettalong.org/), easily
+installed as a [rubygem](https://rubygems.org/). Rubygems installation should
+satisfy dependencies automatically.
+
+HTML generation can then be done from the project root:
+
+```shell
+$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
+  doc/output/webp-container-spec.html
+```
+
+kramdown can optionally syntax highlight code blocks, using
+[CodeRay](https://github.com/rubychan/coderay), a dependency of kramdown that
+rubygems will install automatically. The following will apply inline CSS
+styling; an external stylesheet is not needed.
+
+```shell
+$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
+  doc/template.html --coderay-css style --coderay-line-numbers ' ' \
+  --coderay-default-lang c > \
+  doc/output/webp-lossless-bitstream-spec.html
+```
+
+Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
diff --git a/third_party/libwebp/doc/tools.md b/third_party/libwebp/doc/tools.md
new file mode 100644
index 0000000..bf49274
--- /dev/null
+++ b/third_party/libwebp/doc/tools.md
@@ -0,0 +1,516 @@
+# WebP tools
+
+## Encoding tool
+
+The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp)
+images.
+
+The easiest use should look like:
+
+```shell
+cwebp input.png -q 80 -o output.webp
+```
+
+which will convert the input file to a WebP file using a quality factor of 80 on
+a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is
+75).
+
+You might want to try the `-lossless` flag too, which will compress the source
+(in RGBA format) without any loss. The `-q` quality parameter will in this case
+control the amount of processing time spent trying to make the output file as
+small as possible.
+
+A longer list of options is available using the `-longhelp` command line flag:
+
+```shell
+> cwebp -longhelp
+Usage:
+ cwebp [-preset <...>] [options] in_file [-o out_file]
+```
+
+If input size (-s) for an image is not specified, it is assumed to be a PNG,
+JPEG, TIFF or WebP file. Note: Animated PNG and WebP files are not supported.
+
+Options:
+
+```
+-h / -help ............. short help
+-H / -longhelp ......... long help
+-q <float> ............. quality factor (0:small..100:big), default=75
+-alpha_q <int> ......... transparency-compression quality (0..100),
+                         default=100
+-preset <string> ....... preset setting, one of:
+                          default, photo, picture,
+                          drawing, icon, text
+   -preset must come first, as it overwrites other parameters
+-z <int> ............... activates lossless preset with given
+                         level in [0:fast, ..., 9:slowest]
+
+-m <int> ............... compression method (0=fast, 6=slowest), default=4
+-segments <int> ........ number of segments to use (1..4), default=4
+-size <int> ............ target size (in bytes)
+-psnr <float> .......... target PSNR (in dB. typically: 42)
+
+-s <int> <int> ......... input size (width x height) for YUV
+-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
+-f <int> ............... filter strength (0=off..100), default=60
+-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
+-strong ................ use strong filter instead of simple (default)
+-nostrong .............. use simple filter instead of strong
+-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
+-partition_limit <int> . limit quality to fit the 512k limit on
+                         the first partition (0=no degradation ... 100=full)
+-pass <int> ............ analysis pass number (1..10)
+-qrange <min> <max> .... specifies the permissible quality range
+                         (default: 0 100)
+-crop <x> <y> <w> <h> .. crop picture with the given rectangle
+-resize <w> <h> ........ resize picture (*after* any cropping)
+-mt .................... use multi-threading if available
+-low_memory ............ reduce memory usage (slower encoding)
+-map <int> ............. print map of extra info
+-print_psnr ............ prints averaged PSNR distortion
+-print_ssim ............ prints averaged SSIM distortion
+-print_lsim ............ prints local-similarity distortion
+-d <file.pgm> .......... dump the compressed output (PGM file)
+-alpha_method <int> .... transparency-compression method (0..1), default=1
+-alpha_filter <string> . predictive filtering for alpha plane,
+                         one of: none, fast (default) or best
+-exact ................. preserve RGB values in transparent area, default=off
+-blend_alpha <hex> ..... blend colors against background color
+                         expressed as RGB values written in
+                         hexadecimal, e.g. 0xc0e0d0 for red=0xc0
+                         green=0xe0 and blue=0xd0
+-noalpha ............... discard any transparency information
+-lossless .............. encode image losslessly, default=off
+-near_lossless <int> ... use near-lossless image preprocessing
+                         (0..100=off), default=100
+-hint <string> ......... specify image characteristics hint,
+                         one of: photo, picture or graph
+
+-metadata <string> ..... comma separated list of metadata to
+                         copy from the input to the output if present.
+                         Valid values: all, none (default), exif, icc, xmp
+
+-short ................. condense printed message
+-quiet ................. don't print anything
+-version ............... print version number and exit
+-noasm ................. disable all assembly optimizations
+-v ..................... verbose, e.g. print encoding/decoding times
+-progress .............. report encoding progress
+```
+
+Experimental Options:
+
+```
+-jpeg_like ............. roughly match expected JPEG size
+-af .................... auto-adjust filter strength
+-pre <int> ............. pre-processing filter
+```
+
+The main options you might want to try in order to further tune the visual
+quality are:
+
+-preset -sns -f -m
+
+Namely:
+
+*   `preset` will set up a default encoding configuration targeting a particular
+    type of input. It should appear first in the list of options, so that
+    subsequent options can take effect on top of this preset. Default value is
+    'default'.
+*   `sns` will progressively turn on (when going from 0 to 100) some additional
+    visual optimizations (like: segmentation map re-enforcement). This option
+    will balance the bit allocation differently. It tries to take bits from the
+    "easy" parts of the picture and use them in the "difficult" ones instead.
+    Usually, raising the sns value (at fixed -q value) leads to larger files,
+    but with better quality. Typical value is around '75'.
+*   `f` option directly links to the filtering strength used by the codec's
+    in-loop processing. The higher the value, the smoother the highly-compressed
+    area will look. This is particularly useful when aiming at very small files.
+    Typical values are around 20-30. Note that using the option
+    -strong/-nostrong will change the type of filtering. Use "-f 0" to turn
+    filtering off.
+*   `m` controls the trade-off between encoding speed and quality. Default is 4.
+    You can try -m 5 or -m 6 to explore more (time-consuming) encoding
+    possibilities. A lower value will result in faster encoding at the expense
+    of quality.
+
+## Decoding tool
+
+There is a decoding sample in examples/dwebp.c which will take a .webp file and
+decode it to a PNG image file (amongst other formats). This is simply to
+demonstrate the use of the API. You can verify the file test.webp decodes to
+exactly the same as test_ref.ppm by using:
+
+```shell
+cd examples
+./dwebp test.webp -ppm -o test.ppm
+diff test.ppm test_ref.ppm
+```
+
+The full list of options is available using -h:
+
+```shell
+> dwebp -h
+Usage: dwebp in_file [options] [-o out_file]
+```
+
+Decodes the WebP image file to PNG format [Default]. Note: Animated WebP files
+are not supported.
+
+Use following options to convert into alternate image formats:
+
+```
+-pam ......... save the raw RGBA samples as a color PAM
+-ppm ......... save the raw RGB samples as a color PPM
+-bmp ......... save as uncompressed BMP format
+-tiff ........ save as uncompressed TIFF format
+-pgm ......... save the raw YUV samples as a grayscale PGM
+               file with IMC4 layout
+-yuv ......... save the raw YUV samples in flat layout
+```
+
+Other options are:
+
+```
+-version ..... print version number and exit
+-nofancy ..... don't use the fancy YUV420 upscaler
+-nofilter .... disable in-loop filtering
+-nodither .... disable dithering
+-dither <d> .. dithering strength (in 0..100)
+-alpha_dither  use alpha-plane dithering if needed
+-mt .......... use multi-threading
+-crop <x> <y> <w> <h> ... crop output with the given rectangle
+-resize <w> <h> ......... resize output (*after* any cropping)
+-flip ........ flip the output vertically
+-alpha ....... only save the alpha plane
+-incremental . use incremental decoding (useful for tests)
+-h ........... this help message
+-v ........... verbose (e.g. print encoding/decoding times)
+-quiet ....... quiet mode, don't print anything
+-noasm ....... disable all assembly optimizations
+```
+
+## WebP file analysis tool
+
+`webpinfo` can be used to print out the chunk level structure and bitstream
+header information of WebP files. It can also check if the files are of valid
+WebP format.
+
+Usage:
+
+```shell
+webpinfo [options] in_files
+```
+
+Note: there could be multiple input files; options must come before input files.
+
+Options:
+
+```
+-version ........... Print version number and exit.
+-quiet ............. Do not show chunk parsing information.
+-diag .............. Show parsing error diagnosis.
+-summary ........... Show chunk stats summary.
+-bitstream_info .... Parse bitstream header.
+```
+
+## Visualization tool
+
+There's a little self-serve visualization tool called 'vwebp' under the
+examples/ directory. It uses OpenGL to open a simple drawing window and show a
+decoded WebP file. It's not yet integrated in the automake build system, but you
+can try to manually compile it using the recommendations below.
+
+Usage:
+
+```shell
+vwebp in_file [options]
+```
+
+Decodes the WebP image file and visualize it using OpenGL
+
+Options are:
+
+```
+-version ..... print version number and exit
+-noicc ....... don't use the icc profile if present
+-nofancy ..... don't use the fancy YUV420 upscaler
+-nofilter .... disable in-loop filtering
+-dither <int>  dithering strength (0..100), default=50
+-noalphadither disable alpha plane dithering
+-usebgcolor .. display background color
+-mt .......... use multi-threading
+-info ........ print info
+-h ........... this help message
+```
+
+Keyboard shortcuts:
+
+```
+'c' ................ toggle use of color profile
+'b' ................ toggle background color display
+'i' ................ overlay file information
+'d' ................ disable blending & disposal (debug)
+'q' / 'Q' / ESC .... quit
+```
+
+### Building
+
+Prerequisites:
+
+1.  OpenGL & OpenGL Utility Toolkit (GLUT)
+
+    Linux: `sudo apt-get install freeglut3-dev mesa-common-dev`
+
+    Mac + Xcode: These libraries should be available in the OpenGL / GLUT
+    frameworks.
+
+    Windows: http://freeglut.sourceforge.net/index.php#download
+
+2.  (Optional) qcms (Quick Color Management System)
+
+    1.  Download qcms from Mozilla / Chromium:
+        https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
+        https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
+    2.  Build and archive the source files as libqcms.a / qcms.lib
+    3.  Update makefile.unix / Makefile.vc
+        1.  Define WEBP_HAVE_QCMS
+        2.  Update include / library paths to reference the qcms directory.
+
+Build using makefile.unix / Makefile.vc:
+
+```shell
+$ make -f makefile.unix examples/vwebp
+> nmake /f Makefile.vc CFG=release-static \
+    ../obj/x64/release-static/bin/vwebp.exe
+```
+
+## Animation creation tool
+
+The utility `img2webp` can turn a sequence of input images (PNG, JPEG, ...) into
+an animated WebP file. It offers fine control over duration, encoding modes,
+etc.
+
+Usage:
+
+```shell
+img2webp [file_options] [[frame_options] frame_file]... [-o webp_file]
+```
+
+File-level options (only used at the start of compression):
+
+```
+-min_size ............ minimize size
+-kmax <int> .......... maximum number of frame between key-frames
+                        (0=only keyframes)
+-kmin <int> .......... minimum number of frame between key-frames
+                        (0=disable key-frames altogether)
+-mixed ............... use mixed lossy/lossless automatic mode
+-near_lossless <int> . use near-lossless image preprocessing
+                       (0..100=off), default=100
+-sharp_yuv ........... use sharper (and slower) RGB->YUV conversion
+                       (lossy only)
+-loop <int> .......... loop count (default: 0, = infinite loop)
+-v ................... verbose mode
+-h ................... this help
+-version ............. print version number and exit
+```
+
+Per-frame options (only used for subsequent images input):
+
+```
+-d <int> ............. frame duration in ms (default: 100)
+-lossless  ........... use lossless mode (default)
+-lossy ... ........... use lossy mode
+-q <float> ........... quality
+-m <int> ............. method to use
+```
+
+example: `img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp`
+
+Note: if a single file name is passed as the argument, the arguments will be
+tokenized from this file. The file name must not start with the character '-'.
+
+## Animated GIF conversion
+
+Animated GIF files can be converted to WebP files with animation using the
+gif2webp utility available under examples/. The files can then be viewed using
+vwebp.
+
+Usage:
+
+```shell
+gif2webp [options] gif_file -o webp_file
+```
+
+Options:
+
+```
+-h / -help ............. this help
+-lossy ................. encode image using lossy compression
+-mixed ................. for each frame in the image, pick lossy
+                         or lossless compression heuristically
+-q <float> ............. quality factor (0:small..100:big)
+-m <int> ............... compression method (0=fast, 6=slowest)
+-min_size .............. minimize output size (default:off)
+                         lossless compression by default; can be
+                         combined with -q, -m, -lossy or -mixed
+                         options
+-kmin <int> ............ min distance between key frames
+-kmax <int> ............ max distance between key frames
+-f <int> ............... filter strength (0=off..100)
+-metadata <string> ..... comma separated list of metadata to
+                         copy from the input to the output if present
+                         Valid values: all, none, icc, xmp (default)
+-loop_compatibility .... use compatibility mode for Chrome
+                         version prior to M62 (inclusive)
+-mt .................... use multi-threading if available
+
+-version ............... print version number and exit
+-v ..................... verbose
+-quiet ................. don't print anything
+```
+
+### Building
+
+With the libgif development files installed, gif2webp can be built using
+makefile.unix:
+
+```shell
+$ make -f makefile.unix examples/gif2webp
+```
+
+or using autoconf:
+
+```shell
+$ ./configure --enable-everything
+$ make
+```
+
+## Comparison of animated images
+
+Test utility anim_diff under examples/ can be used to compare two animated
+images (each can be GIF or WebP).
+
+Usage:
+
+```shell
+anim_diff <image1> <image2> [options]
+```
+
+Options:
+
+```
+-dump_frames <folder> dump decoded frames in PAM format
+-min_psnr <float> ... minimum per-frame PSNR
+-raw_comparison ..... if this flag is not used, RGB is
+                      premultiplied before comparison
+-max_diff <int> ..... maximum allowed difference per channel
+                      between corresponding pixels in subsequent
+                      frames
+-h .................. this help
+-version ............ print version number and exit
+```
+
+### Building
+
+With the libgif development files installed, anim_diff can be built using
+makefile.unix:
+
+```shell
+$ make -f makefile.unix examples/anim_diff
+```
+
+or using autoconf:
+
+```shell
+$ ./configure --enable-everything
+$ make
+```
+
+## WebP Mux tool
+
+The examples/ directory contains a tool (webpmux) for manipulating WebP files.
+The webpmux tool can be used to create an extended format WebP file and also to
+extract or strip relevant data from such a file.
+
+A list of options is available using the -help command line flag:
+
+```shell
+> webpmux -help
+Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
+       webpmux -set SET_OPTIONS INPUT -o OUTPUT
+       webpmux -duration DURATION_OPTIONS [-duration ...]
+               INPUT -o OUTPUT
+       webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
+       webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
+               [-bgcolor BACKGROUND_COLOR] -o OUTPUT
+       webpmux -info INPUT
+       webpmux [-h|-help]
+       webpmux -version
+       webpmux argument_file_name
+
+GET_OPTIONS:
+ Extract relevant data:
+   icc       get ICC profile
+   exif      get EXIF metadata
+   xmp       get XMP metadata
+   frame n   get nth frame
+
+SET_OPTIONS:
+ Set color profile/metadata/parameters:
+   loop LOOP_COUNT            set the loop count
+   bgcolor BACKGROUND_COLOR   set the animation background color
+   icc  file.icc              set ICC profile
+   exif file.exif             set EXIF metadata
+   xmp  file.xmp              set XMP metadata
+   where:    'file.icc' contains the ICC profile to be set,
+             'file.exif' contains the EXIF metadata to be set
+             'file.xmp' contains the XMP metadata to be set
+
+DURATION_OPTIONS:
+ Set duration of selected frames:
+   duration            set duration for all frames
+   duration,frame      set duration of a particular frame
+   duration,start,end  set duration of frames in the
+                        interval [start,end])
+   where: 'duration' is the duration in milliseconds
+          'start' is the start frame index
+          'end' is the inclusive end frame index
+           The special 'end' value '0' means: last frame.
+
+STRIP_OPTIONS:
+ Strip color profile/metadata:
+   icc       strip ICC profile
+   exif      strip EXIF metadata
+   xmp       strip XMP metadata
+
+FRAME_OPTIONS(i):
+ Create animation:
+   file_i +di[+xi+yi[+mi[bi]]]
+   where:    'file_i' is the i'th animation frame (WebP format),
+             'di' is the pause duration before next frame,
+             'xi','yi' specify the image offset for this frame,
+             'mi' is the dispose method for this frame (0 or 1),
+             'bi' is the blending method for this frame (+b or -b)
+
+LOOP_COUNT:
+ Number of times to repeat the animation.
+ Valid range is 0 to 65535 [Default: 0 (infinite)].
+
+BACKGROUND_COLOR:
+ Background color of the canvas.
+  A,R,G,B
+  where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
+            the Alpha, Red, Green and Blue component values respectively
+            [Default: 255,255,255,255]
+
+INPUT & OUTPUT are in WebP format.
+
+Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
+valid.
+
+Note: if a single file name is passed as the argument, the arguments will be
+tokenized from this file. The file name must not start with the character '-'.
+```
diff --git a/third_party/libwebp/doc/webp-container-spec.txt b/third_party/libwebp/doc/webp-container-spec.txt
index 94a7ca2..3e66526 100644
--- a/third_party/libwebp/doc/webp-container-spec.txt
+++ b/third_party/libwebp/doc/webp-container-spec.txt
@@ -2,10 +2,10 @@
 
 Although you may be viewing an alternate representation, this document
 is sourced in Markdown, a light-duty markup scheme, and is optimized for
-the [kramdown](http://kramdown.rubyforge.org/) transformer.
+the [kramdown](https://kramdown.gettalong.org/) transformer.
 
-See the accompanying README. External link targets are referenced at the
-end of this file.
+See the accompanying specs_generation.md. External link targets are referenced
+at the end of this file.
 
 -->
 
@@ -20,25 +20,25 @@
 Introduction
 ------------
 
-WebP is an image format that uses either (i) the VP8 key frame encoding
-to compress image data in a lossy way, or (ii) the WebP lossless encoding
-(and possibly other encodings in the future). These encoding schemes should
-make it more efficient than currently used formats. It is optimized for fast
-image transfer over the network (e.g., for websites). The WebP format has
-feature parity (color profile, metadata, animation etc) with other formats as
-well. This document describes the structure of a WebP file.
+WebP is an image format that uses either (i) the VP8 key frame encoding to
+compress image data in a lossy way, or (ii) the WebP lossless encoding. These
+encoding schemes should make it more efficient than older formats such as JPEG,
+GIF and PNG. It is optimized for fast image transfer over the network (for
+example, for websites). The WebP format has feature parity (color profile,
+metadata, animation, etc.) with other formats as well. This document describes
+the structure of a WebP file.
 
-The WebP container (i.e., RIFF container for WebP) allows feature support over
-and above the basic use case of WebP (i.e., a file containing a single image
-encoded as a VP8 key frame). The WebP container provides additional support
-for:
+The WebP container (that is, the RIFF container for WebP) allows feature support
+over and above the basic use case of WebP (that is, a file containing a single
+image encoded as a VP8 key frame). The WebP container provides additional
+support for:
 
   * **Lossless compression.** An image can be losslessly compressed, using the
     WebP Lossless Format.
 
-  * **Metadata.** An image may have metadata stored in EXIF or XMP formats.
+  * **Metadata.** An image may have metadata stored in Exif or XMP formats.
 
-  * **Transparency.** An image may have transparency, i.e., an alpha channel.
+  * **Transparency.** An image may have transparency, that is, an alpha channel.
 
   * **Color Profile.** An image may have an embedded ICC profile as described
     by the [International Color Consortium][iccspec].
@@ -46,24 +46,21 @@
   * **Animation.** An image may have multiple frames with pauses between them,
     making it an animation.
 
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-document are to be interpreted as described in [RFC 2119][].
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
+"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][]
+when, and only when, they appear in all capitals, as shown here.
 
 Bit numbering in chunk diagrams starts at `0` for the most significant bit
 ('MSB 0') as described in [RFC 1166][].
 
-**Note:** Out of the features mentioned above, lossy compression, lossless
-compression, transparency, metadata, color profile and animation are finalized
-and are to be considered stable.
+Terminology & Basics
+--------------------
 
-Terminology &amp; Basics
-------------------------
-
-A WebP file contains either a still image (i.e., an encoded matrix of pixels)
+A WebP file contains either a still image (that is, an encoded matrix of pixels)
 or an [animation](#animation). Optionally, it can also contain transparency
-information, color profile and metadata. In case we need to refer only to the
-matrix of pixels, we will call it the _canvas_ of the image.
+information, color profile and metadata. We refer to the matrix of pixels as the
+_canvas_ of the image.
 
 Below are additional terms used throughout this document:
 
@@ -87,18 +84,25 @@
 _FourCC_
 
 : A _FourCC_ (four-character code) is a _uint32_ created by concatenating four
-  ASCII characters in little-endian order.
+  ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and
+ 'AAAA' (0x41414141) are treated as different _FourCCs_.
 
 _1-based_
 
-: An unsigned integer field storing values offset by `-1`. e.g., Such a field
-  would store value _25_ as _24_.
+: An unsigned integer field storing values offset by `-1`, for example, such a
+  field would store value _25_ as _24_.
+
+_ChunkHeader('ABCD')_
+
+: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
+  chunks, where 'ABCD' is the FourCC for the chunk. This element's size is 8
+  bytes.
 
 
 RIFF File Format
 ----------------
 
-The WebP file format is based on the RIFF (resource interchange file format)
+The WebP file format is based on the RIFF (Resource Interchange File Format)
 document format.
 
 The basic element of a RIFF file is a _chunk_. It consists of:
@@ -110,7 +114,7 @@
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                          Chunk Size                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                         Chunk Payload                         |
+    :                         Chunk Payload                         :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Chunk FourCC: 32 bits
@@ -119,19 +123,13 @@
 
 Chunk Size: 32 bits (_uint32_)
 
-: The size of the chunk not including this field, the chunk identifier or
-  padding.
+: The size of the chunk in bytes, not including this field, the chunk
+  identifier or padding.
 
 Chunk Payload: _Chunk Size_ bytes
 
-: The data payload. If _Chunk Size_ is odd, a single padding byte -- that
-  SHOULD be `0` -- is added.
-
-_ChunkHeader('ABCD')_
-
-: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
-  chunks, where 'ABCD' is the FourCC for the chunk. This element's
-  size is 8 bytes.
+: The data payload. If _Chunk Size_ is odd, a single padding byte -- that MUST
+  be `0` to conform with RIFF -- is added.
 
 **Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard
 chunks that apply to any RIFF file format, while FourCCs specific to a file
@@ -167,9 +165,11 @@
 
 A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size
 in the header is the total size of the chunks that follow plus `4` bytes for
-the 'WEBP' FourCC. The file SHOULD NOT contain anything after it. As the size
-of any chunk is even, the size given by the RIFF header is also even. The
-contents of individual chunks will be described in the following sections.
+the 'WEBP' FourCC. The file SHOULD NOT contain any data after the data
+specified by _File Size_. Readers MAY parse such files, ignoring the trailing
+data. As the size of any chunk is even, the size given by the RIFF header is
+also even. The contents of individual chunks are described in the following
+sections.
 
 
 Simple File Format (Lossy)
@@ -184,9 +184,11 @@
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                    WebP file header (12 bytes)                |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          VP8 chunk                            |
+    :                          VP8 chunk                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8 chunk:
@@ -195,20 +197,24 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8 ')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                           VP8 data                            |
+    :                           VP8 data                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8 data: _Chunk Size_ bytes
 
 : VP8 bitstream data.
 
+Note the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20).
+
 The VP8 bitstream format specification can be found at [VP8 Data Format and
 Decoding Guide][vp8spec]. Note that the VP8 frame header contains the VP8 frame
 width and height. That is assumed to be the width and height of the canvas.
 
-The VP8 specification describes how to decode the image into Y'CbCr
-format. To convert to RGB, Rec. 601 SHOULD be used.
+The VP8 specification describes how to decode the image into Y'CbCr format. To
+convert to RGB, Rec. 601 SHOULD be used. Applications MAY use another
+conversion method, but visual results may differ among decoders.
 
 
 Simple File Format (Lossless)
@@ -225,9 +231,11 @@
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                    WebP file header (12 bytes)                |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          VP8L chunk                           |
+    :                          VP8L chunk                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8L chunk:
@@ -236,8 +244,9 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8L')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                           VP8L data                           |
+    :                           VP8L data                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8L data: _Chunk Size_ bytes
@@ -265,11 +274,11 @@
 
   * Image data.
 
-  * An optional 'EXIF' chunk with EXIF metadata.
+  * An optional 'EXIF' chunk with Exif metadata.
 
   * An optional 'XMP ' chunk with XMP metadata.
 
-  * An optional list of [unknown chunks](#unknown-chunks). _\[status: experimental\]_
+  * An optional list of [unknown chunks](#unknown-chunks).
 
 For a _still image_, the _image data_ consists of a single frame, which is made
 up of:
@@ -283,7 +292,7 @@
 
 All chunks SHOULD be placed in the same order as listed above. If a chunk
 appears in the wrong place, the file is invalid, but readers MAY parse the
-file, ignoring the chunks that come too late.
+file, ignoring the chunks that are out of order.
 
 **Rationale:** Setting the order of chunks should allow quicker file
 parsing. For example, if an 'ALPH' chunk does not appear in its required
@@ -297,9 +306,12 @@
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                   WebP file header (12 bytes)                 |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8X')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Rsv|I|L|E|X|A|R|                   Reserved                    |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -310,7 +322,7 @@
 
 Reserved (Rsv): 2 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 ICC profile (I): 1 bit
 
@@ -321,9 +333,9 @@
 : Set if any of the frames of the image contain transparency information
   ("alpha").
 
-EXIF metadata (E): 1 bit
+Exif metadata (E): 1 bit
 
-: Set if the file contains EXIF metadata.
+: Set if the file contains Exif metadata.
 
 XMP metadata (X): 1 bit
 
@@ -336,25 +348,25 @@
 
 Reserved (R): 1 bit
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Reserved: 24 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Canvas Width Minus One: 24 bits
 
 : _1-based_ width of the canvas in pixels.
-  The actual canvas width is '1 + Canvas Width Minus One'
+  The actual canvas width is `1 + Canvas Width Minus One`.
 
 Canvas Height Minus One: 24 bits
 
 : _1-based_ height of the canvas in pixels.
-  The actual canvas height is '1 + Canvas Height Minus One'
+  The actual canvas height is `1 + Canvas Height Minus One`.
 
 The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
 
-Future specifications MAY add more fields.
+Future specifications may add more fields. Unknown fields MUST be ignored.
 
 ### Chunks
 
@@ -372,6 +384,7 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ANIM')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       Background Color                        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -387,8 +400,8 @@
 
 **Note**:
 
-  * Background color MAY contain a transparency value (alpha), even if the
-    _Alpha_ flag in [VP8X chunk](#extended_header) is unset.
+  * Background color MAY contain a non-opaque alpha value, even if the _Alpha_
+    flag in [VP8X chunk](#extended_header) is unset.
 
   * Viewer applications SHOULD treat the background color value as a hint, and
     are not required to use it.
@@ -401,8 +414,8 @@
 : The number of times to loop the animation. `0` means infinitely.
 
 This chunk MUST appear if the _Animation_ flag in the VP8X chunk is set.
-If the _Animation_ flag is not set and this chunk is present, it
-SHOULD be ignored.
+If the _Animation_ flag is not set and this chunk is present, it MUST be
+ignored.
 
 ANMF chunk:
 
@@ -413,6 +426,7 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ANMF')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        Frame X                |             ...
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -422,26 +436,26 @@
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                 Frame Duration                |  Reserved |B|D|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                         Frame Data                            |
+    :                         Frame Data                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Frame X: 24 bits (_uint24_)
 
-: The X coordinate of the upper left corner of the frame is `Frame X * 2`
+: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
 
 Frame Y: 24 bits (_uint24_)
 
-: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`
+: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
 
 Frame Width Minus One: 24 bits (_uint24_)
 
 : The _1-based_ width of the frame.
-  The frame width is `1 + Frame Width Minus One`
+  The frame width is `1 + Frame Width Minus One`.
 
 Frame Height Minus One: 24 bits (_uint24_)
 
 : The _1-based_ height of the frame.
-  The frame height is `1 + Frame Height Minus One`
+  The frame height is `1 + Frame Height Minus One`.
 
 Frame Duration: 24 bits (_uint24_)
 
@@ -452,7 +466,7 @@
 
 Reserved: 6 bits
 
-: SHOULD be 0.
+: MUST be `0`. Readers MUST ignore this field.
 
 Blending method (B): 1 bit
 
@@ -497,8 +511,9 @@
     if blend.A = 0 then
       blend.RGB = 0
     else
-      blend.RGB = (src.RGB * src.A +
-                   dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
+      blend.RGB =
+          (src.RGB * src.A +
+           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
 ~~~~~
 
   * Alpha-blending SHOULD be done in linear color space, by taking into account
@@ -525,22 +540,23 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ALPH')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Rsv| P | F | C |     Alpha Bitstream...                        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Reserved (Rsv): 2 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Pre-processing (P): 2 bits
 
-: These INFORMATIVE bits are used to signal the pre-processing that has
+: These _informative_ bits are used to signal the pre-processing that has
   been performed during compression. The decoder can use this information to
-  e.g. dither the values or smooth the gradients prior to display.
+  for example, dither the values or smooth the gradients prior to display.
 
-    * `0`: no pre-processing
-    * `1`: level reduction
+    * `0`: No pre-processing.
+    * `1`: Level reduction.
 
 Filtering method (F): 2 bits
 
@@ -573,14 +589,14 @@
   * v    otherwise
 
 The final value is derived by adding the decompressed value `X` to the
-predictor and using modulo-256 arithmetic to wrap the \[256-511\] range
-into the \[0-255\] one:
+predictor and using modulo-256 arithmetic to wrap the \[256..511\] range
+into the \[0..255\] one:
 
 `alpha = (predictor + X) % 256`
 
-There are special cases for left-most and top-most pixel positions:
+There are special cases for the left-most and top-most pixel positions:
 
-  * Top-left value at location (0,0) uses 0 as predictor value. Otherwise,
+  * The top-left value at location (0, 0) uses 0 as predictor value. Otherwise,
   * For horizontal or gradient filtering methods, the left-most pixels at
     location (0, y) are predicted using the location (0, y-1) just above.
   * For vertical or gradient filtering methods, the top-most pixels at
@@ -642,14 +658,15 @@
 [Simple File Format (Lossy)](#simple-file-format-lossy)
 and [Simple File Format (Lossless)](#simple-file-format-lossless) respectively.
 
-#### Color profile
+#### Color Profile
 
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ICCP')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                       Color Profile                           |
+    :                       Color Profile                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Color Profile: _Chunk Size_ bytes
@@ -669,8 +686,7 @@
 Metadata can be stored in 'EXIF' or 'XMP ' chunks.
 
 There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there
-are more such chunks, readers MAY ignore all except the first one. Also, a file
-may possibly contain both 'EXIF' and 'XMP ' chunks.
+are more such chunks, readers MAY ignore all except the first one.
 
 The chunks are defined as follows:
 
@@ -680,13 +696,14 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('EXIF')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        EXIF Metadata                          |
+    :                        Exif Metadata                          :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
-EXIF Metadata: _Chunk Size_ bytes
+Exif Metadata: _Chunk Size_ bytes
 
-: image metadata in EXIF format.
+: Image metadata in Exif format.
 
 XMP chunk:
 
@@ -694,18 +711,21 @@
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('XMP ')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        XMP Metadata                           |
+    :                        XMP Metadata                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 XMP Metadata: _Chunk Size_ bytes
 
-: image metadata in XMP format.
+: Image metadata in XMP format.
+
+Note the fourth character in the 'XMP ' FourCC is an ASCII space (0x20).
 
 Additional guidance about handling metadata can be found in the
 Metadata Working Group's [Guidelines for Handling Metadata][metadata].
 
-#### Unknown Chunks _\[status: experimental\]_
+#### Unknown Chunks
 
 A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk
 tag_ is different from any of the chunks described in this document, is
@@ -724,49 +744,73 @@
 Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their
 original order (unless they specifically intend to modify these chunks).
 
-### Assembling the Canvas from frames
+### Assembling the Canvas From Frames
 
-Here we provide an overview of how a reader should assemble a canvas in the
-case of an animated image. The notation _VP8X.field_ means the field in the
-'VP8X' chunk with the same description.
+Here we provide an overview of how a reader MUST assemble a canvas in the case
+of an animated image.
 
-Displaying an _animated image_ canvas MUST be equivalent to the following
-pseudocode:
+The process begins with creating a canvas using the dimensions given in the
+'VP8X' chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus
+One + 1` pixels high. The `Loop Count` field from the 'ANIM' chunk controls how
+many times the animation process is repeated. This is `Loop Count - 1` for
+non-zero `Loop Count` values or infinitely if `Loop Count` is zero.
+
+At the beginning of each loop iteration the canvas is filled using the
+background color from the 'ANIM' chunk or an application defined color.
+
+'ANMF' chunks contain individual frames given in display order. Before rendering
+each frame, the previous frame's `Disposal method` is applied.
+
+The rendering of the decoded frame begins at the Cartesian coordinates (`2 *
+Frame X`, `2 * Frame Y`) using the top-left corner of the canvas as the origin.
+`Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels
+high are rendered onto the canvas using the `Blending method`.
+
+The canvas is displayed for `Frame Duration` milliseconds. This continues until
+all frames given by 'ANMF' chunks have been displayed. A new loop iteration is
+then begun or the canvas is left in its final state if all iterations have been
+completed.
+
+The following pseudocode illustrates the rendering process. The notation
+_VP8X.field_ means the field in the 'VP8X' chunk with the same description.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 assert VP8X.flags.hasAnimation
 canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
          background color ANIM.background_color.
 loop_count ← ANIM.loopCount
-dispose_method ← ANIM.disposeMethod
+dispose_method ← Dispose to background color
 if loop_count == 0:
-    loop_count = ∞
+  loop_count = ∞
 frame_params ← nil
 assert next chunk in image_data is ANMF
 for loop = 0..loop_count - 1
-    clear canvas to ANIM.background_color or application defined color
-    until eof or non-ANMF chunk
-        frame_params.frameX = Frame X
-        frame_params.frameY = Frame Y
-        frame_params.frameWidth = Frame Width Minus One + 1
-        frame_params.frameHeight = Frame Height Minus One + 1
-        frame_params.frameDuration = Frame Duration
-        frame_right = frame_params.frameX + frame_params.frameWidth
-        frame_bottom = frame_params.frameY + frame_params.frameHeight
-        assert VP8X.canvasWidth >= frame_right
-        assert VP8X.canvasHeight >= frame_bottom
-        for subchunk in 'Frame Data':
-            if subchunk.tag == "ALPH":
-                assert alpha subchunks not found in 'Frame Data' earlier
-                frame_params.alpha = alpha_data
-            else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
-                assert bitstream subchunks not found in 'Frame Data' earlier
-                frame_params.bitstream = bitstream_data
-        render frame with frame_params.alpha and frame_params.bitstream on
-            canvas with top-left corner at (frame_params.frameX,
-            frame_params.frameY), using dispose method dispose_method.
-        canvas contains the decoded image.
-        Show the contents of the canvas for frame_params.frameDuration * 1ms.
+  clear canvas to ANIM.background_color or application defined color
+  until eof or non-ANMF chunk
+    frame_params.frameX = Frame X
+    frame_params.frameY = Frame Y
+    frame_params.frameWidth = Frame Width Minus One + 1
+    frame_params.frameHeight = Frame Height Minus One + 1
+    frame_params.frameDuration = Frame Duration
+    frame_right = frame_params.frameX + frame_params.frameWidth
+    frame_bottom = frame_params.frameY + frame_params.frameHeight
+    assert VP8X.canvasWidth >= frame_right
+    assert VP8X.canvasHeight >= frame_bottom
+    for subchunk in 'Frame Data':
+      if subchunk.tag == "ALPH":
+        assert alpha subchunks not found in 'Frame Data' earlier
+        frame_params.alpha = alpha_data
+      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
+        assert bitstream subchunks not found in 'Frame Data' earlier
+        frame_params.bitstream = bitstream_data
+    render frame with frame_params.alpha and frame_params.bitstream
+      on canvas with top-left corner at (frame_params.frameX,
+      frame_params.frameY), using blending method
+      frame_params.blendingMethod.
+    canvas contains the decoded image.
+    Show the contents of the canvas for
+    frame_params.frameDuration * 1ms.
+    dispose_method = frame_params.disposeMethod
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
@@ -802,7 +846,7 @@
 +- XMP  (metadata)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-An animated image with EXIF metadata may look as follows:
+An animated image with Exif metadata may look as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 RIFF/WEBP
@@ -815,9 +859,10 @@
 +- EXIF (metadata)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-[vp8spec]:  http://tools.ietf.org/html/rfc6386
-[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
-[iccspec]: http://www.color.org/icc_specs2.xalter
-[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
-[rfc 1166]: http://tools.ietf.org/html/rfc1166
-[rfc 2119]: http://tools.ietf.org/html/rfc2119
+[vp8spec]:  https://datatracker.ietf.org/doc/html/rfc6386
+[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
+[iccspec]: https://www.color.org/icc_specs2.xalter
+[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
+[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
+[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
+[rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174
diff --git a/third_party/libwebp/doc/webp-lossless-bitstream-spec.txt b/third_party/libwebp/doc/webp-lossless-bitstream-spec.txt
index 2d2dde1..ebaf655 100644
--- a/third_party/libwebp/doc/webp-lossless-bitstream-spec.txt
+++ b/third_party/libwebp/doc/webp-lossless-bitstream-spec.txt
@@ -1,113 +1,52 @@
 <!--
 
-Although you may be viewing an alternate representation, this document
-is sourced in Markdown, a light-duty markup scheme, and is optimized for
-the [kramdown](http://kramdown.rubyforge.org/) transformer.
+Although you may be viewing an alternate representation, this document is
+sourced in Markdown, a light-duty markup scheme, and is optimized for the
+[kramdown](https://kramdown.gettalong.org/) transformer.
 
-See the accompanying README. External link targets are referenced at the
-end of this file.
+See the accompanying specs_generation.md. External link targets are referenced
+at the end of this file.
 
 -->
 
 Specification for WebP Lossless Bitstream
 =========================================
 
-_Jyrki Alakuijala, Ph.D., Google, Inc., 2012-06-19_
-
-Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
+_Jyrki Alakuijala, Ph.D., Google, Inc., 2023-03-09_
 
 Abstract
 --------
 
-WebP lossless is an image format for lossless compression of ARGB
-images. The lossless format stores and restores the pixel values
-exactly, including the color values for zero alpha pixels. The
-format uses subresolution images, recursively embedded into the format
-itself, for storing statistical data about the images, such as the used
-entropy codes, spatial predictors, color space conversion, and color
-table. LZ77, Huffman coding, and a color cache are used for compression
-of the bulk data. Decoding speeds faster than PNG have been
-demonstrated, as well as 25% denser compression than can be achieved
-using today's PNG format.
+WebP lossless is an image format for lossless compression of ARGB images. The
+lossless format stores and restores the pixel values exactly, including the
+color values for pixels whose alpha value is 0. The format uses subresolution
+images, recursively embedded into the format itself, for storing statistical
+data about the images, such as the used entropy codes, spatial predictors, color
+space conversion, and color table. LZ77, prefix coding, and a color cache are
+used for compression of the bulk data. Decoding speeds faster than PNG have been
+demonstrated, as well as 25% denser compression than can be achieved using
+today's PNG format.
 
 
 * TOC placeholder
 {:toc}
 
 
-Nomenclature
-------------
-
-ARGB
-: A pixel value consisting of alpha, red, green, and blue values.
-
-ARGB image
-: A two-dimensional array containing ARGB pixels.
-
-color cache
-: A small hash-addressed array to store recently used colors, to be able
-  to recall them with shorter codes.
-
-color indexing image
-: A one-dimensional image of colors that can be indexed using a small
-  integer (up to 256 within WebP lossless).
-
-color transform image
-: A two-dimensional subresolution image containing data about
-  correlations of color components.
-
-distance mapping
-: Changes LZ77 distances to have the smallest values for pixels in 2D
-  proximity.
-
-entropy image
-: A two-dimensional subresolution image indicating which entropy coding
-  should be used in a respective square in the image, i.e., each pixel
-  is a meta Huffman code.
-
-Huffman code
-: A classic way to do entropy coding where a smaller number of bits are
-  used for more frequent codes.
-
-LZ77
-: Dictionary-based sliding window compression algorithm that either
-  emits symbols or describes them as sequences of past symbols.
-
-meta Huffman code
-: A small integer (up to 16 bits) that indexes an element in the meta
-  Huffman table.
-
-predictor image
-: A two-dimensional subresolution image indicating which spatial
-  predictor is used for a particular square in the image.
-
-prefix coding
-: A way to entropy code larger integers that codes a few bits of the
-  integer using an entropy code and codifies the remaining bits raw.
-  This allows for the descriptions of the entropy codes to remain
-  relatively small even when the range of symbols is large.
-
-scan-line order
-: A processing order of pixels, left-to-right, top-to-bottom, starting
-  from the left-hand-top pixel, proceeding to the right. Once a row is
-  completed, continue from the left-hand column of the next row.
-
-
 1 Introduction
 --------------
 
-This document describes the compressed data representation of a WebP
-lossless image. It is intended as a detailed reference for WebP lossless
-encoder and decoder implementation.
+This document describes the compressed data representation of a WebP lossless
+image. It is intended as a detailed reference for the WebP lossless encoder and
+decoder implementation.
 
-In this document, we extensively use C programming language syntax to
-describe the bitstream, and assume the existence of a function for
-reading bits, `ReadBits(n)`. The bytes are read in the natural order of
-the stream containing them, and bits of each byte are read in
-least-significant-bit-first order. When multiple bits are read at the
-same time, the integer is constructed from the original data in the
-original order. The most significant bits of the returned integer are
-also the most significant bits of the original data. Thus the statement
+In this document, we extensively use C programming language syntax to describe
+the bitstream, and assume the existence of a function for reading bits,
+`ReadBits(n)`. The bytes are read in the natural order of the stream containing
+them, and bits of each byte are read in least-significant-bit-first order. When
+multiple bits are read at the same time, the integer is constructed from the
+original data in the original order. The most significant bits of the returned
+integer are also the most significant bits of the original data. Thus, the
+statement
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 b = ReadBits(2);
@@ -120,24 +59,79 @@
 b |= ReadBits(1) << 1;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-We assume that each color component (e.g. alpha, red, blue and green) is
-represented using an 8-bit byte. We define the corresponding type as
-uint8. A whole ARGB pixel is represented by a type called uint32, an
-unsigned integer consisting of 32 bits. In the code showing the behavior
-of the transformations, alpha value is codified in bits 31..24, red in
-bits 23..16, green in bits 15..8 and blue in bits 7..0, but
-implementations of the format are free to use another representation
-internally.
+We assume that each color component, that is, alpha, red, blue and green, is
+represented using an 8-bit byte. We define the corresponding type as uint8. A
+whole ARGB pixel is represented by a type called uint32, an unsigned integer
+consisting of 32 bits. In the code showing the behavior of the transformations,
+alpha value is codified in bits 31..24, red in bits 23..16, green in bits 15..8
+and blue in bits 7..0, but implementations of the format are free to use another
+representation internally.
 
-Broadly, a WebP lossless image contains header data, transform
-information and actual image data. Headers contain width and height of
-the image. A WebP lossless image can go through four different types of
-transformation before being entropy encoded. The transform information
-in the bitstream contains the data required to apply the respective
-inverse transforms.
+Broadly, a WebP lossless image contains header data, transform information and
+actual image data. Headers contain width and height of the image. A WebP
+lossless image can go through four different types of transformation before
+being entropy encoded. The transform information in the bitstream contains the
+data required to apply the respective inverse transforms.
 
 
-2 RIFF Header
+2 Nomenclature
+--------------
+
+ARGB
+:   A pixel value consisting of alpha, red, green, and blue values.
+
+ARGB image
+:   A two-dimensional array containing ARGB pixels.
+
+color cache
+:   A small hash-addressed array to store recently used colors, to be able to
+    recall them with shorter codes.
+
+color indexing image
+:   A one-dimensional image of colors that can be indexed using a small integer
+    (up to 256 within WebP lossless).
+
+color transform image
+:   A two-dimensional subresolution image containing data about correlations of
+    color components.
+
+distance mapping
+:   Changes LZ77 distances to have the smallest values for pixels in 2D
+    proximity.
+
+entropy image
+:   A two-dimensional subresolution image indicating which entropy coding should
+    be used in a respective square in the image, that is, each pixel is a meta
+    prefix code.
+
+prefix code
+:   A classic way to do entropy coding where a smaller number of bits are used
+    for more frequent codes.
+
+LZ77
+:   Dictionary-based sliding window compression algorithm that either emits
+    symbols or describes them as sequences of past symbols.
+
+meta prefix code
+:   A small integer (up to 16 bits) that indexes an element in the meta prefix
+    table.
+
+predictor image
+:   A two-dimensional subresolution image indicating which spatial predictor is
+    used for a particular square in the image.
+
+prefix coding
+:   A way to entropy code larger integers that codes a few bits of the integer
+    using an entropy code and codifies the remaining bits raw. This allows for
+    the descriptions of the entropy codes to remain relatively small even when
+    the range of symbols is large.
+
+scan-line order
+:   A processing order of pixels, left-to-right, top-to-bottom, starting from
+    the left-hand-top pixel, proceeding to the right. Once a row is completed,
+    continue from the left-hand column of the next row.
+
+3 RIFF Header
 -------------
 
 The beginning of the header has the RIFF container. This consists of the
@@ -154,49 +148,47 @@
       lossless stream.
    6. One byte signature 0x2f.
 
-The first 28 bits of the bitstream specify the width and height of the
-image. Width and height are decoded as 14-bit integers as follows:
+The first 28 bits of the bitstream specify the width and height of the image.
+Width and height are decoded as 14-bit integers as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int image_width = ReadBits(14) + 1;
 int image_height = ReadBits(14) + 1;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The 14-bit dynamics for image size limit the maximum size of a WebP
-lossless image to 16384✕16384 pixels.
+The 14-bit precision for image width and height limits the maximum size of a
+WebP lossless image to 16384✕16384 pixels.
 
-The alpha_is_used bit is a hint only, and should not impact decoding.
-It should be set to 0 when all alpha values are 255 in the picture, and
-1 otherwise.
+The alpha_is_used bit is a hint only, and should not impact decoding. It should
+be set to 0 when all alpha values are 255 in the picture, and 1 otherwise.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int alpha_is_used = ReadBits(1);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The version_number is a 3 bit code that must be set to 0. Any other value
-should be treated as an error. \[AMENDED\]
+The version_number is a 3 bit code that must be set to 0. Any other value should
+be treated as an error.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int version_number = ReadBits(3);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-3 Transformations
+4 Transformations
 -----------------
 
-Transformations are reversible manipulations of the image data that can
-reduce the remaining symbolic entropy by modeling spatial and color
-correlations. Transformations can make the final compression more dense.
+Transformations are reversible manipulations of the image data that can reduce
+the remaining symbolic entropy by modeling spatial and color correlations.
+Transformations can make the final compression more dense.
 
-An image can go through four types of transformation. A 1 bit indicates
-the presence of a transform. Each transform is allowed to be used only
-once. The transformations are used only for the main level ARGB image:
-the subresolution images have no transforms, not even the 0 bit
-indicating the end-of-transforms.
+An image can go through four types of transformation. A 1 bit indicates the
+presence of a transform. Each transform is allowed to be used only once. The
+transformations are used only for the main level ARGB image: the subresolution
+images have no transforms, not even the 0 bit indicating the end-of-transforms.
 
-Typically an encoder would use these transforms to reduce the Shannon
-entropy in the residual image. Also, the transform data can be decided
-based on entropy minimization.
+Typically, an encoder would use these transforms to reduce the Shannon entropy
+in the residual image. Also, the transform data can be decided based on entropy
+minimization.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 while (ReadBits(1)) {  // Transform present.
@@ -209,66 +201,62 @@
 // Decode actual image data (Section 4).
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If a transform is present then the next two bits specify the transform
-type. There are four types of transforms.
+If a transform is present then the next two bits specify the transform type.
+There are four types of transforms.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 enum TransformType {
   PREDICTOR_TRANSFORM             = 0,
   COLOR_TRANSFORM                 = 1,
-  SUBTRACT_GREEN                  = 2,
+  SUBTRACT_GREEN_TRANSFORM        = 2,
   COLOR_INDEXING_TRANSFORM        = 3,
 };
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The transform type is followed by the transform data. Transform data
-contains the information required to apply the inverse transform and
-depends on the transform type. Next we describe the transform data for
-different types.
+The transform type is followed by the transform data. Transform data contains
+the information required to apply the inverse transform and depends on the
+transform type. Next we describe the transform data for different types.
 
 
-### Predictor Transform
+### 4.1 Predictor Transform
 
-The predictor transform can be used to reduce entropy by exploiting the
-fact that neighboring pixels are often correlated. In the predictor
-transform, the current pixel value is predicted from the pixels already
-decoded (in scan-line order) and only the residual value (actual -
-predicted) is encoded. The _prediction mode_ determines the type of
-prediction to use. We divide the image into squares and all the pixels
-in a square use same prediction mode.
+The predictor transform can be used to reduce entropy by exploiting the fact
+that neighboring pixels are often correlated. In the predictor transform, the
+current pixel value is predicted from the pixels already decoded (in scan-line
+order) and only the residual value (actual - predicted) is encoded. The
+_prediction mode_ determines the type of prediction to use. We divide the image
+into squares and all the pixels in a square use the same prediction mode.
 
-The first 3 bits of prediction data define the block width and height in
-number of bits. The number of block columns, `block_xsize`, is used in
-indexing two-dimensionally.
+The first 3 bits of prediction data define the block width and height in number
+of bits. The number of block columns, `block_xsize`, is used in indexing
+two-dimensionally.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int size_bits = ReadBits(3) + 2;
 int block_width = (1 << size_bits);
 int block_height = (1 << size_bits);
-#define DIV_ROUND_UP(num, den) ((num) + (den) - 1) / (den))
+#define DIV_ROUND_UP(num, den) (((num) + (den) - 1) / (den))
 int block_xsize = DIV_ROUND_UP(image_width, 1 << size_bits);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The transform data contains the prediction mode for each block of the
-image. All the `block_width * block_height` pixels of a block use same
-prediction mode. The prediction modes are treated as pixels of an image
-and encoded using the same techniques described in
-[Chapter 4](#image-data).
+The transform data contains the prediction mode for each block of the image. All
+the `block_width * block_height` pixels of a block use same prediction mode. The
+prediction modes are treated as pixels of an image and encoded using the same
+techniques described in [Chapter 5](#image-data).
 
-For a pixel _x, y_, one can compute the respective filter block address
-by:
+For a pixel _x, y_, one can compute the respective filter block address by:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int block_index = (y >> size_bits) * block_xsize +
                   (x >> size_bits);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-There are 14 different prediction modes. In each prediction mode, the
-current pixel value is predicted from one or more neighboring pixels
-whose values are already known.
+There are 14 different prediction modes. In each prediction mode, the current
+pixel value is predicted from one or more neighboring pixels whose values are
+already known.
 
-We choose the neighboring pixels (TL, T, TR, and L) of the current pixel
-(P) as follows:
+We choose the neighboring pixels (TL, T, TR, and L) of the current pixel (P) as
+follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 O    O    O    O    O    O    O    O    O    O    O
@@ -279,12 +267,12 @@
 X    X    X    X    X    X    X    X    X    X    X
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-where TL means top-left, T top, TR top-right, L left pixel.
-At the time of predicting a value for P, all pixels O, TL, T, TR and L
-have been already processed, and pixel P and all pixels X are unknown.
+where TL means top-left, T top, TR top-right, L left pixel. At the time of
+predicting a value for P, all pixels O, TL, T, TR and L have already been
+processed, and pixel P and all pixels X are unknown.
 
-Given the above neighboring pixels, the different prediction modes are
-defined as follows.
+Given the above neighboring pixels, the different prediction modes are defined
+as follows.
 
 | Mode   | Predicted value of each channel of the current pixel    |
 | ------ | ------------------------------------------------------- |
@@ -331,7 +319,7 @@
            abs(pGreen - GREEN(T)) + abs(pBlue - BLUE(T));
 
   // Return either left or top, the one closer to the prediction.
-  if (pL < pT) {     // \[AMENDED\]
+  if (pL < pT) {
     return L;
   } else {
     return T;
@@ -339,8 +327,8 @@
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The functions `ClampAddSubtractFull` and `ClampAddSubtractHalf` are
-performed for each ARGB component as follows:
+The functions `ClampAddSubtractFull` and `ClampAddSubtractHalf` are performed
+for each ARGB component as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Clamp the input value between 0 and 255.
@@ -362,28 +350,26 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 There are special handling rules for some border pixels. If there is a
-prediction transform, regardless of the mode \[0..13\] for these pixels,
-the predicted value for the left-topmost pixel of the image is
-0xff000000, L-pixel for all pixels on the top row, and T-pixel for all
-pixels on the leftmost column.
+prediction transform, regardless of the mode \[0..13\] for these pixels, the
+predicted value for the left-topmost pixel of the image is 0xff000000, L-pixel
+for all pixels on the top row, and T-pixel for all pixels on the leftmost
+column.
 
 Addressing the TR-pixel for pixels on the rightmost column is
-exceptional. The pixels on the rightmost column are predicted by using
-the modes \[0..13\] just like pixels not on border, but by using the
-leftmost pixel on the same row as the current TR-pixel. The TR-pixel
-offset in memory is the same for border and non-border pixels.
+exceptional. The pixels on the rightmost column are predicted by using the modes
+\[0..13\] just like pixels not on the border, but the leftmost pixel on the same
+row as the current pixel is instead used as the TR-pixel.
 
 
-### Color Transform
+### 4.2 Color Transform
 
-The goal of the color transform is to decorrelate the R, G and B values
-of each pixel. Color transform keeps the green (G) value as it is,
-transforms red (R) based on green and transforms blue (B) based on green
-and then based on red.
+The goal of the color transform is to decorrelate the R, G and B values of each
+pixel. The color transform keeps the green (G) value as it is, transforms red
+(R) based on green and transforms blue (B) based on green and then based on red.
 
-As is the case for the predictor transform, first the image is divided
-into blocks and the same transform mode is used for all the pixels in a
-block. For each block there are three types of color transform elements.
+As is the case for the predictor transform, first the image is divided into
+blocks and the same transform mode is used for all the pixels in a block. For
+each block there are three types of color transform elements.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 typedef struct {
@@ -393,11 +379,10 @@
 } ColorTransformElement;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The actual color transformation is done by defining a color transform
-delta. The color transform delta depends on the `ColorTransformElement`,
-which is the same for all the pixels in a particular block. The delta is
-added during color transform. The inverse color transform then is just
-subtracting those deltas.
+The actual color transformation is done by defining a color transform delta. The
+color transform delta depends on the `ColorTransformElement`, which is the same
+for all the pixels in a particular block. The delta is subtracted during the
+color transform. The inverse color transform then is just adding those deltas.
 
 The color transform function is defined as follows:
 
@@ -406,22 +391,22 @@
                     ColorTransformElement *trans,
                     uint8 *new_red, uint8 *new_blue) {
   // Transformed values of red and blue components
-  uint32 tmp_red = red;
-  uint32 tmp_blue = blue;
+  int tmp_red = red;
+  int tmp_blue = blue;
 
-  // Applying transform is just adding the transform deltas
-  tmp_red  += ColorTransformDelta(trans->green_to_red, green);
-  tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
-  tmp_blue += ColorTransformDelta(trans->red_to_blue, red);
+  // Applying the transform is just subtracting the transform deltas
+  tmp_red  -= ColorTransformDelta(trans->green_to_red_,  green);
+  tmp_blue -= ColorTransformDelta(trans->green_to_blue_, green);
+  tmp_blue -= ColorTransformDelta(trans->red_to_blue_, red);
 
   *new_red = tmp_red & 0xff;
   *new_blue = tmp_blue & 0xff;
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-`ColorTransformDelta` is computed using a signed 8-bit integer
-representing a 3.5-fixed-point number, and a signed 8-bit RGB color
-channel (c) \[-128..127\] and is defined as follows:
+`ColorTransformDelta` is computed using a signed 8-bit integer representing a
+3.5-fixed-point number, and a signed 8-bit RGB color channel (c) \[-128..127\]
+and is defined as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int8 ColorTransformDelta(int8 t, int8 c) {
@@ -429,22 +414,20 @@
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A conversion from the 8-bit unsigned representation (uint8) to the 8-bit
-signed one (int8) is required before calling ColorTransformDelta().
-It should be performed using 8-bit two's complement (that is: uint8 range
-\[128-255\] is mapped to the \[-128, -1\] range of its converted int8 value).
+A conversion from the 8-bit unsigned representation (uint8) to the 8-bit signed
+one (int8) is required before calling `ColorTransformDelta()`. It should be
+performed using 8-bit two's complement (that is: uint8 range \[128..255\] is
+mapped to the \[-128..-1\] range of its converted int8 value).
 
-The multiplication is to be done using more precision (with at least
-16-bit dynamics). The sign extension property of the shift operation
-does not matter here: only the lowest 8 bits are used from the result,
-and there the sign extension shifting and unsigned shifting are
-consistent with each other.
+The multiplication is to be done using more precision (with at least 16-bit
+precision). The sign extension property of the shift operation does not matter
+here: only the lowest 8 bits are used from the result, and there the sign
+extension shifting and unsigned shifting are consistent with each other.
 
-Now we describe the contents of color transform data so that decoding
-can apply the inverse color transform and recover the original red and
-blue values. The first 3 bits of the color transform data contain the
-width and height of the image block in number of bits, just like the
-predictor transform:
+Now we describe the contents of color transform data so that decoding can apply
+the inverse color transform and recover the original red and blue values. The
+first 3 bits of the color transform data contain the width and height of the
+image block in number of bits, just like the predictor transform:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int size_bits = ReadBits(3) + 2;
@@ -452,41 +435,43 @@
 int block_height = 1 << size_bits;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The remaining part of the color transform data contains
-`ColorTransformElement` instances corresponding to each block of the
-image. `ColorTransformElement` instances are treated as pixels of an
-image and encoded using the methods described in
-[Chapter 4](#image-data).
+The remaining part of the color transform data contains `ColorTransformElement`
+instances corresponding to each block of the image. `ColorTransformElement`
+instances are treated as pixels of an image and encoded using the methods
+described in [Chapter 5](#image-data).
 
-During decoding, `ColorTransformElement` instances of the blocks are
-decoded and the inverse color transform is applied on the ARGB values of
-the pixels. As mentioned earlier, that inverse color transform is just
-subtracting `ColorTransformElement` values from the red and blue
-channels.
+During decoding, `ColorTransformElement` instances of the blocks are decoded and
+the inverse color transform is applied on the ARGB values of the pixels. As
+mentioned earlier, that inverse color transform is just adding
+`ColorTransformElement` values to the red and blue channels.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 void InverseTransform(uint8 red, uint8 green, uint8 blue,
-                      ColorTransformElement *p,
+                      ColorTransformElement *trans,
                       uint8 *new_red, uint8 *new_blue) {
-  // Applying inverse transform is just subtracting the
-  // color transform deltas
-  red  -= ColorTransformDelta(p->green_to_red_,  green);
-  blue -= ColorTransformDelta(p->green_to_blue_, green);
-  blue -= ColorTransformDelta(p->red_to_blue_, red & 0xff);
+  // Transformed values of red and blue components
+  int tmp_red = red;
+  int tmp_blue = blue;
 
-  *new_red = red & 0xff;
-  *new_blue = blue & 0xff;
+  // Applying the inverse transform is just adding the
+  // color transform deltas
+  tmp_red  += ColorTransformDelta(trans->green_to_red, green);
+  tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
+  tmp_blue +=
+      ColorTransformDelta(trans->red_to_blue, tmp_red & 0xff);
+
+  *new_red = tmp_red & 0xff;
+  *new_blue = tmp_blue & 0xff;
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-### Subtract Green Transform
+### 4.3 Subtract Green Transform
 
-The subtract green transform subtracts green values from red and blue
-values of each pixel. When this transform is present, the decoder needs
-to add the green value to both red and blue. There is no data associated
-with this transform. The decoder applies the inverse transform as
-follows:
+The subtract green transform subtracts green values from red and blue values of
+each pixel. When this transform is present, the decoder needs to add the green
+value to both red and blue. There is no data associated with this transform. The
+decoder applies the inverse transform as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) {
@@ -495,71 +480,63 @@
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-This transform is redundant as it can be modeled using the color
-transform, but it is still often useful. Since it can extend the
-dynamics of the color transform and there is no additional data here,
-the subtract green transform can be coded using fewer bits than a
-full-blown color transform.
+This transform is redundant as it can be modeled using the color transform, but
+since there is no additional data here, the subtract green transform can be
+coded using fewer bits than a full-blown color transform.
 
 
-### Color Indexing Transform
+### 4.4 Color Indexing Transform
 
-If there are not many unique pixel values, it may be more efficient to
-create a color index array and replace the pixel values by the array's
-indices. The color indexing transform achieves this. (In the context of
-WebP lossless, we specifically do not call this a palette transform
-because a similar but more dynamic concept exists in WebP lossless
-encoding: color cache.)
+If there are not many unique pixel values, it may be more efficient to create a
+color index array and replace the pixel values by the array's indices. The color
+indexing transform achieves this. (In the context of WebP lossless, we
+specifically do not call this a palette transform because a similar but more
+dynamic concept exists in WebP lossless encoding: color cache).
 
-The color indexing transform checks for the number of unique ARGB values
-in the image. If that number is below a threshold (256), it creates an
-array of those ARGB values, which is then used to replace the pixel
-values with the corresponding index: the green channel of the pixels are
-replaced with the index; all alpha values are set to 255; all red and
-blue values to 0.
+The color indexing transform checks for the number of unique ARGB values in the
+image. If that number is below a threshold (256), it creates an array of those
+ARGB values, which is then used to replace the pixel values with the
+corresponding index: the green channel of the pixels are replaced with the
+index; all alpha values are set to 255; all red and blue values to 0.
 
-The transform data contains color table size and the entries in the
-color table. The decoder reads the color indexing transform data as
-follows:
+The transform data contains color table size and the entries in the color table.
+The decoder reads the color indexing transform data as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // 8 bit value for color table size
 int color_table_size = ReadBits(8) + 1;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The color table is stored using the image storage format itself. The
-color table can be obtained by reading an image, without the RIFF
-header, image size, and transforms, assuming a height of one pixel and
-a width of `color_table_size`. The color table is always
-subtraction-coded to reduce image entropy. The deltas of palette colors
-contain typically much less entropy than the colors themselves, leading
-to significant savings for smaller images. In decoding, every final
-color in the color table can be obtained by adding the previous color
-component values by each ARGB component separately, and storing the
-least significant 8 bits of the result.
+The color table is stored using the image storage format itself. The color table
+can be obtained by reading an image, without the RIFF header, image size, and
+transforms, assuming a height of one pixel and a width of `color_table_size`.
+The color table is always subtraction-coded to reduce image entropy. The deltas
+of palette colors contain typically much less entropy than the colors
+themselves, leading to significant savings for smaller images. In decoding,
+every final color in the color table can be obtained by adding the previous
+color component values by each ARGB component separately, and storing the least
+significant 8 bits of the result.
 
-The inverse transform for the image is simply replacing the pixel values
-(which are indices to the color table) with the actual color table
-values. The indexing is done based on the green component of the ARGB
-color.
+The inverse transform for the image is simply replacing the pixel values (which
+are indices to the color table) with the actual color table values. The indexing
+is done based on the green component of the ARGB color.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Inverse transform
 argb = color_table[GREEN(argb)];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If the index is equal or larger than color_table_size, the argb color value
-should be set to 0x00000000 (transparent black).  \[AMENDED\]
+If the index is equal or larger than `color_table_size`, the argb color value
+should be set to 0x00000000 (transparent black).
 
-When the color table is small (equal to or less than 16 colors), several
-pixels are bundled into a single pixel. The pixel bundling packs several
-(2, 4, or 8) pixels into a single pixel, reducing the image width
-respectively. Pixel bundling allows for a more efficient joint
-distribution entropy coding of neighboring pixels, and gives some
-arithmetic coding-like benefits to the entropy code, but it can only be
-used when there are a small number of unique values.
+When the color table is small (equal to or less than 16 colors), several pixels
+are bundled into a single pixel. The pixel bundling packs several (2, 4, or 8)
+pixels into a single pixel, reducing the image width respectively. Pixel
+bundling allows for a more efficient joint distribution entropy coding of
+neighboring pixels, and gives some arithmetic coding-like benefits to the
+entropy code, but it can only be used when there are 16 or fewer unique values.
 
-`color_table_size` specifies how many pixels are combined together:
+`color_table_size` specifies how many pixels are combined:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int width_bits;
@@ -574,13 +551,12 @@
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-`width_bits` has a value of 0, 1, 2 or 3. A value of 0 indicates no
-pixel bundling to be done for the image. A value of 1 indicates that two
-pixels are combined together, and each pixel has a range of \[0..15\]. A
-value of 2 indicates that four pixels are combined together, and each
-pixel has a range of \[0..3\]. A value of 3 indicates that eight pixels
-are combined together and each pixel has a range of \[0..1\], i.e., a
-binary value.
+`width_bits` has a value of 0, 1, 2 or 3. A value of 0 indicates no pixel
+bundling is to be done for the image. A value of 1 indicates that two pixels are
+combined, and each pixel has a range of \[0..15\]. A value of 2 indicates that
+four pixels are combined, and each pixel has a range of \[0..3\]. A value of 3
+indicates that eight pixels are combined and each pixel has a range of \[0..1\],
+that is, a binary value.
 
 The values are packed into the green component as follows:
 
@@ -590,43 +566,43 @@
     4 most-significant bits of the green value at x / 2.
   * `width_bits` = 2: for every x value where x ≡ 0 (mod 4), a green
     value at x is positioned into the 2 least-significant bits of the
-    green value at x / 4, green values at x + 1 to x + 3 in order to the
-    more significant bits of the green value at x / 4.
+    green value at x / 4, green values at x + 1 to x + 3 are positioned in order
+    to the more significant bits of the green value at x / 4.
   * `width_bits` = 3: for every x value where x ≡ 0 (mod 8), a green
     value at x is positioned into the least-significant bit of the green
-    value at x / 8, green values at x + 1 to x + 7 in order to the more
-    significant bits of the green value at x / 8.
+    value at x / 8, green values at x + 1 to x + 7 are positioned in order to
+    the more significant bits of the green value at x / 8.
 
 
-4 Image Data
+5 Image Data
 ------------
 
 Image data is an array of pixel values in scan-line order.
 
-### 4.1 Roles of Image Data
+### 5.1 Roles of Image Data
 
 We use image data in five different roles:
 
   1. ARGB image: Stores the actual pixels of the image.
   1. Entropy image: Stores the
-     [meta Huffman codes](#decoding-of-meta-huffman-codes). The red and green
-     components of a pixel define the meta Huffman code used in a particular
+     [meta prefix codes](#decoding-of-meta-prefix-codes). The red and green
+     components of a pixel define the meta prefix code used in a particular
      block of the ARGB image.
-  1. Predictor image: Stores the metadata for [Predictor
-     Transform](#predictor-transform). The green component of a pixel defines
-     which of the 14 predictors is used within a particular block of the
+  1. Predictor image: Stores the metadata for
+     [Predictor Transform](#predictor-transform). The green component of a pixel
+     defines which of the 14 predictors is used within a particular block of the
      ARGB image.
   1. Color transform image. It is created by `ColorTransformElement` values
      (defined in [Color Transform](#color-transform)) for different blocks of
      the image. Each `ColorTransformElement` `'cte'` is treated as a pixel whose
      alpha component is `255`, red component is `cte.red_to_blue`, green
      component is `cte.green_to_blue` and blue component is `cte.green_to_red`.
-  1. Color indexing image: An array of of size `color_table_size` (up to 256
+  1. Color indexing image: An array of size `color_table_size` (up to 256
      ARGB values) storing the metadata for the
      [Color Indexing Transform](#color-indexing-transform). This is stored as an
      image of width `color_table_size` and height `1`.
 
-### 4.2 Encoding of Image data
+### 5.2 Encoding of Image Data
 
 The encoding of image data is independent of its role.
 
@@ -643,21 +619,22 @@
 
 Each pixel is encoded using one of the three possible methods:
 
-  1. Huffman coded literal: each channel (green, red, blue and alpha) is
+  1. Prefix coded literal: each channel (green, red, blue and alpha) is
      entropy-coded independently;
   2. LZ77 backward reference: a sequence of pixels are copied from elsewhere
      in the image; or
   3. Color cache code: using a short multiplicative hash code (color cache
      index) of a recently seen color.
 
-The following sub-sections describe each of these in detail.
+The following subsections describe each of these in detail.
 
-#### 4.2.1 Huffman Coded Literals
+#### 5.2.1 Prefix Coded Literals
 
-The pixel is stored as Huffman coded values of green, red, blue and alpha (in
-that order). See [this section](#decoding-entropy-coded-image-data) for details.
+The pixel is stored as prefix coded values of green, red, blue and alpha (in
+that order). See [Section 6.2.3](#decoding-entropy-coded-image-data) for
+details.
 
-#### 4.2.2 LZ77 Backward Reference
+#### 5.2.2 LZ77 Backward Reference
 
 Backward references are tuples of _length_ and _distance code_:
 
@@ -674,11 +651,11 @@
 
 **Rationale**: This approach reduces the storage requirement for the entropy
 code. Also, large values are usually rare, and so extra bits would be used for
-very few values in the image. Thus, this approach results in a better
-compression overall.
+very few values in the image. Thus, this approach results in better compression
+overall.
 
 The following table denotes the prefix codes and extra bits used for storing
-different range of values.
+different ranges of values.
 
 Note: The maximum backward reference length is limited to 4096. Hence, only the
 first 24 prefix codes (with the respective extra bits) are meaningful for length
@@ -700,8 +677,8 @@
 | 524289..786432  | 38          | 18         |
 | 786433..1048576 | 39          | 18         |
 
-The pseudocode to obtain a (length or distance) value from the prefix code is
-as follows:
+The pseudocode to obtain a (length or distance) value from the prefix code is as
+follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 if (prefix_code < 4) {
@@ -715,13 +692,13 @@
 **Distance Mapping:**
 {:#distance-mapping}
 
-As noted previously, distance code is a number indicating the position of a
-previously seen pixel, from which the pixels are to be copied. This sub-section
+As noted previously, a distance code is a number indicating the position of a
+previously seen pixel, from which the pixels are to be copied. This subsection
 defines the mapping between a distance code and the position of a previous
 pixel.
 
-The distance codes larger than 120 denote the pixel-distance in scan-line
-order, offset by 120.
+Distance codes larger than 120 denote the pixel-distance in scan-line order,
+offset by 120.
 
 The smallest distance codes \[1..120\] are special, and are reserved for a close
 neighborhood of the current pixel. This neighborhood consists of 120 pixels:
@@ -736,54 +713,58 @@
 `(xi, yi)` is as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-(0, 1),  (1, 0),  (1, 1),  (-1, 1), (0, 2),  (2, 0),  (1, 2),  (-1, 2),
-(2, 1),  (-2, 1), (2, 2),  (-2, 2), (0, 3),  (3, 0),  (1, 3),  (-1, 3),
-(3, 1),  (-3, 1), (2, 3),  (-2, 3), (3, 2),  (-3, 2), (0, 4),  (4, 0),
-(1, 4),  (-1, 4), (4, 1),  (-4, 1), (3, 3),  (-3, 3), (2, 4),  (-2, 4),
-(4, 2),  (-4, 2), (0, 5),  (3, 4),  (-3, 4), (4, 3),  (-4, 3), (5, 0),
-(1, 5),  (-1, 5), (5, 1),  (-5, 1), (2, 5),  (-2, 5), (5, 2),  (-5, 2),
-(4, 4),  (-4, 4), (3, 5),  (-3, 5), (5, 3),  (-5, 3), (0, 6),  (6, 0),
-(1, 6),  (-1, 6), (6, 1),  (-6, 1), (2, 6),  (-2, 6), (6, 2),  (-6, 2),
-(4, 5),  (-4, 5), (5, 4),  (-5, 4), (3, 6),  (-3, 6), (6, 3),  (-6, 3),
-(0, 7),  (7, 0),  (1, 7),  (-1, 7), (5, 5),  (-5, 5), (7, 1),  (-7, 1),
-(4, 6),  (-4, 6), (6, 4),  (-6, 4), (2, 7),  (-2, 7), (7, 2),  (-7, 2),
-(3, 7),  (-3, 7), (7, 3),  (-7, 3), (5, 6),  (-5, 6), (6, 5),  (-6, 5),
-(8, 0),  (4, 7),  (-4, 7), (7, 4),  (-7, 4), (8, 1),  (8, 2),  (6, 6),
-(-6, 6), (8, 3),  (5, 7),  (-5, 7), (7, 5),  (-7, 5), (8, 4),  (6, 7),
-(-6, 7), (7, 6),  (-7, 6), (8, 5),  (7, 7),  (-7, 7), (8, 6),  (8, 7)
+(0, 1),  (1, 0),  (1, 1),  (-1, 1), (0, 2),  (2, 0),  (1, 2),
+(-1, 2), (2, 1),  (-2, 1), (2, 2),  (-2, 2), (0, 3),  (3, 0),
+(1, 3),  (-1, 3), (3, 1),  (-3, 1), (2, 3),  (-2, 3), (3, 2),
+(-3, 2), (0, 4),  (4, 0),  (1, 4),  (-1, 4), (4, 1),  (-4, 1),
+(3, 3),  (-3, 3), (2, 4),  (-2, 4), (4, 2),  (-4, 2), (0, 5),
+(3, 4),  (-3, 4), (4, 3),  (-4, 3), (5, 0),  (1, 5),  (-1, 5),
+(5, 1),  (-5, 1), (2, 5),  (-2, 5), (5, 2),  (-5, 2), (4, 4),
+(-4, 4), (3, 5),  (-3, 5), (5, 3),  (-5, 3), (0, 6),  (6, 0),
+(1, 6),  (-1, 6), (6, 1),  (-6, 1), (2, 6),  (-2, 6), (6, 2),
+(-6, 2), (4, 5),  (-4, 5), (5, 4),  (-5, 4), (3, 6),  (-3, 6),
+(6, 3),  (-6, 3), (0, 7),  (7, 0),  (1, 7),  (-1, 7), (5, 5),
+(-5, 5), (7, 1),  (-7, 1), (4, 6),  (-4, 6), (6, 4),  (-6, 4),
+(2, 7),  (-2, 7), (7, 2),  (-7, 2), (3, 7),  (-3, 7), (7, 3),
+(-7, 3), (5, 6),  (-5, 6), (6, 5),  (-6, 5), (8, 0),  (4, 7),
+(-4, 7), (7, 4),  (-7, 4), (8, 1),  (8, 2),  (6, 6),  (-6, 6),
+(8, 3),  (5, 7),  (-5, 7), (7, 5),  (-7, 5), (8, 4),  (6, 7),
+(-6, 7), (7, 6),  (-7, 6), (8, 5),  (7, 7),  (-7, 7), (8, 6),
+(8, 7)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-For example, distance code `1` indicates offset of `(0, 1)` for the neighboring
-pixel, that is, the pixel above the current pixel (0-pixel difference in
-X-direction and 1 pixel difference in Y-direction). Similarly, distance code
-`3` indicates left-top pixel.
+For example, the distance code `1` indicates an offset of `(0, 1)` for the
+neighboring pixel, that is, the pixel above the current pixel (0 pixel
+difference in the X-direction and 1 pixel difference in the Y-direction).
+Similarly, the distance code `3` indicates the left-top pixel.
 
-The decoder can convert a distances code 'i' to a scan-line order distance
-'dist' as follows:
+The decoder can convert a distance code `i` to a scan-line order distance `dist`
+as follows:
 
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-(xi, yi) = distance_map[i]
-dist = x + y * xsize
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(xi, yi) = distance_map[i - 1]
+dist = xi + yi * xsize
 if (dist < 1) {
   dist = 1
 }
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-where 'distance_map' is the mapping noted above and `xsize` is the width of the
+where `distance_map` is the mapping noted above and `xsize` is the width of the
 image in pixels.
 
 
-#### 4.2.3 Color Cache Coding
+#### 5.2.3 Color Cache Coding
+{:#color-cache-code}
 
 Color cache stores a set of colors that have been recently used in the image.
 
 **Rationale:** This way, the recently used colors can sometimes be referred to
-more efficiently than emitting them using other two methods (described in
-[4.2.1](#huffman-coded-literals) and [4.2.2](#lz77-backward-reference)).
+more efficiently than emitting them using the other two methods (described in
+[5.2.1](#prefix-coded-literals) and [5.2.2](#lz77-backward-reference)).
 
 Color cache codes are stored as follows. First, there is a 1-bit value that
 indicates if the color cache is used. If this bit is 0, no color cache codes
-exist, and they are not transmitted in the Huffman code that decodes the green
+exist, and they are not transmitted in the prefix code that decodes the green
 symbols and the length prefix codes. However, if this bit is 1, the color cache
 size is read next:
 
@@ -797,147 +778,270 @@
 `color_cache_code_bits` is \[1..11\]. Compliant decoders must indicate a
 corrupted bitstream for other values.
 
-A color cache is an array of size `color_cache_size`. Each entry
-stores one ARGB color. Colors are looked up by indexing them by
-(0x1e35a7bd * `color`) >> (32 - `color_cache_code_bits`). Only one
-lookup is done in a color cache; there is no conflict resolution.
+A color cache is an array of size `color_cache_size`. Each entry stores one ARGB
+color. Colors are looked up by indexing them by (0x1e35a7bd * `color`) >> (32 -
+`color_cache_code_bits`). Only one lookup is done in a color cache; there is no
+conflict resolution.
 
-In the beginning of decoding or encoding of an image, all entries in all
-color cache values are set to zero. The color cache code is converted to
-this color at decoding time. The state of the color cache is maintained
-by inserting every pixel, be it produced by backward referencing or as
-literals, into the cache in the order they appear in the stream.
+In the beginning of decoding or encoding of an image, all entries in all color
+cache values are set to zero. The color cache code is converted to this color at
+decoding time. The state of the color cache is maintained by inserting every
+pixel, be it produced by backward referencing or as literals, into the cache in
+the order they appear in the stream.
 
 
-5 Entropy Code
+6 Entropy Code
 --------------
 
-### 5.1 Overview
+### 6.1 Overview
 
-Most of the data is coded using [canonical Huffman code][canonical_huff]. Hence,
-the codes are transmitted by sending the _Huffman code lengths_, as opposed to
-the actual _Huffman codes_.
+Most of the data is coded using a [canonical prefix code][canonical_huff].
+Hence, the codes are transmitted by sending the _prefix code lengths_, as
+opposed to the actual _prefix codes_.
 
-In particular, the format uses **spatially-variant Huffman coding**. In other
+In particular, the format uses **spatially-variant prefix coding**. In other
 words, different blocks of the image can potentially use different entropy
 codes.
 
-**Rationale**: Different areas of the image may have different characteristics. So, allowing them to use different entropy codes provides more flexibility and
-potentially a better compression.
+**Rationale**: Different areas of the image may have different characteristics.
+So, allowing them to use different entropy codes provides more flexibility and
+potentially better compression.
 
-### 5.2 Details
+### 6.2 Details
 
-The encoded image data consists of two parts:
+The encoded image data consists of several parts:
 
-  1. Meta Huffman codes
+  1. Decoding and building the prefix codes
+  1. Meta prefix codes
   1. Entropy-coded image data
 
-#### 5.2.1 Decoding of Meta Huffman Codes
+#### 6.2.1 Decoding and Building the Prefix Codes
 
-As noted earlier, the format allows the use of different Huffman codes for
-different blocks of the image. _Meta Huffman codes_ are indexes identifying
-which Huffman codes to use in different parts of the image.
+There are several steps in decoding the prefix codes.
 
-Meta Huffman codes may be used _only_ when the image is being used in the
+**Decoding the Code Lengths:**
+{:#decoding-the-code-lengths}
+
+This section describes how to read the prefix code lengths from the bitstream.
+
+The prefix code lengths can be coded in two ways. The method used is specified
+by a 1-bit value.
+
+  * If this bit is 1, it is a _simple code length code_, and
+  * If this bit is 0, it is a _normal code length code_.
+
+In both cases, there can be unused code lengths that are still part of the
+stream. This may be inefficient, but it is allowed by the format.
+The described tree must be a complete binary tree. A single leaf node is
+considered a complete binary tree and can be encoded using either the simple
+code length code or the normal code length code. When coding a single leaf
+node using the _normal code length code_, all but one code length should be
+zeros, and the single leaf node value is marked with the length of 1 -- even
+when no bits are consumed when that single leaf node tree is used.
+
+**(i) Simple Code Length Code:**
+
+This variant is used in the special case when only 1 or 2 prefix symbols are in
+the range \[0..255\] with code length `1`. All other prefix code lengths are
+implicitly zeros.
+
+The first bit indicates the number of symbols:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int num_symbols = ReadBits(1) + 1;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Following are the symbol values.
+
+This first symbol is coded using 1 or 8 bits depending on the value of
+`is_first_8bits`. The range is \[0..1\] or \[0..255\], respectively. The second
+symbol, if present, is always assumed to be in the range \[0..255\] and coded
+using 8 bits.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int is_first_8bits = ReadBits(1);
+symbol0 = ReadBits(1 + 7 * is_first_8bits);
+code_lengths[symbol0] = 1;
+if (num_symbols == 2) {
+  symbol1 = ReadBits(8);
+  code_lengths[symbol1] = 1;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Note:** Another special case is when _all_ prefix code lengths are _zeros_ (an
+empty prefix code). For example, a prefix code for distance can be empty if
+there are no backward references. Similarly, prefix codes for alpha, red, and
+blue can be empty if all pixels within the same meta prefix code are produced
+using the color cache. However, this case doesn't need special handling, as
+empty prefix codes can be coded as those containing a single symbol `0`.
+
+**(ii) Normal Code Length Code:**
+
+The code lengths of the prefix code fit in 8 bits and are read as follows.
+First, `num_code_lengths` specifies the number of code lengths.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int num_code_lengths = 4 + ReadBits(4);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If `num_code_lengths` is > 19, the bitstream is invalid.
+
+The code lengths are themselves encoded using prefix codes: lower level code
+lengths, `code_length_code_lengths`, first have to be read. The rest of those
+`code_length_code_lengths` (according to the order in `kCodeLengthCodeOrder`)
+are zeros.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int kCodeLengthCodes = 19;
+int kCodeLengthCodeOrder[kCodeLengthCodes] = {
+  17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+int code_length_code_lengths[kCodeLengthCodes] = { 0 };  // All zeros
+for (i = 0; i < num_code_lengths; ++i) {
+  code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Next, if `ReadBits(1) == 0`, the maximum number of different read symbols is
+`num_code_lengths`. Otherwise, it is defined as:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int length_nbits = 2 + 2 * ReadBits(3);
+int max_symbol = 2 + ReadBits(length_nbits);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A prefix table is then built from `code_length_code_lengths` and used to read up
+to `max_symbol` code lengths.
+
+  * Code \[0..15\] indicates literal code lengths.
+    * Value 0 means no symbols have been coded.
+    * Values \[1..15\] indicate the bit length of the respective code.
+  * Code 16 repeats the previous non-zero value \[3..6\] times, that is,
+    `3 + ReadBits(2)` times. If code 16 is used before a non-zero
+    value has been emitted, a value of 8 is repeated.
+  * Code 17 emits a streak of zeros \[3..10\], that is, `3 + ReadBits(3)`
+    times.
+  * Code 18 emits a streak of zeros of length \[11..138\], that is,
+    `11 + ReadBits(7)` times.
+
+Once code lengths are read, a prefix code for each symbol type (A, R, G, B,
+distance) is formed using their respective alphabet sizes:
+
+  * G channel: 256 + 24 + `color_cache_size`
+  * other literals (A,R,B): 256
+  * distance code: 40
+
+The Normal Code Length Code must code a full decision tree, that is, the sum of
+`2 ^ (-length)` for all non-zero codes must be exactly one. There is however
+one exception to this rule, the single leaf node tree, where the leaf node
+value is marked with value 1 and other values are 0s.
+
+#### 6.2.2 Decoding of Meta Prefix Codes
+
+As noted earlier, the format allows the use of different prefix codes for
+different blocks of the image. _Meta prefix codes_ are indexes identifying which
+prefix codes to use in different parts of the image.
+
+Meta prefix codes may be used _only_ when the image is being used in the
 [role](#roles-of-image-data) of an _ARGB image_.
 
-There are two possibilities for the meta Huffman codes, indicated by a 1-bit
+There are two possibilities for the meta prefix codes, indicated by a 1-bit
 value:
 
-  * If this bit is zero, there is only one meta Huffman code used everywhere in
+  * If this bit is zero, there is only one meta prefix code used everywhere in
     the image. No more data is stored.
-  * If this bit is one, the image uses multiple meta Huffman codes. These meta
-    Huffman codes are stored as an _entropy image_ (described below).
+  * If this bit is one, the image uses multiple meta prefix codes. These meta
+    prefix codes are stored as an _entropy image_ (described below).
 
 **Entropy image:**
 
-The entropy image defines which Huffman codes are used in different parts of the
+The entropy image defines which prefix codes are used in different parts of the
 image, as described below.
 
-The first 3-bits contain the `huffman_bits` value. The dimensions of the entropy
-image are derived from 'huffman_bits'.
+The first 3-bits contain the `prefix_bits` value. The dimensions of the entropy
+image are derived from `prefix_bits`.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int huffman_bits = ReadBits(3) + 2;
-int huffman_xsize = DIV_ROUND_UP(xsize, 1 << huffman_bits);
-int huffman_ysize = DIV_ROUND_UP(ysize, 1 << huffman_bits);
+int prefix_bits = ReadBits(3) + 2;
+int prefix_xsize = DIV_ROUND_UP(xsize, 1 << prefix_bits);
+int prefix_ysize = DIV_ROUND_UP(ysize, 1 << prefix_bits);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 where `DIV_ROUND_UP` is as defined [earlier](#predictor-transform).
 
-Next bits contain an entropy image of width `huffman_xsize` and height
-`huffman_ysize`.
+The next bits contain an entropy image of width `prefix_xsize` and height
+`prefix_ysize`.
 
-**Interpretation of Meta Huffman Codes:**
+**Interpretation of Meta Prefix Codes:**
 
-For any given pixel (x, y), there is a set of five Huffman codes associated with
+For any given pixel (x, y), there is a set of five prefix codes associated with
 it. These codes are (in bitstream order):
 
-  * **Huffman code #1**: used for green channel, backward-reference length and
-    color cache
-  * **Huffman code #2, #3 and #4**: used for red, blue and alpha channels
+  * **Prefix code #1**: used for green channel, backward-reference length and
+    color cache.
+  * **Prefix code #2, #3 and #4**: used for red, blue and alpha channels
     respectively.
-  * **Huffman code #5**: used for backward-reference distance.
+  * **Prefix code #5**: used for backward-reference distance.
 
-From here on, we refer to this set as a **Huffman code group**.
+From here on, we refer to this set as a **prefix code group**.
 
-The number of Huffman code groups in the ARGB image can be obtained by finding
-the _largest meta Huffman code_ from the entropy image:
+The number of prefix code groups in the ARGB image can be obtained by finding
+the _largest meta prefix code_ from the entropy image:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int num_huff_groups = max(entropy image) + 1;
+int num_prefix_groups = max(entropy image) + 1;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-where `max(entropy image)` indicates the largest Huffman code stored in the
+where `max(entropy image)` indicates the largest prefix code stored in the
 entropy image.
 
-As each Huffman code groups contains five Huffman codes, the total number of
-Huffman codes is:
+As each prefix code group contains five prefix codes, the total number of prefix
+codes is:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int num_huff_codes = 5 * num_huff_groups;
+int num_prefix_codes = 5 * num_prefix_groups;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Given a pixel (x, y) in the ARGB image, we can obtain the corresponding Huffman
+Given a pixel (x, y) in the ARGB image, we can obtain the corresponding prefix
 codes to be used as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int position = (y >> huffman_bits) * huffman_xsize + (x >> huffman_bits);
-int meta_huff_code = (entropy_image[pos] >> 8) & 0xffff;
-HuffmanCodeGroup huff_group = huffman_code_groups[meta_huff_code];
+int position =
+    (y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
+int meta_prefix_code = (entropy_image[position] >> 8) & 0xffff;
+PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-where, we have assumed the existence of `HuffmanCodeGroup` structure, which
-represents a set of five Huffman codes. Also, `huffman_code_groups` is an array
-of `HuffmanCodeGroup` (of size `num_huff_groups`).
+where, we have assumed the existence of `PrefixCodeGroup` structure, which
+represents a set of five prefix codes. Also, `prefix_code_groups` is an array of
+`PrefixCodeGroup` (of size `num_prefix_groups`).
 
-The decoder then uses Huffman code group `huff_group` to decode the pixel
+The decoder then uses prefix code group `prefix_group` to decode the pixel
 (x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
 
-#### 5.2.2 Decoding Entropy-coded Image Data
+#### 6.2.3 Decoding Entropy-Coded Image Data
 
 For the current position (x, y) in the image, the decoder first identifies the
-corresponding Huffman code group (as explained in the last section). Given the
-Huffman code group, the pixel is read and decoded as follows:
+corresponding prefix code group (as explained in the last section). Given the
+prefix code group, the pixel is read and decoded as follows:
 
-Read next symbol S from the bitstream using Huffman code #1. \[See
-[next section](#decoding-the-code-lengths) for details on decoding the Huffman
-code lengths\]. Note that S is any integer in the range `0` to
-`(256 + 24 + ` [`color_cache_size`](#color-cache-code)`- 1)`.
+Read the next symbol S from the bitstream using prefix code #1. Note that S is
+any integer in the range `0` to
+`(256 + 24 + ` [`color_cache_size`](#color-cache-code)` - 1)`.
 
 The interpretation of S depends on its value:
 
   1. if S < 256
-     1. Use S as the green component
-     1. Read red from the bitstream using Huffman code #2
-     1. Read blue from the bitstream using Huffman code #3
-     1. Read alpha from the bitstream using Huffman code #4
-  1. if S < 256 + 24
-     1. Use S - 256 as a length prefix code
-     1. Read extra bits for length from the bitstream
+     1. Use S as the green component.
+     1. Read red from the bitstream using prefix code #2.
+     1. Read blue from the bitstream using prefix code #3.
+     1. Read alpha from the bitstream using prefix code #4.
+  1. if S >= 256 && S < 256 + 24
+     1. Use S - 256 as a length prefix code.
+     1. Read extra bits for length from the bitstream.
      1. Determine backward-reference length L from length prefix code and the
         extra bits read.
-     1. Read distance prefix code from the bitstream using Huffman code #5
-     1. Read extra bits for distance from the bitstream
+     1. Read distance prefix code from the bitstream using prefix code #5.
+     1. Read extra bits for distance from the bitstream.
      1. Determine backward-reference distance D from distance prefix code and
         the extra bits read.
      1. Copy the L pixels (in scan-line order) from the sequence of pixels
@@ -947,144 +1051,86 @@
      1. Get ARGB color from the color cache at that index.
 
 
-**Decoding the Code Lengths:**
-{:#decoding-the-code-lengths}
-
-This section describes the details about reading a symbol from the bitstream by
-decoding the Huffman code length.
-
-The Huffman code lengths can be coded in two ways. The method used is specified
-by a 1-bit value.
-
-  * If this bit is 1, it is a _simple code length code_, and
-  * If this bit is 0, it is a _normal code length code_.
-
-**(i) Simple Code Length Code:**
-
-This variant is used in the special case when only 1 or 2 Huffman code lengths
-are non-zero, and are in the range of \[0, 255\]. All other Huffman code lengths
-are implicitly zeros.
-
-The first bit indicates the number of non-zero code lengths:
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int num_code_lengths = ReadBits(1) + 1;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The first code length is stored either using a 1-bit code for values of 0 and 1,
-or using an 8-bit code for values in range \[0, 255\]. The second code length,
-when present, is coded as an 8-bit code.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int is_first_8bits = ReadBits(1);
-code_lengths[0] = ReadBits(1 + 7 * is_first_8bits);
-if (num_code_lengths == 2) {
-  code_lengths[1] = ReadBits(8);
-}
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Note:** Another special case is when _all_ Huffman code lengths are _zeros_
-(an empty Huffman code). For example, a Huffman code for distance can be empty
-if there are no backward references. Similarly, Huffman codes for alpha, red,
-and blue can be empty if all pixels within the same meta Huffman code are
-produced using the color cache. However, this case doesn't need a special
-handling, as empty Huffman codes can be coded as those containing a single
-symbol `0`.
-
-**(ii) Normal Code Length Code:**
-
-The code lengths of a Huffman code are read as follows: `num_code_lengths`
-specifies the number of code lengths; the rest of the code lengths
-(according to the order in `kCodeLengthCodeOrder`) are zeros.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int kCodeLengthCodes = 19;
-int kCodeLengthCodeOrder[kCodeLengthCodes] = {
-  17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-int code_lengths[kCodeLengthCodes] = { 0 };  // All zeros.
-int num_code_lengths = 4 + ReadBits(4);
-for (i = 0; i < num_code_lengths; ++i) {
-  code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
-}
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-  * Code length code \[0..15\] indicates literal code lengths.
-    * Value 0 means no symbols have been coded.
-    * Values \[1..15\] indicate the bit length of the respective code.
-  * Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
-    3 + `ReadBits(2)` times.  If code 16 is used before a non-zero
-    value has been emitted, a value of 8 is repeated.
-  * Code 17 emits a streak of zeros \[3..10\], i.e., 3 + `ReadBits(3)`
-    times.
-  * Code 18 emits a streak of zeros of length \[11..138\], i.e.,
-    11 + `ReadBits(7)` times.
-
-
-6 Overall Structure of the Format
+7 Overall Structure of the Format
 ---------------------------------
 
-Below is a view into the format in Backus-Naur form. It does not cover
-all details. End-of-image (EOI) is only implicitly coded into the number
-of pixels (xsize * ysize).
+Below is a view into the format in Augmented Backus-Naur Form ([ABNF]). It does
+not cover all details. End-of-image (EOI) is only implicitly coded into the
+number of pixels (xsize * ysize).
 
 
-#### Basic Structure
+#### 7.1 Basic Structure
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<format> ::= <RIFF header><image size><image stream>
-<image stream> ::= <optional-transform><spatially-coded image>
+format        = RIFF-header image-header image-stream
+RIFF-header   = "RIFF" 4OCTET "WEBP" "VP8L" 4OCTET %x2F
+image-header  = image-size alpha-is-used version
+image-size    = 14BIT 14BIT ; width - 1, height - 1
+alpha-is-used = 1BIT
+version       = 3BIT ; 0
+image-stream  = optional-transform spatially-coded-image
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-#### Structure of Transforms
+#### 7.2 Structure of Transforms
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<optional-transform> ::= (1-bit value 1; <transform> <optional-transform>) |
-                         1-bit value 0
-<transform> ::= <predictor-tx> | <color-tx> | <subtract-green-tx> |
-                <color-indexing-tx>
-<predictor-tx> ::= 2-bit value 0; <predictor image>
-<predictor image> ::= 3-bit sub-pixel code ; <entropy-coded image>
-<color-tx> ::= 2-bit value 1; <color image>
-<color image> ::= 3-bit sub-pixel code ; <entropy-coded image>
-<subtract-green-tx> ::= 2-bit value 2
-<color-indexing-tx> ::= 2-bit value 3; <color-indexing image>
-<color-indexing image> ::= 8-bit color count; <entropy-coded image>
+optional-transform   =  (%b1 transform optional-transform) / %b0
+transform            =  predictor-tx / color-tx / subtract-green-tx
+transform            =/ color-indexing-tx
+
+predictor-tx         =  %b00 predictor-image
+predictor-image      =  3BIT ; sub-pixel code
+                        entropy-coded-image
+
+color-tx             =  %b01 color-image
+color-image          =  3BIT ; sub-pixel code
+                        entropy-coded-image
+
+subtract-green-tx    =  %b10
+
+color-indexing-tx    =  %b11 color-indexing-image
+color-indexing-image =  8BIT ; color count
+                        entropy-coded-image
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-#### Structure of the Image Data
+#### 7.3 Structure of the Image Data
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<spatially-coded image> ::= <meta huffman><entropy-coded image>
-<entropy-coded image> ::= <color cache info><huffman codes><lz77-coded image>
-<meta huffman> ::= 1-bit value 0 |
-                   (1-bit value 1; <entropy image>)
-<entropy image> ::= 3-bit subsample value; <entropy-coded image>
-<color cache info> ::= 1 bit value 0 |
-                       (1-bit value 1; 4-bit value for color cache size)
-<huffman codes> ::= <huffman code group> | <huffman code group><huffman codes>
-<huffman code group> ::= <huffman code><huffman code><huffman code>
-                         <huffman code><huffman code>
-                         See "Interpretation of Meta Huffman codes" to
-                         understand what each of these five Huffman codes are
-                         for.
-<huffman code> ::= <simple huffman code> | <normal huffman code>
-<simple huffman code> ::= see "Simple code length code" for details
-<normal huffman code> ::= <code length code>; encoded code lengths
-<code length code> ::= see section "Normal code length code"
-<lz77-coded image> ::= ((<argb-pixel> | <lz77-copy> | <color-cache-code>)
-                       <lz77-coded image>) | ""
+spatially-coded-image =  color-cache-info meta-prefix data
+entropy-coded-image   =  color-cache-info data
+
+color-cache-info      =  %b0
+color-cache-info      =/ (%b1 4BIT) ; 1 followed by color cache size
+
+meta-prefix           =  %b0 / (%b1 entropy-image)
+
+data                  =  prefix-codes lz77-coded-image
+entropy-image         =  3BIT ; subsample value
+                         entropy-coded-image
+
+prefix-codes          =  prefix-code-group *prefix-codes
+prefix-code-group     =
+    5prefix-code ; See "Interpretation of Meta Prefix Codes" to
+                 ; understand what each of these five prefix
+                 ; codes are for.
+
+prefix-code           =  simple-prefix-code / normal-prefix-code
+simple-prefix-code    =  ; see "Simple Code Length Code" for details
+normal-prefix-code    =  ; see "Normal Code Length Code" for details
+
+lz77-coded-image      =
+    *((argb-pixel / lz77-copy / color-cache-code) lz77-coded-image)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 A possible example sequence:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<RIFF header><image size>1-bit value 1<subtract-green-tx>
-1-bit value 1<predictor-tx>1-bit value 0<meta huffman>
-<color cache info><huffman codes>
-<lz77-coded image>
+RIFF-header image-size %b1 subtract-green-tx
+%b1 predictor-tx %b0 color-cache-info
+%b0 prefix-codes lz77-coded-image
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
+[ABNF]: https://www.rfc-editor.org/rfc/rfc5234
+[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code
diff --git a/third_party/libwebp/examples/Android.mk b/third_party/libwebp/examples/Android.mk
index 486b8b8..ae0f5b4 100644
--- a/third_party/libwebp/examples/Android.mk
+++ b/third_party/libwebp/examples/Android.mk
@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 ################################################################################
@@ -26,7 +28,6 @@
     cwebp.c \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
 LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpdemux webp
 
 LOCAL_MODULE := cwebp
@@ -42,7 +43,6 @@
     dwebp.c \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
 LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webpdemux webp
 LOCAL_MODULE := dwebp
 
@@ -57,7 +57,6 @@
     webpmux.c \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
 LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp
 
 LOCAL_MODULE := webpmux_example
@@ -73,7 +72,6 @@
     img2webp.c \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
 LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
                           webp
 
@@ -90,9 +88,9 @@
     webpinfo.c \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
 LOCAL_STATIC_LIBRARIES := example_util imageio_util webp
 
 LOCAL_MODULE := webpinfo_example
 
 include $(BUILD_EXECUTABLE)
+endif  # NDK_ROOT
diff --git a/third_party/libwebp/examples/Makefile.am b/third_party/libwebp/examples/Makefile.am
index e10872f..bbf0bac 100644
--- a/third_party/libwebp/examples/Makefile.am
+++ b/third_party/libwebp/examples/Makefile.am
@@ -1,7 +1,7 @@
 AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
 
 bin_PROGRAMS =
-if WANT_DEMUX
+if BUILD_DEMUX
   bin_PROGRAMS += dwebp cwebp
 endif
 if BUILD_ANIMDIFF
@@ -13,7 +13,7 @@
 if BUILD_IMG2WEBP
   bin_PROGRAMS += img2webp
 endif
-if WANT_MUX
+if BUILD_MUX
   bin_PROGRAMS += webpmux
 endif
 if BUILD_VWEBP
@@ -28,7 +28,7 @@
 libexample_util_la_SOURCES = example_util.c example_util.h
 libexample_util_la_LIBADD = ../src/libwebp.la
 
-anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
+anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h gifdec.c gifdec.h
 anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
 anim_diff_LDADD  =
 anim_diff_LDADD += ../src/demux/libwebpdemux.la
@@ -36,7 +36,7 @@
 anim_diff_LDADD += ../imageio/libimageio_util.la
 anim_diff_LDADD += $(GIF_LIBS) -lm
 
-anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h
+anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h gifdec.c gifdec.h
 anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(PNG_INCLUDES)
 anim_dump_CPPFLAGS += $(GIF_INCLUDES)
 anim_dump_LDADD  =
@@ -47,7 +47,7 @@
 anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
 
 cwebp_SOURCES  = cwebp.c stopwatch.h
-cwebp_CPPFLAGS  = $(AM_CPPFLAGS)
+cwebp_CPPFLAGS  = $(AM_CPPFLAGS) -I$(top_srcdir)
 cwebp_LDADD  =
 cwebp_LDADD += libexample_util.la
 cwebp_LDADD += ../imageio/libimageio_util.la
@@ -92,7 +92,7 @@
 webpmux_LDADD += ../src/libwebp.la
 
 img2webp_SOURCES = img2webp.c
-img2webp_CPPFLAGS = $(AM_CPPFLAGS)
+img2webp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)
 img2webp_LDADD  =
 img2webp_LDADD += libexample_util.la
 img2webp_LDADD += ../imageio/libimageio_util.la
diff --git a/third_party/libwebp/examples/anim_diff.c b/third_party/libwebp/examples/anim_diff.c
index e74a915..7ffabc8 100644
--- a/third_party/libwebp/examples/anim_diff.c
+++ b/third_party/libwebp/examples/anim_diff.c
@@ -20,6 +20,8 @@
 #include <string.h>  // for 'strcmp'.
 
 #include "./anim_util.h"
+#include "./example_util.h"
+#include "./unicode.h"
 
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
@@ -143,8 +145,18 @@
   if (!ok) return 0;  // These are fatal failures, can't proceed.
 
   if (is_multi_frame_image) {  // Checks relevant for multi-frame images only.
-    ok = CompareValues(img1->loop_count, img2->loop_count,
-                       "Loop count mismatch") && ok;
+    int max_loop_count_workaround = 0;
+    // Transcodes to webp increase the gif loop count by 1 for compatibility.
+    // When the gif has the maximum value the webp value will be off by one.
+    if ((img1->format == ANIM_GIF && img1->loop_count == 65536 &&
+         img2->format == ANIM_WEBP && img2->loop_count == 65535) ||
+        (img1->format == ANIM_WEBP && img1->loop_count == 65535 &&
+         img2->format == ANIM_GIF && img2->loop_count == 65536)) {
+      max_loop_count_workaround = 1;
+    }
+    ok = (max_loop_count_workaround ||
+          CompareValues(img1->loop_count, img2->loop_count,
+                        "Loop count mismatch")) && ok;
     ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor,
                                 premultiply) && ok;
   }
@@ -207,25 +219,20 @@
   const char* files[2] = { NULL, NULL };
   AnimatedImage images[2];
 
+  INIT_WARGV(argc, argv);
+
   for (c = 1; c < argc; ++c) {
     int parse_error = 0;
     if (!strcmp(argv[c], "-dump_frames")) {
       if (c < argc - 1) {
         dump_frames = 1;
-        dump_folder = argv[++c];
+        dump_folder = (const char*)GET_WARGV(argv, ++c);
       } else {
         parse_error = 1;
       }
     } else if (!strcmp(argv[c], "-min_psnr")) {
       if (c < argc - 1) {
-        const char* const v = argv[++c];
-        char* end = NULL;
-        const double d = strtod(v, &end);
-        if (end == v) {
-          parse_error = 1;
-          fprintf(stderr, "Error! '%s' is not a floating point number.\n", v);
-        }
-        min_psnr = d;
+        min_psnr = ExUtilGetFloat(argv[++c], &parse_error);
       } else {
         parse_error = 1;
       }
@@ -233,20 +240,13 @@
       premultiply = 0;
     } else if (!strcmp(argv[c], "-max_diff")) {
       if (c < argc - 1) {
-        const char* const v = argv[++c];
-        char* end = NULL;
-        const int n = (int)strtol(v, &end, 10);
-        if (end == v) {
-          parse_error = 1;
-          fprintf(stderr, "Error! '%s' is not an integer.\n", v);
-        }
-        max_diff = n;
+        max_diff = ExUtilGetInt(argv[++c], 0, &parse_error);
       } else {
         parse_error = 1;
       }
     } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       Help();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-version")) {
       int dec_version, demux_version;
       GetAnimatedImageVersions(&dec_version, &demux_version);
@@ -255,13 +255,13 @@
              (dec_version >> 0) & 0xff,
              (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
              (demux_version >> 0) & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else {
       if (!got_input1) {
-        files[0] = argv[c];
+        files[0] = (const char*)GET_WARGV(argv, c);
         got_input1 = 1;
       } else if (!got_input2) {
-        files[1] = argv[c];
+        files[1] = (const char*)GET_WARGV(argv, c);
         got_input2 = 1;
       } else {
         parse_error = 1;
@@ -269,29 +269,30 @@
     }
     if (parse_error) {
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
   }
   if (argc < 3) {
     Help();
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
 
   if (!got_input2) {
     Help();
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
   if (dump_frames) {
-    printf("Dumping decoded frames in: %s\n", dump_folder);
+    WPRINTF("Dumping decoded frames in: %s\n", (const W_CHAR*)dump_folder);
   }
 
   memset(images, 0, sizeof(images));
   for (i = 0; i < 2; ++i) {
-    printf("Decoding file: %s\n", files[i]);
+    WPRINTF("Decoding file: %s\n", (const W_CHAR*)files[i]);
     if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) {
-      fprintf(stderr, "Error decoding file: %s\n Aborting.\n", files[i]);
+      WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n",
+               (const W_CHAR*)files[i]);
       return_code = -2;
       goto End;
     } else {
@@ -301,14 +302,16 @@
 
   if (!CompareAnimatedImagePair(&images[0], &images[1],
                                 premultiply, min_psnr)) {
-    fprintf(stderr, "\nFiles %s and %s differ.\n", files[0], files[1]);
+    WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0],
+             (const W_CHAR*)files[1]);
     return_code = -3;
   } else {
-    printf("\nFiles %s and %s are identical.\n", files[0], files[1]);
+    WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0],
+            (const W_CHAR*)files[1]);
     return_code = 0;
   }
  End:
   ClearAnimatedImage(&images[0]);
   ClearAnimatedImage(&images[1]);
-  return return_code;
+  FREE_WARGV_AND_RETURN(return_code);
 }
diff --git a/third_party/libwebp/examples/anim_dump.c b/third_party/libwebp/examples/anim_dump.c
index 7b96cfe..e447338 100644
--- a/third_party/libwebp/examples/anim_dump.c
+++ b/third_party/libwebp/examples/anim_dump.c
@@ -17,6 +17,7 @@
 #include "./anim_util.h"
 #include "webp/decode.h"
 #include "../imageio/image_enc.h"
+#include "./unicode.h"
 
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
@@ -36,15 +37,17 @@
 
 int main(int argc, const char* argv[]) {
   int error = 0;
-  const char* dump_folder = ".";
-  const char* prefix = "dump_";
-  const char* suffix = "png";
+  const W_CHAR* dump_folder = TO_W_CHAR(".");
+  const W_CHAR* prefix = TO_W_CHAR("dump_");
+  const W_CHAR* suffix = TO_W_CHAR("png");
   WebPOutputFileFormat format = PNG;
   int c;
 
+  INIT_WARGV(argc, argv);
+
   if (argc < 2) {
     Help();
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
   for (c = 1; !error && c < argc; ++c) {
@@ -54,23 +57,23 @@
         error = 1;
         break;
       }
-      dump_folder = argv[++c];
+      dump_folder = GET_WARGV(argv, ++c);
     } else if (!strcmp(argv[c], "-prefix")) {
       if (c + 1 == argc) {
         fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
         error = 1;
         break;
       }
-      prefix = argv[++c];
+      prefix = GET_WARGV(argv, ++c);
     } else if (!strcmp(argv[c], "-tiff")) {
       format = TIFF;
-      suffix = "tiff";
+      suffix = TO_W_CHAR("tiff");
     } else if (!strcmp(argv[c], "-pam")) {
       format = PAM;
-      suffix = "pam";
+      suffix = TO_W_CHAR("pam");
     } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       Help();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-version")) {
       int dec_version, demux_version;
       GetAnimatedImageVersions(&dec_version, &demux_version);
@@ -79,21 +82,21 @@
              (dec_version >> 0) & 0xff,
              (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
              (demux_version >> 0) & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else {
       uint32_t i;
       AnimatedImage image;
-      const char* const file = argv[c];
+      const W_CHAR* const file = GET_WARGV(argv, c);
       memset(&image, 0, sizeof(image));
-      printf("Decoding file: %s as %s/%sxxxx.%s\n",
-             file, dump_folder, prefix, suffix);
-      if (!ReadAnimatedImage(file, &image, 0, NULL)) {
-        fprintf(stderr, "Error decoding file: %s\n Aborting.\n", file);
+      WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n",
+              file, dump_folder, prefix, suffix);
+      if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) {
+        WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file);
         error = 1;
         break;
       }
       for (i = 0; !error && i < image.num_frames; ++i) {
-        char out_file[1024];
+        W_CHAR out_file[1024];
         WebPDecBuffer buffer;
         WebPInitDecBuffer(&buffer);
         buffer.colorspace = MODE_RGBA;
@@ -103,10 +106,10 @@
         buffer.u.RGBA.rgba = image.frames[i].rgba;
         buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
         buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
-        snprintf(out_file, sizeof(out_file), "%s/%s%.4d.%s",
-                 dump_folder, prefix, i, suffix);
-        if (!WebPSaveImage(&buffer, format, out_file)) {
-          fprintf(stderr, "Error while saving image '%s'\n", out_file);
+        WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s",
+                  dump_folder, prefix, i, suffix);
+        if (!WebPSaveImage(&buffer, format, (const char*)out_file)) {
+          WFPRINTF(stderr, "Error while saving image '%s'\n", out_file);
           error = 1;
         }
         WebPFreeDecBuffer(&buffer);
@@ -114,5 +117,5 @@
       ClearAnimatedImage(&image);
     }
   }
-  return error ? 1 : 0;
+  FREE_WARGV_AND_RETURN(error ? 1 : 0);
 }
diff --git a/third_party/libwebp/examples/anim_util.c b/third_party/libwebp/examples/anim_util.c
index c7a05c7..cf7da4c 100644
--- a/third_party/libwebp/examples/anim_util.c
+++ b/third_party/libwebp/examples/anim_util.c
@@ -23,6 +23,9 @@
 #include "webp/decode.h"
 #include "webp/demux.h"
 #include "../imageio/imageio_util.h"
+#include "./gifdec.h"
+#include "./unicode.h"
+#include "./unicode_gif.h"
 
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
@@ -57,15 +60,15 @@
       !CheckSizeForOverflow(total_frame_size)) {
     return 0;
   }
-  mem = (uint8_t*)malloc((size_t)total_size);
-  frames = (DecodedFrame*)malloc((size_t)total_frame_size);
+  mem = (uint8_t*)WebPMalloc((size_t)total_size);
+  frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size);
 
   if (mem == NULL || frames == NULL) {
-    free(mem);
-    free(frames);
+    WebPFree(mem);
+    WebPFree(frames);
     return 0;
   }
-  free(image->raw_mem);
+  WebPFree(image->raw_mem);
   image->num_frames = num_frames;
   image->frames = frames;
   for (i = 0; i < num_frames; ++i) {
@@ -79,8 +82,8 @@
 
 void ClearAnimatedImage(AnimatedImage* const image) {
   if (image != NULL) {
-    free(image->raw_mem);
-    free(image->frames);
+    WebPFree(image->raw_mem);
+    WebPFree(image->frames);
     image->num_frames = 0;
     image->frames = NULL;
     image->raw_mem = NULL;
@@ -151,42 +154,42 @@
   int ok = 0;
   size_t max_len;
   int y;
-  const char* base_name = NULL;
-  char* file_name = NULL;
+  const W_CHAR* base_name = NULL;
+  W_CHAR* file_name = NULL;
   FILE* f = NULL;
   const char* row;
 
-  if (dump_folder == NULL) dump_folder = ".";
+  if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR(".");
 
-  base_name = strrchr(filename, '/');
-  base_name = (base_name == NULL) ? filename : base_name + 1;
-  max_len = strlen(dump_folder) + 1 + strlen(base_name)
+  base_name = WSTRRCHR(filename, '/');
+  base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
+  max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
           + strlen("_frame_") + strlen(".pam") + 8;
-  file_name = (char*)malloc(max_len * sizeof(*file_name));
+  file_name = (W_CHAR*)WebPMalloc(max_len * sizeof(*file_name));
   if (file_name == NULL) goto End;
 
-  if (snprintf(file_name, max_len, "%s/%s_frame_%d.pam",
-               dump_folder, base_name, frame_num) < 0) {
+  if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
+                (const W_CHAR*)dump_folder, base_name, frame_num) < 0) {
     fprintf(stderr, "Error while generating file name\n");
     goto End;
   }
 
-  f = fopen(file_name, "wb");
+  f = WFOPEN(file_name, "wb");
   if (f == NULL) {
-    fprintf(stderr, "Error opening file for writing: %s\n", file_name);
+    WFPRINTF(stderr, "Error opening file for writing: %s\n", file_name);
     ok = 0;
     goto End;
   }
   if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
               "DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
               canvas_width, canvas_height) < 0) {
-    fprintf(stderr, "Write error for file %s\n", file_name);
+    WFPRINTF(stderr, "Write error for file %s\n", file_name);
     goto End;
   }
   row = (const char*)rgba;
   for (y = 0; y < canvas_height; ++y) {
     if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) {
-      fprintf(stderr, "Error writing to file: %s\n", file_name);
+      WFPRINTF(stderr, "Error writing to file: %s\n", file_name);
       goto End;
     }
     row += canvas_width * kNumChannels;
@@ -194,7 +197,7 @@
   ok = 1;
  End:
   if (f != NULL) fclose(f);
-  free(file_name);
+  WebPFree(file_name);
   return ok;
 }
 
@@ -222,7 +225,7 @@
 
   dec = WebPAnimDecoderNew(webp_data, NULL);
   if (dec == NULL) {
-    fprintf(stderr, "Error parsing image: %s\n", filename);
+    WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename);
     goto End;
   }
 
@@ -238,7 +241,7 @@
   image->bgcolor = anim_info.bgcolor;
 
   // Allocate frames.
-  if (!AllocateFrames(image, anim_info.frame_count)) return 0;
+  if (!AllocateFrames(image, anim_info.frame_count)) goto End;
 
   // Decode frames.
   while (WebPAnimDecoderHasMoreFrames(dec)) {
@@ -275,6 +278,7 @@
     prev_frame_timestamp = timestamp;
   }
   ok = dump_ok;
+  if (ok) image->format = ANIM_WEBP;
 
  End:
   WebPAnimDecoderDelete(dec);
@@ -369,26 +373,6 @@
 #define DGifCloseFile(a, b) DGifCloseFile(a)
 #endif
 
-static void GIFDisplayError(const GifFileType* const gif, int gif_error) {
-  // libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
-#if LOCAL_GIF_PREREQ(4, 2)
-#if LOCAL_GIF_PREREQ(5, 0)
-  const char* error_str =
-      GifErrorString((gif == NULL) ? gif_error : gif->Error);
-#else
-  const char* error_str = GifErrorString();
-  (void)gif;
-#endif
-  if (error_str == NULL) error_str = "Unknown error";
-  fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
-#else
-  (void)gif;
-  fprintf(stderr, "GIFLib Error %d: ", gif_error);
-  PrintGifError();
-  fprintf(stderr, "\n");
-#endif
-}
-
 static int IsKeyFrameGIF(const GifImageDesc* prev_desc, int prev_dispose,
                          const DecodedFrame* const prev_frame,
                          int canvas_width, int canvas_height) {
@@ -421,7 +405,7 @@
     return 0xffffffff;  // Invalid: assume white.
   } else {
     const GifColorType color = color_map->Colors[gif->SBackGroundColor];
-    return (0xff << 24) |
+    return (0xffu << 24) |
            (color.Red << 16) |
            (color.Green << 8) |
            (color.Blue << 0);
@@ -529,15 +513,15 @@
   int gif_error;
   GifFileType* gif;
 
-  gif = DGifOpenFileName(filename, NULL);
+  gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL);
   if (gif == NULL) {
-    fprintf(stderr, "Could not read file: %s.\n", filename);
+    WFPRINTF(stderr, "Could not read file: %s.\n", (const W_CHAR*)filename);
     return 0;
   }
 
   gif_error = DGifSlurp(gif);
   if (gif_error != GIF_OK) {
-    fprintf(stderr, "Could not parse image: %s.\n", filename);
+    WFPRINTF(stderr, "Could not parse image: %s.\n", (const W_CHAR*)filename);
     GIFDisplayError(gif, gif_error);
     DGifCloseFile(gif, NULL);
     return 0;
@@ -574,7 +558,10 @@
     }
   }
   // Allocate frames.
-  AllocateFrames(image, frame_count);
+  if (!AllocateFrames(image, frame_count)) {
+    DGifCloseFile(gif, NULL);
+    return 0;
+  }
 
   canvas_width = image->canvas_width;
   canvas_height = image->canvas_height;
@@ -687,6 +674,7 @@
       }
     }
   }
+  image->format = ANIM_GIF;
   DGifCloseFile(gif, NULL);
   return 1;
 }
@@ -722,7 +710,7 @@
   memset(image, 0, sizeof(*image));
 
   if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) {
-    fprintf(stderr, "Error reading file: %s\n", filename);
+    WFPRINTF(stderr, "Error reading file: %s\n", (const W_CHAR*)filename);
     return 0;
   }
 
@@ -732,9 +720,9 @@
   } else if (IsGIF(&webp_data)) {
     ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
   } else {
-    fprintf(stderr,
-            "Unknown file type: %s. Supported file types are WebP and GIF\n",
-            filename);
+    WFPRINTF(stderr,
+             "Unknown file type: %s. Supported file types are WebP and GIF\n",
+             (const W_CHAR*)filename);
     ok = 0;
   }
   if (!ok) ClearAnimatedImage(image);
diff --git a/third_party/libwebp/examples/anim_util.h b/third_party/libwebp/examples/anim_util.h
index 8063121..574e032 100644
--- a/third_party/libwebp/examples/anim_util.h
+++ b/third_party/libwebp/examples/anim_util.h
@@ -22,6 +22,11 @@
 extern "C" {
 #endif
 
+typedef enum {
+  ANIM_GIF,
+  ANIM_WEBP
+} AnimatedFileFormat;
+
 typedef struct {
   uint8_t* rgba;         // Decoded and reconstructed full frame.
   int duration;          // Frame duration in milliseconds.
@@ -29,6 +34,7 @@
 } DecodedFrame;
 
 typedef struct {
+  AnimatedFileFormat format;
   uint32_t canvas_width;
   uint32_t canvas_height;
   uint32_t bgcolor;
diff --git a/third_party/libwebp/examples/cwebp.c b/third_party/libwebp/examples/cwebp.c
index de7190b..835579d 100644
--- a/third_party/libwebp/examples/cwebp.c
+++ b/third_party/libwebp/examples/cwebp.c
@@ -12,6 +12,7 @@
 //
 // Author: Skal (pascal.massimino@gmail.com)
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -23,7 +24,10 @@
 #include "../examples/example_util.h"
 #include "../imageio/image_dec.h"
 #include "../imageio/imageio_util.h"
+#include "../imageio/webpdec.h"
 #include "./stopwatch.h"
+#include "./unicode.h"
+#include "sharpyuv/sharpyuv.h"
 #include "webp/encode.h"
 
 #ifndef WEBP_DLL
@@ -88,9 +92,10 @@
     }
   }
   if (!ok) {
-    fprintf(stderr, "Error! Could not process file %s\n", filename);
+    WFPRINTF(stderr, "Error! Could not process file %s\n",
+             (const W_CHAR*)filename);
   }
-  free((void*)data);
+  WebPFree((void*)data);
   return ok;
 }
 
@@ -114,9 +119,10 @@
   }
  End:
   if (!ok) {
-    fprintf(stderr, "Error! Could not process file %s\n", filename);
+    WFPRINTF(stderr, "Error! Could not process file %s\n",
+             (const W_CHAR*)filename);
   }
-  free((void*)data);
+  WebPFree((void*)data);
   return ok;
 }
 
@@ -125,7 +131,8 @@
 static void AllocExtraInfo(WebPPicture* const pic) {
   const int mb_w = (pic->width + 15) / 16;
   const int mb_h = (pic->height + 15) / 16;
-  pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info));
+  pic->extra_info =
+      (uint8_t*)WebPMalloc(mb_w * mb_h * sizeof(*pic->extra_info));
 }
 
 static void PrintByteCount(const int bytes[4], int total_size,
@@ -144,7 +151,7 @@
   int s;
   const int total = counts[0] + counts[1] + counts[2] + counts[3];
   for (s = 0; s < 4; ++s) {
-    fprintf(stderr, "|      %2d%%", (int)(100. * counts[s] / total + .5));
+    fprintf(stderr, "|     %3d%%", (int)(100. * counts[s] / total + .5));
   }
   fprintf(stderr, "| %7d\n", total);
 }
@@ -185,7 +192,7 @@
   if (short_output) {
     fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
   } else {
-    fprintf(stderr, "File:      %s\n", file_name);
+    WFPRINTF(stderr, "File:      %s\n", (const W_CHAR*)file_name);
     fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
     fprintf(stderr, "Output:    %d bytes (%.2f bpp)\n", stats->coded_size,
             8.f * stats->coded_size / pic->width / pic->height);
@@ -204,7 +211,7 @@
     const int num_i16 = stats->block_count[1];
     const int num_skip = stats->block_count[2];
     const int total = num_i4 + num_i16;
-    fprintf(stderr, "File:      %s\n", file_name);
+    WFPRINTF(stderr, "File:      %s\n", (const W_CHAR*)file_name);
     fprintf(stderr, "Dimension: %d x %d%s\n",
             pic->width, pic->height,
             stats->alpha_data_size ? " (with alpha)" : "");
@@ -309,7 +316,7 @@
   const int alpha_height =
       WebPPictureHasTransparency(picture) ? picture->height : 0;
   const int height = picture->height + uv_height + alpha_height;
-  FILE* const f = fopen(PGM_name, "wb");
+  FILE* const f = WFOPEN(PGM_name, "wb");
   if (f == NULL) return 0;
   fprintf(f, "P5\n%d %d\n255\n", stride, height);
   for (y = 0; y < picture->height; ++y) {
@@ -521,6 +528,7 @@
   printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n");
   printf("If input size (-s) for an image is not specified, it is\n"
          "assumed to be a PNG, JPEG, TIFF or WebP file.\n");
+  printf("Note: Animated PNG and WebP files are not supported.\n");
 #ifdef HAVE_WINCODEC_H
   printf("Windows builds can take as input any of the files handled by WIC.\n");
 #endif
@@ -561,8 +569,10 @@
   printf("                           "
          "the first partition (0=no degradation ... 100=full)\n");
   printf("  -pass <int> ............ analysis pass number (1..10)\n");
+  printf("  -qrange <min> <max> .... specifies the permissible quality range\n"
+         "                           (default: 0 100)\n");
   printf("  -crop <x> <y> <w> <h> .. crop picture with the given rectangle\n");
-  printf("  -resize <w> <h> ........ resize picture (after any cropping)\n");
+  printf("  -resize <w> <h> ........ resize picture (*after* any cropping)\n");
   printf("  -mt .................... use multi-threading if available\n");
   printf("  -low_memory ............ reduce memory usage (slower encoding)\n");
   printf("  -map <int> ............. print map of extra info\n");
@@ -582,9 +592,8 @@
          "                           green=0xe0 and blue=0xd0\n");
   printf("  -noalpha ............... discard any transparency information\n");
   printf("  -lossless .............. encode image losslessly, default=off\n");
-  printf("  -near_lossless <int> ... use near-lossless image\n"
-         "                           preprocessing (0..100=off), "
-         "default=100\n");
+  printf("  -near_lossless <int> ... use near-lossless image preprocessing\n"
+         "                           (0..100=off), default=100\n");
   printf("  -hint <string> ......... specify image characteristics hint,\n");
   printf("                           one of: photo, picture or graph\n");
 
@@ -611,6 +620,7 @@
   printf("  -af .................... auto-adjust filter strength\n");
   printf("  -pre <int> ............. pre-processing filter\n");
   printf("\n");
+  printf("Supported input formats:\n  %s\n", WebPGetEnabledInputFileFormats());
 }
 
 //------------------------------------------------------------------------------
@@ -637,10 +647,10 @@
 
 //------------------------------------------------------------------------------
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   int return_value = -1;
-  const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
-  FILE *out = NULL;
+  const char* in_file = NULL, *out_file = NULL, *dump_file = NULL;
+  FILE* out = NULL;
   int c;
   int short_output = 0;
   int quiet = 0;
@@ -660,35 +670,38 @@
   WebPConfig config;
   WebPAuxStats stats;
   WebPMemoryWriter memory_writer;
+  int use_memory_writer;
   Metadata metadata;
   Stopwatch stop_watch;
 
+  INIT_WARGV(argc, argv);
+
   MetadataInit(&metadata);
   WebPMemoryWriterInit(&memory_writer);
   if (!WebPPictureInit(&picture) ||
       !WebPPictureInit(&original_picture) ||
       !WebPConfigInit(&config)) {
     fprintf(stderr, "Error! Version mismatch!\n");
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
   if (argc == 1) {
     HelpShort();
-    return 0;
+    FREE_WARGV_AND_RETURN(0);
   }
 
   for (c = 1; c < argc; ++c) {
     int parse_error = 0;
     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       HelpShort();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
       HelpLong();
-      return 0;
-    } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
-      out_file = argv[++c];
-    } else if (!strcmp(argv[c], "-d") && c < argc - 1) {
-      dump_file = argv[++c];
+      FREE_WARGV_AND_RETURN(0);
+    } else if (!strcmp(argv[c], "-o") && c + 1 < argc) {
+      out_file = (const char*)GET_WARGV(argv, ++c);
+    } else if (!strcmp(argv[c], "-d") && c + 1 < argc) {
+      dump_file = (const char*)GET_WARGV(argv, ++c);
       config.show_compressed = 1;
     } else if (!strcmp(argv[c], "-print_psnr")) {
       config.show_compressed = 1;
@@ -701,7 +714,7 @@
       print_distortion = 2;
     } else if (!strcmp(argv[c], "-short")) {
       ++short_output;
-    } else if (!strcmp(argv[c], "-s") && c < argc - 2) {
+    } else if (!strcmp(argv[c], "-s") && c + 2 < argc) {
       picture.width = ExUtilGetInt(argv[++c], 0, &parse_error);
       picture.height = ExUtilGetInt(argv[++c], 0, &parse_error);
       if (picture.width > WEBP_MAX_DIMENSION || picture.width < 0 ||
@@ -711,30 +724,30 @@
                 picture.width, picture.height);
         goto Error;
       }
-    } else if (!strcmp(argv[c], "-m") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-m") && c + 1 < argc) {
       config.method = ExUtilGetInt(argv[++c], 0, &parse_error);
       use_lossless_preset = 0;   // disable -z option
-    } else if (!strcmp(argv[c], "-q") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-q") && c + 1 < argc) {
       config.quality = ExUtilGetFloat(argv[++c], &parse_error);
       use_lossless_preset = 0;   // disable -z option
-    } else if (!strcmp(argv[c], "-z") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-z") && c + 1 < argc) {
       lossless_preset = ExUtilGetInt(argv[++c], 0, &parse_error);
       if (use_lossless_preset != 0) use_lossless_preset = 1;
-    } else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-alpha_q") && c + 1 < argc) {
       config.alpha_quality = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-alpha_method") && c + 1 < argc) {
       config.alpha_compression = ExUtilGetInt(argv[++c], 0, &parse_error);
     } else if (!strcmp(argv[c], "-alpha_cleanup")) {
       // This flag is obsolete, does opposite of -exact.
       config.exact = 0;
     } else if (!strcmp(argv[c], "-exact")) {
       config.exact = 1;
-    } else if (!strcmp(argv[c], "-blend_alpha") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-blend_alpha") && c + 1 < argc) {
       blend_alpha = 1;
       // background color is given in hex with an optional '0x' prefix
       background_color = ExUtilGetInt(argv[++c], 16, &parse_error);
       background_color = background_color & 0x00ffffffu;
-    } else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-alpha_filter") && c + 1 < argc) {
       ++c;
       if (!strcmp(argv[c], "none")) {
         config.alpha_filtering = 0;
@@ -750,10 +763,10 @@
       keep_alpha = 0;
     } else if (!strcmp(argv[c], "-lossless")) {
       config.lossless = 1;
-    } else if (!strcmp(argv[c], "-near_lossless") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) {
       config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
       config.lossless = 1;  // use near-lossless only with lossless
-    } else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-hint") && c + 1 < argc) {
       ++c;
       if (!strcmp(argv[c], "photo")) {
         config.image_hint = WEBP_HINT_PHOTO;
@@ -765,13 +778,13 @@
         fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
         goto Error;
       }
-    } else if (!strcmp(argv[c], "-size") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-size") && c + 1 < argc) {
       config.target_size = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-psnr") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-psnr") && c + 1 < argc) {
       config.target_PSNR = ExUtilGetFloat(argv[++c], &parse_error);
-    } else if (!strcmp(argv[c], "-sns") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-sns") && c + 1 < argc) {
       config.sns_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-f") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-f") && c + 1 < argc) {
       config.filter_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
     } else if (!strcmp(argv[c], "-af")) {
       config.autofilter = 1;
@@ -785,27 +798,32 @@
       config.filter_type = 1;
     } else if (!strcmp(argv[c], "-nostrong")) {
       config.filter_type = 0;
-    } else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-sharpness") && c + 1 < argc) {
       config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error);
     } else if (!strcmp(argv[c], "-sharp_yuv")) {
       config.use_sharp_yuv = 1;
-    } else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-pass") && c + 1 < argc) {
       config.pass = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-qrange") && c + 2 < argc) {
+      config.qmin = ExUtilGetInt(argv[++c], 0, &parse_error);
+      config.qmax = ExUtilGetInt(argv[++c], 0, &parse_error);
+      if (config.qmin < 0) config.qmin = 0;
+      if (config.qmax > 100) config.qmax = 100;
+    } else if (!strcmp(argv[c], "-pre") && c + 1 < argc) {
       config.preprocessing = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-segments") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-segments") && c + 1 < argc) {
       config.segments = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-partition_limit") && c + 1 < argc) {
       config.partition_limit = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-map") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-map") && c + 1 < argc) {
       picture.extra_info_type = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
+    } else if (!strcmp(argv[c], "-crop") && c + 4 < argc) {
       crop = 1;
       crop_x = ExUtilGetInt(argv[++c], 0, &parse_error);
       crop_y = ExUtilGetInt(argv[++c], 0, &parse_error);
       crop_w = ExUtilGetInt(argv[++c], 0, &parse_error);
       crop_h = ExUtilGetInt(argv[++c], 0, &parse_error);
-    } else if (!strcmp(argv[c], "-resize") && c < argc - 2) {
+    } else if (!strcmp(argv[c], "-resize") && c + 2 < argc) {
       resize_w = ExUtilGetInt(argv[++c], 0, &parse_error);
       resize_h = ExUtilGetInt(argv[++c], 0, &parse_error);
 #ifndef WEBP_DLL
@@ -814,14 +832,18 @@
 #endif
     } else if (!strcmp(argv[c], "-version")) {
       const int version = WebPGetEncoderVersion();
+      const int sharpyuv_version = SharpYuvGetVersion();
       printf("%d.%d.%d\n",
              (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
-      return 0;
+      printf("libsharpyuv: %d.%d.%d\n",
+             (sharpyuv_version >> 24) & 0xff, (sharpyuv_version >> 16) & 0xffff,
+             sharpyuv_version & 0xff);
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-progress")) {
       show_progress = 1;
     } else if (!strcmp(argv[c], "-quiet")) {
       quiet = 1;
-    } else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-preset") && c + 1 < argc) {
       WebPPreset preset;
       ++c;
       if (!strcmp(argv[c], "default")) {
@@ -844,7 +866,7 @@
         fprintf(stderr, "Error! Could initialize configuration with preset.\n");
         goto Error;
       }
-    } else if (!strcmp(argv[c], "-metadata") && c < argc - 1) {
+    } else if (!strcmp(argv[c], "-metadata") && c + 1 < argc) {
       static const struct {
         const char* option;
         int flag;
@@ -878,8 +900,7 @@
         if (i == kNumTokens) {
           fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
                   (int)(token - start), start);
-          HelpLong();
-          return -1;
+          FREE_WARGV_AND_RETURN(-1);
         }
         start = token + 1;
       }
@@ -893,19 +914,19 @@
     } else if (!strcmp(argv[c], "-v")) {
       verbose = 1;
     } else if (!strcmp(argv[c], "--")) {
-      if (c < argc - 1) in_file = argv[++c];
+      if (c + 1 < argc) in_file = (const char*)GET_WARGV(argv, ++c);
       break;
     } else if (argv[c][0] == '-') {
       fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
       HelpLong();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     } else {
-      in_file = argv[c];
+      in_file = (const char*)GET_WARGV(argv, c);
     }
 
     if (parse_error) {
       HelpLong();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
   }
   if (in_file == NULL) {
@@ -955,7 +976,8 @@
   }
   if (!ReadPicture(in_file, &picture, keep_alpha,
                    (keep_metadata == 0) ? NULL : &metadata)) {
-    fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file);
+    WFPRINTF(stderr, "Error! Cannot read input picture file '%s'\n",
+             (const W_CHAR*)in_file);
     goto Error;
   }
   picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
@@ -968,28 +990,41 @@
     const double read_time = StopwatchReadAndReset(&stop_watch);
     fprintf(stderr, "Time to read input: %.3fs\n", read_time);
   }
+  // The bitstream should be kept in memory when metadata must be appended
+  // before writing it to a file/stream, and/or when the near-losslessly encoded
+  // bitstream must be decoded for distortion computation (lossy will modify the
+  // 'picture' but not the lossless pipeline).
+  // Otherwise directly write the bitstream to a file.
+  use_memory_writer = (out_file != NULL && keep_metadata) ||
+                      (!quiet && print_distortion >= 0 && config.lossless &&
+                       config.near_lossless < 100);
 
   // Open the output
   if (out_file != NULL) {
-    const int use_stdout = !strcmp(out_file, "-");
-    out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
+    const int use_stdout = !WSTRCMP(out_file, "-");
+    out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(out_file, "wb");
     if (out == NULL) {
-      fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file);
+      WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
+               (const W_CHAR*)out_file);
       goto Error;
     } else {
       if (!short_output && !quiet) {
-        fprintf(stderr, "Saving file '%s'\n", out_file);
+        WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)out_file);
       }
     }
-    if (keep_metadata == 0) {
-      picture.writer = MyWriter;
-      picture.custom_ptr = (void*)out;
-    } else {
+    if (use_memory_writer) {
       picture.writer = WebPMemoryWrite;
       picture.custom_ptr = (void*)&memory_writer;
+    } else {
+      picture.writer = MyWriter;
+      picture.custom_ptr = (void*)out;
     }
   } else {
     out = NULL;
+    if (use_memory_writer) {
+      picture.writer = WebPMemoryWrite;
+      picture.custom_ptr = (void*)&memory_writer;
+    }
     if (!quiet && !short_output) {
       fprintf(stderr, "No output file specified (no -o flag). Encoding will\n");
       fprintf(stderr, "be performed, but its results discarded.\n\n");
@@ -1012,10 +1047,53 @@
     }
   }
   if ((resize_w | resize_h) > 0) {
+    WebPPicture picture_no_alpha;
+    if (config.exact) {
+      // If -exact, we can't premultiply RGB by A otherwise RGB is lost if A=0.
+      // We rescale an opaque copy and assemble scaled A and non-premultiplied
+      // RGB channels. This is slower but it's a very uncommon use case. Color
+      // leak at sharp alpha edges is possible.
+      if (!WebPPictureCopy(&picture, &picture_no_alpha)) {
+        fprintf(stderr, "Error! Cannot copy temporary picture\n");
+        goto Error;
+      }
+
+      // We enforced picture.use_argb = 1 above. Now, remove the alpha values.
+      {
+        int x, y;
+        uint32_t* argb_no_alpha = picture_no_alpha.argb;
+        for (y = 0; y < picture_no_alpha.height; ++y) {
+          for (x = 0; x < picture_no_alpha.width; ++x) {
+            argb_no_alpha[x] |= 0xff000000;  // Opaque copy.
+          }
+          argb_no_alpha += picture_no_alpha.argb_stride;
+        }
+      }
+
+      if (!WebPPictureRescale(&picture_no_alpha, resize_w, resize_h)) {
+        fprintf(stderr, "Error! Cannot resize temporary picture\n");
+        goto Error;
+      }
+    }
+
     if (!WebPPictureRescale(&picture, resize_w, resize_h)) {
       fprintf(stderr, "Error! Cannot resize picture\n");
       goto Error;
     }
+
+    if (config.exact) {  // Put back the alpha information.
+      int x, y;
+      uint32_t* argb_no_alpha = picture_no_alpha.argb;
+      uint32_t* argb = picture.argb;
+      for (y = 0; y < picture_no_alpha.height; ++y) {
+        for (x = 0; x < picture_no_alpha.width; ++x) {
+          argb[x] = (argb[x] & 0xff000000) | (argb_no_alpha[x] & 0x00ffffff);
+        }
+        argb_no_alpha += picture_no_alpha.argb_stride;
+        argb += picture.argb_stride;
+      }
+      WebPPictureFree(&picture_no_alpha);
+    }
   }
   if (verbose && (crop != 0 || (resize_w | resize_h) > 0)) {
     const double preproc_time = StopwatchReadAndReset(&stop_watch);
@@ -1025,8 +1103,12 @@
   if (picture.extra_info_type > 0) {
     AllocExtraInfo(&picture);
   }
-  if (print_distortion >= 0) {  // Save original picture for later comparison
-    WebPPictureCopy(&picture, &original_picture);
+  // Save original picture for later comparison. Only for lossy as lossless does
+  // not modify 'picture' (even near-lossless).
+  if (print_distortion >= 0 && !config.lossless &&
+      !WebPPictureCopy(&picture, &original_picture)) {
+    fprintf(stderr, "Error! Cannot copy temporary picture\n");
+    goto Error;
   }
 
   // Compress.
@@ -1044,40 +1126,72 @@
     fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time);
   }
 
-  // Write info
+  // Get the decompressed image for the lossless pipeline.
+  if (!quiet && print_distortion >= 0 && config.lossless) {
+    if (config.near_lossless == 100) {
+      // Pure lossless: image was not modified, make 'original_picture' a view
+      // of 'picture' by copying all members except the freeable pointers.
+      original_picture = picture;
+      original_picture.memory_ = original_picture.memory_argb_ = NULL;
+    } else {
+      // Decode the bitstream stored in 'memory_writer' to get the altered image
+      // to 'picture'; save the 'original_picture' beforehand.
+      assert(use_memory_writer);
+      original_picture = picture;
+      if (!WebPPictureInit(&picture)) {  // Do not free 'picture'.
+        fprintf(stderr, "Error! Version mismatch!\n");
+        goto Error;
+      }
+
+      picture.use_argb = 1;
+      if (!ReadWebP(
+              memory_writer.mem, memory_writer.size, &picture,
+              /*keep_alpha=*/WebPPictureHasTransparency(&original_picture),
+              /*metadata=*/NULL)) {
+        fprintf(stderr, "Error! Cannot decode encoded WebP bitstream\n");
+        fprintf(stderr, "Error code: %d (%s)\n", picture.error_code,
+                kErrorMessages[picture.error_code]);
+        goto Error;
+      }
+      picture.stats = original_picture.stats;
+    }
+    original_picture.stats = NULL;
+  }
+
+  // Write the YUV planes to a PGM file. Only available for lossy.
   if (dump_file) {
     if (picture.use_argb) {
-      fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode.");
+      fprintf(stderr, "Warning: can't dump file (-d option) "
+                      "in lossless mode.\n");
     } else if (!DumpPicture(&picture, dump_file)) {
-      fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file);
+      WFPRINTF(stderr, "Warning, couldn't dump picture %s\n",
+               (const W_CHAR*)dump_file);
     }
   }
 
-  if (keep_metadata != 0) {
-    if (out != NULL) {
-      if (!WriteWebPWithMetadata(out, &picture, &memory_writer,
-                                 &metadata, keep_metadata, &metadata_written)) {
-        fprintf(stderr, "Error writing WebP file with metadata!\n");
-        goto Error;
-      }
-    } else {  // output is disabled, just display the metadata stats.
-      const struct {
-        const MetadataPayload* const payload;
-        int flag;
-      } *iter, info[] = {
-        { &metadata.exif, METADATA_EXIF },
-        { &metadata.iccp, METADATA_ICC },
-        { &metadata.xmp, METADATA_XMP },
-        { NULL, 0 }
-      };
-      uint32_t unused1 = 0;
-      uint64_t unused2 = 0;
+  if (use_memory_writer && out != NULL &&
+      !WriteWebPWithMetadata(out, &picture, &memory_writer, &metadata,
+                             keep_metadata, &metadata_written)) {
+    fprintf(stderr, "Error writing WebP file!\n");
+    goto Error;
+  }
 
-      for (iter = info; iter->payload != NULL; ++iter) {
-        if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
-                               0, &unused1, &unused2)) {
-          metadata_written |= iter->flag;
-        }
+  if (out == NULL && keep_metadata) {
+    // output is disabled, just display the metadata stats.
+    const struct {
+      const MetadataPayload* const payload;
+      int flag;
+    } *iter, info[] = {{&metadata.exif, METADATA_EXIF},
+                       {&metadata.iccp, METADATA_ICC},
+                       {&metadata.xmp, METADATA_XMP},
+                       {NULL, 0}};
+    uint32_t unused1 = 0;
+    uint64_t unused2 = 0;
+
+    for (iter = info; iter->payload != NULL; ++iter) {
+      if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
+                             /*flag=*/0, &unused1, &unused2)) {
+        metadata_written |= iter->flag;
       }
     }
   }
@@ -1117,7 +1231,7 @@
 
  Error:
   WebPMemoryWriterClear(&memory_writer);
-  free(picture.extra_info);
+  WebPFree(picture.extra_info);
   MetadataFree(&metadata);
   WebPPictureFree(&picture);
   WebPPictureFree(&original_picture);
@@ -1125,7 +1239,7 @@
     fclose(out);
   }
 
-  return return_value;
+  FREE_WARGV_AND_RETURN(return_value);
 }
 
 //------------------------------------------------------------------------------
diff --git a/third_party/libwebp/examples/dwebp.c b/third_party/libwebp/examples/dwebp.c
index 154069a..652de6a 100644
--- a/third_party/libwebp/examples/dwebp.c
+++ b/third_party/libwebp/examples/dwebp.c
@@ -24,6 +24,7 @@
 #include "../imageio/image_enc.h"
 #include "../imageio/webpdec.h"
 #include "./stopwatch.h"
+#include "./unicode.h"
 
 static int verbose = 0;
 static int quiet = 0;
@@ -42,7 +43,7 @@
 
 static int SaveOutput(const WebPDecBuffer* const buffer,
                       WebPOutputFileFormat format, const char* const out_file) {
-  const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
+  const int use_stdout = (out_file != NULL) && !WSTRCMP(out_file, "-");
   int ok = 1;
   Stopwatch stop_watch;
 
@@ -56,7 +57,7 @@
       if (use_stdout) {
         fprintf(stderr, "Saved to stdout\n");
       } else {
-        fprintf(stderr, "Saved file %s\n", out_file);
+        WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file);
       }
     }
     if (verbose) {
@@ -67,7 +68,7 @@
     if (use_stdout) {
       fprintf(stderr, "Error writing to stdout !!\n");
     } else {
-      fprintf(stderr, "Error writing file %s !!\n", out_file);
+      WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file);
     }
   }
   return ok;
@@ -75,7 +76,8 @@
 
 static void Help(void) {
   printf("Usage: dwebp in_file [options] [-o out_file]\n\n"
-         "Decodes the WebP image file to PNG format [Default]\n"
+         "Decodes the WebP image file to PNG format [Default].\n"
+         "Note: Animated WebP files are not supported.\n\n"
          "Use following options to convert into alternate image formats:\n"
          "  -pam ......... save the raw RGBA samples as a color PAM\n"
          "  -ppm ......... save the raw RGB samples as a color PPM\n"
@@ -94,7 +96,7 @@
          "  -alpha_dither  use alpha-plane dithering if needed\n"
          "  -mt .......... use multi-threading\n"
          "  -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
-         "  -resize <w> <h> ......... scale the output (*after* any cropping)\n"
+         "  -resize <w> <h> ......... resize output (*after* any cropping)\n"
          "  -flip ........ flip the output vertically\n"
          "  -alpha ....... only save the alpha plane\n"
          "  -incremental . use incremental decoding (useful for tests)\n"
@@ -131,7 +133,7 @@
                      format == RGB_565) ? 2
                   : 4;
     uint32_t stride = bpp * w + 7;   // <- just for exercising
-    external_buffer = (uint8_t*)malloc(stride * h);
+    external_buffer = (uint8_t*)WebPMalloc(stride * h);
     if (external_buffer == NULL) return NULL;
     output_buffer->u.RGBA.stride = stride;
     output_buffer->u.RGBA.size = stride * h;
@@ -144,7 +146,7 @@
     uint32_t total_size = stride * h * (has_alpha ? 2 : 1)
                         + 2 * uv_stride * (h + 1) / 2;
     assert(format >= YUV && format <= YUVA);
-    external_buffer = (uint8_t*)malloc(total_size);
+    external_buffer = (uint8_t*)WebPMalloc(total_size);
     if (external_buffer == NULL) return NULL;
     tmp = external_buffer;
     output_buffer->u.YUVA.y = tmp;
@@ -175,10 +177,10 @@
   return external_buffer;
 }
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   int ok = 0;
-  const char *in_file = NULL;
-  const char *out_file = NULL;
+  const char* in_file = NULL;
+  const char* out_file = NULL;
 
   WebPDecoderConfig config;
   WebPDecBuffer* const output_buffer = &config.output;
@@ -191,18 +193,20 @@
   int incremental = 0;
   int c;
 
+  INIT_WARGV(argc, argv);
+
   if (!WebPInitDecoderConfig(&config)) {
     fprintf(stderr, "Library version mismatch!\n");
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
   for (c = 1; c < argc; ++c) {
     int parse_error = 0;
     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       Help();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
-      out_file = argv[++c];
+      out_file = (const char*)GET_WARGV(argv, ++c);
     } else if (!strcmp(argv[c], "-alpha")) {
       format = ALPHA_PLANE_ONLY;
     } else if (!strcmp(argv[c], "-nofancy")) {
@@ -223,7 +227,7 @@
       const int version = WebPGetDecoderVersion();
       printf("%d.%d.%d\n",
              (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-pgm")) {
       format = PGM;
     } else if (!strcmp(argv[c], "-yuv")) {
@@ -284,26 +288,26 @@
     } else if (!strcmp(argv[c], "-incremental")) {
       incremental = 1;
     } else if (!strcmp(argv[c], "--")) {
-      if (c < argc - 1) in_file = argv[++c];
+      if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c);
       break;
     } else if (argv[c][0] == '-') {
       fprintf(stderr, "Unknown option '%s'\n", argv[c]);
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     } else {
-      in_file = argv[c];
+      in_file = (const char*)GET_WARGV(argv, c);
     }
 
     if (parse_error) {
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
   }
 
   if (in_file == NULL) {
     fprintf(stderr, "missing input file!!\n");
     Help();
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
 
   if (quiet) verbose = 0;
@@ -312,7 +316,7 @@
     VP8StatusCode status = VP8_STATUS_OK;
     size_t data_size = 0;
     if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
 
     switch (format) {
@@ -389,18 +393,18 @@
 
   if (out_file != NULL) {
     if (!quiet) {
-      fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. "
-                      "Now saving...\n",
-              in_file, output_buffer->width, output_buffer->height,
+      WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file);
+      fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n",
+              output_buffer->width, output_buffer->height,
               bitstream->has_alpha ? " (with alpha)" : "",
               kFormatType[bitstream->format]);
     }
     ok = SaveOutput(output_buffer, format, out_file);
   } else {
     if (!quiet) {
-      fprintf(stderr, "File %s can be decoded "
-                      "(dimensions: %d x %d %s. Format: %s).\n",
-              in_file, output_buffer->width, output_buffer->height,
+      WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file);
+      fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n",
+              output_buffer->width, output_buffer->height,
               bitstream->has_alpha ? " (with alpha)" : "",
               kFormatType[bitstream->format]);
       fprintf(stderr, "Nothing written; "
@@ -409,9 +413,9 @@
   }
  Exit:
   WebPFreeDecBuffer(output_buffer);
-  free((void*)external_buffer);
-  free((void*)data);
-  return ok ? 0 : -1;
+  WebPFree((void*)external_buffer);
+  WebPFree((void*)data);
+  FREE_WARGV_AND_RETURN(ok ? 0 : -1);
 }
 
 //------------------------------------------------------------------------------
diff --git a/third_party/libwebp/examples/example_util.c b/third_party/libwebp/examples/example_util.c
index 825a123..fa38d3c 100644
--- a/third_party/libwebp/examples/example_util.c
+++ b/third_party/libwebp/examples/example_util.c
@@ -75,7 +75,7 @@
 void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
   if (args != NULL) {
     if (args->own_argv_) {
-      free((void*)args->argv_);
+      WebPFree((void*)args->argv_);
       WebPDataClear(&args->argv_data_);
     }
     ResetCommandLineArguments(0, NULL, args);
@@ -90,12 +90,23 @@
   if (argc == 1 && argv[0][0] != '-') {
     char* cur;
     const char sep[] = " \t\r\n\f\v";
+
+#if defined(_WIN32) && defined(_UNICODE)
+    fprintf(stderr,
+            "Error: Reading arguments from a file is a feature unavailable "
+            "with Unicode binaries.\n");
+    return 0;
+#endif
+
     if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
       return 0;
     }
     args->own_argv_ = 1;
-    args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_));
-    if (args->argv_ == NULL) return 0;
+    args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_));
+    if (args->argv_ == NULL) {
+      ExUtilDeleteCommandLineArguments(args);
+      return 0;
+    }
 
     argc = 0;
     for (cur = strtok((char*)args->argv_data_.bytes, sep);
@@ -103,6 +114,7 @@
          cur = strtok(NULL, sep)) {
       if (argc == MAX_ARGC) {
         fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
+        ExUtilDeleteCommandLineArguments(args);
         return 0;
       }
       assert(strlen(cur) != 0);
diff --git a/third_party/libwebp/examples/gif2webp.c b/third_party/libwebp/examples/gif2webp.c
index b61f273..cc9b25d 100644
--- a/third_party/libwebp/examples/gif2webp.c
+++ b/third_party/libwebp/examples/gif2webp.c
@@ -33,6 +33,8 @@
 #include "../examples/example_util.h"
 #include "../imageio/imageio_util.h"
 #include "./gifdec.h"
+#include "./unicode.h"
+#include "./unicode_gif.h"
 
 #if !defined(STDIN_FILENO)
 #define STDIN_FILENO 0
@@ -94,13 +96,12 @@
 
 //------------------------------------------------------------------------------
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   int verbose = 0;
   int gif_error = GIF_ERROR;
   WebPMuxError err = WEBP_MUX_OK;
   int ok = 0;
-  const char *in_file = NULL, *out_file = NULL;
-  FILE* out = NULL;
+  const W_CHAR* in_file = NULL, *out_file = NULL;
   GifFileType* gif = NULL;
   int frame_duration = 0;
   int frame_timestamp = 0;
@@ -133,11 +134,13 @@
   int default_kmin = 1;  // Whether to use default kmin value.
   int default_kmax = 1;
 
+  INIT_WARGV(argc, argv);
+
   if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
       !WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
       !WebPPictureInit(&prev_canvas)) {
     fprintf(stderr, "Error! Version mismatch!\n");
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
   config.lossless = 1;  // Use lossless compression by default.
 
@@ -147,16 +150,16 @@
 
   if (argc == 1) {
     Help();
-    return 0;
+    FREE_WARGV_AND_RETURN(0);
   }
 
   for (c = 1; c < argc; ++c) {
     int parse_error = 0;
     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       Help();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
-      out_file = argv[++c];
+      out_file = GET_WARGV(argv, ++c);
     } else if (!strcmp(argv[c], "-lossy")) {
       config.lossless = 0;
     } else if (!strcmp(argv[c], "-mixed")) {
@@ -213,7 +216,7 @@
           fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
                   (int)(token - start), start);
           Help();
-          return -1;
+          FREE_WARGV_AND_RETURN(-1);
         }
         start = token + 1;
       }
@@ -226,7 +229,7 @@
              (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
              enc_version & 0xff, (mux_version >> 16) & 0xff,
              (mux_version >> 8) & 0xff, mux_version & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-quiet")) {
       quiet = 1;
       enc_options.verbose = 0;
@@ -234,19 +237,19 @@
       verbose = 1;
       enc_options.verbose = 1;
     } else if (!strcmp(argv[c], "--")) {
-      if (c < argc - 1) in_file = argv[++c];
+      if (c < argc - 1) in_file = GET_WARGV(argv, ++c);
       break;
     } else if (argv[c][0] == '-') {
       fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     } else {
-      in_file = argv[c];
+      in_file = GET_WARGV(argv, c);
     }
 
     if (parse_error) {
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
   }
 
@@ -270,13 +273,7 @@
   }
 
   // Start the decoder object
-#if LOCAL_GIF_PREREQ(5,0)
-  gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO, &gif_error)
-                              : DGifOpenFileName(in_file, &gif_error);
-#else
-  gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO)
-                              : DGifOpenFileName(in_file);
-#endif
+  gif = DGifOpenFileUnicode(in_file, &gif_error);
   if (gif == NULL) goto End;
 
   // Loop over GIF images
@@ -317,8 +314,11 @@
           frame.use_argb = 1;
           if (!WebPPictureAlloc(&frame)) goto End;
           GIFClearPic(&frame, NULL);
-          WebPPictureCopy(&frame, &curr_canvas);
-          WebPPictureCopy(&frame, &prev_canvas);
+          if (!(WebPPictureCopy(&frame, &curr_canvas) &&
+                WebPPictureCopy(&frame, &prev_canvas))) {
+            fprintf(stderr, "Error allocating canvas.\n");
+            goto End;
+          }
 
           // Background color.
           GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor,
@@ -382,7 +382,7 @@
       }
       case EXTENSION_RECORD_TYPE: {
         int extension;
-        GifByteType *data = NULL;
+        GifByteType* data = NULL;
         if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) {
           goto End;
         }
@@ -468,8 +468,10 @@
     fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
     goto End;
   }
-
-  if (!loop_compatibility) {
+  // If there's only one frame, we don't need to handle loop count.
+  if (frame_number == 1) {
+    loop_count = 0;
+  } else if (!loop_compatibility) {
     if (!stored_loop_count) {
       // if no loop-count element is seen, the default is '1' (loop-once)
       // and we need to signal it explicitly in WebP. Note however that
@@ -478,7 +480,7 @@
         stored_loop_count = 1;
         loop_count = 1;
       }
-    } else if (loop_count > 0) {
+    } else if (loop_count > 0 && loop_count < 65535) {
       // adapt GIF's semantic to WebP's (except in the infinite-loop case)
       loop_count += 1;
     }
@@ -545,17 +547,18 @@
   }
 
   if (out_file != NULL) {
-    if (!ImgIoUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) {
-      fprintf(stderr, "Error writing output file: %s\n", out_file);
+    if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes,
+                            webp_data.size)) {
+      WFPRINTF(stderr, "Error writing output file: %s\n", out_file);
       goto End;
     }
     if (!quiet) {
-      if (!strcmp(out_file, "-")) {
+      if (!WSTRCMP(out_file, "-")) {
         fprintf(stderr, "Saved %d bytes to STDIO\n",
                 (int)webp_data.size);
       } else {
-        fprintf(stderr, "Saved output file (%d bytes): %s\n",
-                (int)webp_data.size, out_file);
+        WFPRINTF(stderr, "Saved output file (%d bytes): %s\n",
+                 (int)webp_data.size, out_file);
       }
     }
   } else {
@@ -578,7 +581,6 @@
   WebPPictureFree(&curr_canvas);
   WebPPictureFree(&prev_canvas);
   WebPAnimEncoderDelete(enc);
-  if (out != NULL && out_file != NULL) fclose(out);
 
   if (gif_error != GIF_OK) {
     GIFDisplayError(gif, gif_error);
@@ -591,12 +593,12 @@
 #endif
   }
 
-  return !ok;
+  FREE_WARGV_AND_RETURN(!ok);
 }
 
 #else  // !WEBP_HAVE_GIF
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]);
   (void)argc;
   return 0;
diff --git a/third_party/libwebp/examples/gifdec.c b/third_party/libwebp/examples/gifdec.c
index 4219352..99ee996 100644
--- a/third_party/libwebp/examples/gifdec.c
+++ b/third_party/libwebp/examples/gifdec.c
@@ -137,7 +137,7 @@
   }
   dst = sub_image.argb;
 
-  tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
+  tmp = (uint8_t*)WebPMalloc(rect.width * sizeof(*tmp));
   if (tmp == NULL) goto End;
 
   if (image_desc->Interlace) {  // Interlaced image.
@@ -168,7 +168,7 @@
  End:
   if (!ok) picture->error_code = sub_image.error_code;
   WebPPictureFree(&sub_image);
-  free(tmp);
+  WebPFree(tmp);
   return ok;
 }
 
diff --git a/third_party/libwebp/examples/img2webp.c b/third_party/libwebp/examples/img2webp.c
index 2f750c5..3735030 100644
--- a/third_party/libwebp/examples/img2webp.c
+++ b/third_party/libwebp/examples/img2webp.c
@@ -27,6 +27,8 @@
 #include "../imageio/image_dec.h"
 #include "../imageio/imageio_util.h"
 #include "./stopwatch.h"
+#include "./unicode.h"
+#include "sharpyuv/sharpyuv.h"
 #include "webp/encode.h"
 #include "webp/mux.h"
 
@@ -34,18 +36,22 @@
 
 static void Help(void) {
   printf("Usage:\n\n");
-  printf("  img2webp [file-level options] [image files...] "
-         "[per-frame options...]\n");
-  printf("\n");
+  printf("  img2webp [file_options] [[frame_options] frame_file]...");
+  printf(" [-o webp_file]\n\n");
 
   printf("File-level options (only used at the start of compression):\n");
   printf(" -min_size ............ minimize size\n");
-  printf(" -loop <int> .......... loop count (default: 0, = infinite loop)\n");
   printf(" -kmax <int> .......... maximum number of frame between key-frames\n"
          "                        (0=only keyframes)\n");
   printf(" -kmin <int> .......... minimum number of frame between key-frames\n"
          "                        (0=disable key-frames altogether)\n");
   printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
+  printf(" -near_lossless <int> . use near-lossless image preprocessing\n"
+         "                        (0..100=off), default=100\n");
+  printf(" -sharp_yuv ........... use sharper (and slower) RGB->YUV "
+                                  "conversion\n                        "
+                                  "(lossy only)\n");
+  printf(" -loop <int> .......... loop count (default: 0, = infinite loop)\n");
   printf(" -v ................... verbose mode\n");
   printf(" -h ................... this help\n");
   printf(" -version ............. print version number and exit\n");
@@ -61,6 +67,12 @@
   printf("\n");
   printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n"
          "                  -d 80 in2.tiff -o out.webp\n");
+  printf("\nNote: if a single file name is passed as the argument, the "
+         "arguments will be\n");
+  printf("tokenized from this file. The file name must not start with "
+         "the character '-'.\n");
+  printf("\nSupported input formats:\n  %s\n",
+         WebPGetEnabledInputFileFormats());
 }
 
 //------------------------------------------------------------------------------
@@ -79,7 +91,7 @@
   if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0;
   reader = WebPGuessImageReader(data, data_size);
   ok = reader(data, data_size, pic, 1, NULL);
-  free((void*)data);
+  WebPFree((void*)data);
   return ok;
 }
 
@@ -134,8 +146,13 @@
   int c;
   int have_input = 0;
   CommandLineArguments cmd_args;
-  int ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
-  if (!ok) return 1;
+  int ok;
+
+  INIT_WARGV(argc, argv);
+
+  ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
+  if (!ok) FREE_WARGV_AND_RETURN(1);
+
   argc = cmd_args.argc_;
   argv = cmd_args.argv_;
 
@@ -154,7 +171,7 @@
       int parse_error = 0;
       if (!strcmp(argv[c], "-o") && c + 1 < argc) {
         argv[c] = NULL;
-        output = argv[++c];
+        output = (const char*)GET_WARGV_SHIFTED(argv, ++c);
       } else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
         argv[c] = NULL;
         anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
@@ -173,18 +190,26 @@
       } else if (!strcmp(argv[c], "-mixed")) {
         anim_config.allow_mixed = 1;
         config.lossless = 0;
+      } else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) {
+        argv[c] = NULL;
+        config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
+      } else if (!strcmp(argv[c], "-sharp_yuv")) {
+        config.use_sharp_yuv = 1;
       } else if (!strcmp(argv[c], "-v")) {
         verbose = 1;
       } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
         Help();
-        goto End;
+        FREE_WARGV_AND_RETURN(0);
       } else if (!strcmp(argv[c], "-version")) {
         const int enc_version = WebPGetEncoderVersion();
         const int mux_version = WebPGetMuxVersion();
+        const int sharpyuv_version = SharpYuvGetVersion();
         printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
                (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
                enc_version & 0xff, (mux_version >> 16) & 0xff,
                (mux_version >> 8) & 0xff, mux_version & 0xff);
+        printf("libsharpyuv: %d.%d.%d\n", (sharpyuv_version >> 24) & 0xff,
+               (sharpyuv_version >> 16) & 0xffff, sharpyuv_version & 0xff);
         goto End;
       } else {
         continue;
@@ -241,7 +266,7 @@
 
     // read next input image
     pic.use_argb = 1;
-    ok = ReadImage(argv[c], &pic);
+    ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic);
     if (!ok) goto End;
 
     if (enc == NULL) {
@@ -273,8 +298,8 @@
     if (!ok) goto End;
 
     if (verbose) {
-      fprintf(stderr, "Added frame #%3d at time %4d (file: %s)\n",
-              pic_num, timestamp_ms, argv[c]);
+      WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n",
+               pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c));
     }
     timestamp_ms += duration;
     ++pic_num;
@@ -298,7 +323,7 @@
   if (ok) {
     if (output != NULL) {
       ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size);
-      if (ok) fprintf(stderr, "output file: %s     ", output);
+      if (ok) WFPRINTF(stderr, "output file: %s     ", (const W_CHAR*)output);
     } else {
       fprintf(stderr, "[no output file specified]   ");
     }
@@ -310,5 +335,5 @@
   }
   WebPDataClear(&webp_data);
   ExUtilDeleteCommandLineArguments(&cmd_args);
-  return ok ? 0 : 1;
+  FREE_WARGV_AND_RETURN(ok ? 0 : 1);
 }
diff --git a/third_party/libwebp/examples/stopwatch.h b/third_party/libwebp/examples/stopwatch.h
index f9e799c..f1b0fac 100644
--- a/third_party/libwebp/examples/stopwatch.h
+++ b/third_party/libwebp/examples/stopwatch.h
@@ -60,4 +60,4 @@
 
 #endif   /* _WIN32 */
 
-#endif  /* WEBP_EXAMPLES_STOPWATCH_H_ */
+#endif  // WEBP_EXAMPLES_STOPWATCH_H_
diff --git a/third_party/libwebp/examples/unicode.h b/third_party/libwebp/examples/unicode.h
new file mode 100644
index 0000000..0831e23
--- /dev/null
+++ b/third_party/libwebp/examples/unicode.h
@@ -0,0 +1,116 @@
+// Copyright 2018 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Unicode support for Windows. The main idea is to maintain an array of Unicode
+// arguments (wargv) and use it only for file paths. The regular argv is used
+// for everything else.
+//
+// Author: Yannis Guyon (yguyon@google.com)
+
+#ifndef WEBP_EXAMPLES_UNICODE_H_
+#define WEBP_EXAMPLES_UNICODE_H_
+
+#include <stdio.h>
+
+#if defined(_WIN32) && defined(_UNICODE)
+
+// wchar_t is used instead of TCHAR because we only perform additional work when
+// Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t.
+
+#include <fcntl.h>
+#include <io.h>
+#include <wchar.h>
+#include <windows.h>
+#include <shellapi.h>
+
+// Create a wchar_t array containing Unicode parameters.
+#define INIT_WARGV(ARGC, ARGV)                                                \
+  int wargc;                                                                  \
+  const W_CHAR** const wargv =                                                \
+      (const W_CHAR**)CommandLineToArgvW(GetCommandLineW(), &wargc);          \
+  do {                                                                        \
+    if (wargv == NULL || wargc != (ARGC)) {                                   \
+      fprintf(stderr, "Error: Unable to get Unicode arguments.\n");           \
+      FREE_WARGV_AND_RETURN(-1);                                              \
+    }                                                                         \
+  } while (0)
+
+// Use this to get a Unicode argument (e.g. file path).
+#define GET_WARGV(UNUSED, C) wargv[C]
+// For cases where argv is shifted by one compared to wargv.
+#define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1]
+#define GET_WARGV_OR_NULL() wargv
+
+// Release resources. LocalFree() is needed after CommandLineToArgvW().
+#define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv)
+#define LOCAL_FREE(WARGV)                  \
+  do {                                     \
+    if ((WARGV) != NULL) LocalFree(WARGV); \
+  } while (0)
+
+#define W_CHAR wchar_t  // WCHAR without underscore might already be defined.
+#define TO_W_CHAR(STR) (L##STR)
+
+#define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT))
+
+#define WFPRINTF(STREAM, STR, ...)                    \
+  do {                                                \
+    int prev_mode;                                    \
+    fflush(STREAM);                                   \
+    prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \
+    fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__);    \
+    fflush(STREAM);                                   \
+    (void)_setmode(_fileno(STREAM), prev_mode);       \
+  } while (0)
+#define WPRINTF(STR, ...) WFPRINTF(stdout, STR, __VA_ARGS__)
+
+#define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME)
+#define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
+#define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
+#define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__)
+
+#else
+
+#include <string.h>
+
+// Unicode file paths work as is on Unix platforms, and no extra work is done on
+// Windows either if Unicode is disabled.
+
+#define INIT_WARGV(ARGC, ARGV)
+
+#define GET_WARGV(ARGV, C) (ARGV)[C]
+#define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C]
+#define GET_WARGV_OR_NULL() NULL
+
+#define FREE_WARGV()
+#define LOCAL_FREE(WARGV)
+
+#define W_CHAR char
+#define TO_W_CHAR(STR) (STR)
+
+#define WFOPEN(ARG, OPT) fopen(ARG, OPT)
+
+#define WPRINTF(STR, ...) printf(STR, __VA_ARGS__)
+#define WFPRINTF(STREAM, STR, ...) fprintf(STREAM, STR, __VA_ARGS__)
+
+#define WSTRLEN(FILENAME) strlen(FILENAME)
+#define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR)
+#define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR)
+#define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__)
+
+#endif  // defined(_WIN32) && defined(_UNICODE)
+
+// Don't forget to free wargv before returning (e.g. from main).
+#define FREE_WARGV_AND_RETURN(VALUE) \
+  do {                               \
+    FREE_WARGV();                    \
+    return (VALUE);                  \
+  } while (0)
+
+#endif  // WEBP_EXAMPLES_UNICODE_H_
diff --git a/third_party/libwebp/examples/unicode_gif.h b/third_party/libwebp/examples/unicode_gif.h
new file mode 100644
index 0000000..626c6e7
--- /dev/null
+++ b/third_party/libwebp/examples/unicode_gif.h
@@ -0,0 +1,76 @@
+// Copyright 2018 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// giflib doesn't have a Unicode DGifOpenFileName(). Let's make one.
+//
+// Author: Yannis Guyon (yguyon@google.com)
+
+#ifndef WEBP_EXAMPLES_UNICODE_GIF_H_
+#define WEBP_EXAMPLES_UNICODE_GIF_H_
+
+#include "./unicode.h"
+#ifdef HAVE_CONFIG_H
+#include "webp/config.h"  // For WEBP_HAVE_GIF
+#endif
+
+#if defined(WEBP_HAVE_GIF)
+
+#ifdef _WIN32
+#include <fcntl.h>  // Not standard, needed for _topen and flags.
+#include <io.h>
+#endif
+
+#include <gif_lib.h>
+#include <string.h>
+#include "./gifdec.h"
+
+#if !defined(STDIN_FILENO)
+#define STDIN_FILENO 0
+#endif
+
+static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) {
+  if (!WSTRCMP(file_name, "-")) {
+#if LOCAL_GIF_PREREQ(5, 0)
+    return DGifOpenFileHandle(STDIN_FILENO, error);
+#else
+    (void)error;
+    return DGifOpenFileHandle(STDIN_FILENO);
+#endif
+  }
+
+#if defined(_WIN32) && defined(_UNICODE)
+  {
+    int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
+    if (file_handle == -1) {
+      if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
+      return NULL;
+    }
+
+#if LOCAL_GIF_PREREQ(5, 0)
+    return DGifOpenFileHandle(file_handle, error);
+#else
+    return DGifOpenFileHandle(file_handle);
+#endif
+  }
+
+#else
+
+#if LOCAL_GIF_PREREQ(5, 0)
+  return DGifOpenFileName(file_name, error);
+#else
+  return DGifOpenFileName(file_name);
+#endif
+
+#endif  // defined(_WIN32) && defined(_UNICODE)
+  // DGifCloseFile() is called later.
+}
+
+#endif  // defined(WEBP_HAVE_GIF)
+
+#endif  // WEBP_EXAMPLES_UNICODE_GIF_H_
diff --git a/third_party/libwebp/examples/vwebp.c b/third_party/libwebp/examples/vwebp.c
index a79c72c..35f1b18 100644
--- a/third_party/libwebp/examples/vwebp.c
+++ b/third_party/libwebp/examples/vwebp.c
@@ -42,6 +42,7 @@
 
 #include "../examples/example_util.h"
 #include "../imageio/imageio_util.h"
+#include "./unicode.h"
 
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
@@ -56,6 +57,7 @@
   int print_info;
   int only_deltas;
   int use_color_profile;
+  int draw_anim_background_color;
 
   int canvas_width, canvas_height;
   int loop_count;
@@ -225,6 +227,9 @@
 // Callbacks
 
 static void HandleKey(unsigned char key, int pos_x, int pos_y) {
+  // Note: rescaling the window or toggling some features during an animation
+  // generates visual artifacts. This is not fixed because refreshing the frame
+  // may require rendering the whole animation from start till current frame.
   (void)pos_x;
   (void)pos_y;
   if (key == 'q' || key == 'Q' || key == 27 /* Esc */) {
@@ -252,9 +257,11 @@
         glutPostRedisplay();
       }
     }
+  } else if (key == 'b') {
+    kParams.draw_anim_background_color = 1 - kParams.draw_anim_background_color;
+    if (!kParams.has_animation) ClearPreviousFrame();
+    glutPostRedisplay();
   } else if (key == 'i') {
-    // Note: doesn't handle refresh of animation's last-frame (it's quite
-    // more involved to do, since you need to save the previous frame).
     kParams.print_info = 1 - kParams.print_info;
     if (!kParams.has_animation) ClearPreviousFrame();
     glutPostRedisplay();
@@ -285,8 +292,21 @@
   }
 }
 
+static void PrintStringW(const char* const text) {
+#if defined(_WIN32) && defined(_UNICODE)
+  void* const font = GLUT_BITMAP_9_BY_15;
+  const W_CHAR* const wtext = (const W_CHAR*)text;
+  int i;
+  for (i = 0; wtext[i]; ++i) {
+    glutBitmapCharacter(font, wtext[i]);
+  }
+#else
+  PrintString(text);
+#endif
+}
+
 static float GetColorf(uint32_t color, int shift) {
-  return (color >> shift) / 255.f;
+  return ((color >> shift) & 0xff) / 255.f;
 }
 
 static void DrawCheckerBoard(void) {
@@ -309,6 +329,43 @@
   glPopMatrix();
 }
 
+static void DrawBackground(void) {
+  // Whole window cleared with clear color, checkerboard rendered on top of it.
+  glClear(GL_COLOR_BUFFER_BIT);
+  DrawCheckerBoard();
+
+  // ANIM background color rendered (blend) on top. Default is white for still
+  // images (without ANIM chunk). glClear() can't be used for that (no blend).
+  if (kParams.draw_anim_background_color) {
+    glPushMatrix();
+    glLoadIdentity();
+    glColor4f(GetColorf(kParams.bg_color, 16),  // BGRA from spec
+              GetColorf(kParams.bg_color, 8),
+              GetColorf(kParams.bg_color, 0),
+              GetColorf(kParams.bg_color, 24));
+    glRecti(-1, -1, +1, +1);
+    glPopMatrix();
+  }
+}
+
+// Draw background in a scissored rectangle.
+static void DrawBackgroundScissored(int window_x, int window_y, int frame_w,
+                                    int frame_h) {
+  // Only update the requested area, not the whole canvas.
+  window_x = window_x * kParams.viewport_width / kParams.canvas_width;
+  window_y = window_y * kParams.viewport_height / kParams.canvas_height;
+  frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
+  frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
+
+  // glScissor() takes window coordinates (0,0 at bottom left).
+  window_y = kParams.viewport_height - window_y - frame_h;
+
+  glEnable(GL_SCISSOR_TEST);
+  glScissor(window_x, window_y, frame_w, frame_h);
+  DrawBackground();
+  glDisable(GL_SCISSOR_TEST);
+}
+
 static void HandleDisplay(void) {
   const WebPDecBuffer* const pic = kParams.pic;
   const WebPIterator* const curr = &kParams.curr_frame;
@@ -325,38 +382,21 @@
   glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);
 
   if (kParams.only_deltas) {
-    DrawCheckerBoard();
-  } else if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
-      curr->blend_method == WEBP_MUX_NO_BLEND) {
-    // glScissor() takes window coordinates (0,0 at bottom left).
-    int window_x, window_y;
-    int frame_w, frame_h;
+    DrawBackground();
+  } else {
+    // The rectangle of the previous frame might be different than the current
+    // frame, so we may need to DrawBackgroundScissored for both.
     if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
       // Clear the previous frame rectangle.
-      window_x = prev->x_offset;
-      window_y = kParams.canvas_height - prev->y_offset - prev->height;
-      frame_w = prev->width;
-      frame_h = prev->height;
-    } else {  // curr->blend_method == WEBP_MUX_NO_BLEND.
-      // We simulate no-blending behavior by first clearing the current frame
-      // rectangle (to a checker-board) and then alpha-blending against it.
-      window_x = curr->x_offset;
-      window_y = kParams.canvas_height - curr->y_offset - curr->height;
-      frame_w = curr->width;
-      frame_h = curr->height;
+      DrawBackgroundScissored(prev->x_offset, prev->y_offset, prev->width,
+                              prev->height);
     }
-    glEnable(GL_SCISSOR_TEST);
-    // Only update the requested area, not the whole canvas.
-    window_x = window_x * kParams.viewport_width / kParams.canvas_width;
-    window_y = window_y * kParams.viewport_height / kParams.canvas_height;
-    frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
-    frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
-    glScissor(window_x, window_y, frame_w, frame_h);
-
-    glClear(GL_COLOR_BUFFER_BIT);  // use clear color
-    DrawCheckerBoard();
-
-    glDisable(GL_SCISSOR_TEST);
+    if (curr->blend_method == WEBP_MUX_NO_BLEND) {
+      // We simulate no-blending behavior by first clearing the current frame
+      // rectangle and then alpha-blending against it.
+      DrawBackgroundScissored(curr->x_offset, curr->y_offset, curr->width,
+                              curr->height);
+    }
   }
 
   *prev = *curr;
@@ -369,7 +409,7 @@
 
     glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
     glRasterPos2f(-0.95f, 0.90f);
-    PrintString(kParams.file_name);
+    PrintStringW(kParams.file_name);
 
     snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
     glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
@@ -391,8 +431,9 @@
 }
 
 static void StartDisplay(void) {
-  const int width = kParams.canvas_width;
-  const int height = kParams.canvas_height;
+  int width = kParams.canvas_width;
+  int height = kParams.canvas_height;
+  int screen_width, screen_height;
   // TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
   // partially displayed with animated webp + alpha.
 #if defined(__APPLE__) || defined(_WIN32)
@@ -400,6 +441,18 @@
 #else
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 #endif
+  screen_width = glutGet(GLUT_SCREEN_WIDTH);
+  screen_height = glutGet(GLUT_SCREEN_HEIGHT);
+  if (width > screen_width || height > screen_height) {
+    if (width > screen_width) {
+      height = (height * screen_width + width - 1) / width;
+      width = screen_width;
+    }
+    if (height > screen_height) {
+      width = (width * screen_height + height - 1) / height;
+      height = screen_height;
+    }
+  }
   glutInitWindowSize(width, height);
   glutCreateWindow("WebP viewer");
   glutDisplayFunc(HandleDisplay);
@@ -408,57 +461,59 @@
   glutKeyboardFunc(HandleKey);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable(GL_BLEND);
-  glClearColor(GetColorf(kParams.bg_color, 0),
-               GetColorf(kParams.bg_color, 8),
-               GetColorf(kParams.bg_color, 16),
-               GetColorf(kParams.bg_color, 24));
-  glClear(GL_COLOR_BUFFER_BIT);
-  DrawCheckerBoard();
+  glClearColor(0, 0, 0, 0);  // window will be cleared to black (no blend)
+  DrawBackground();
 }
 
 //------------------------------------------------------------------------------
 // Main
 
 static void Help(void) {
-  printf("Usage: vwebp in_file [options]\n\n"
-         "Decodes the WebP image file and visualize it using OpenGL\n"
-         "Options are:\n"
-         "  -version ..... print version number and exit\n"
-         "  -noicc ....... don't use the icc profile if present\n"
-         "  -nofancy ..... don't use the fancy YUV420 upscaler\n"
-         "  -nofilter .... disable in-loop filtering\n"
-         "  -dither <int>  dithering strength (0..100), default=50\n"
-         "  -noalphadither disable alpha plane dithering\n"
-         "  -mt .......... use multi-threading\n"
-         "  -info ........ print info\n"
-         "  -h ........... this help message\n"
-         "\n"
-         "Keyboard shortcuts:\n"
-         "  'c' ................ toggle use of color profile\n"
-         "  'i' ................ overlay file information\n"
-         "  'd' ................ disable blending & disposal (debug)\n"
-         "  'q' / 'Q' / ESC .... quit\n"
-        );
+  printf(
+      "Usage: vwebp in_file [options]\n\n"
+      "Decodes the WebP image file and visualize it using OpenGL\n"
+      "Options are:\n"
+      "  -version ..... print version number and exit\n"
+      "  -noicc ....... don't use the icc profile if present\n"
+      "  -nofancy ..... don't use the fancy YUV420 upscaler\n"
+      "  -nofilter .... disable in-loop filtering\n"
+      "  -dither <int>  dithering strength (0..100), default=50\n"
+      "  -noalphadither disable alpha plane dithering\n"
+      "  -usebgcolor .. display background color\n"
+      "  -mt .......... use multi-threading\n"
+      "  -info ........ print info\n"
+      "  -h ........... this help message\n"
+      "\n"
+      "Keyboard shortcuts:\n"
+      "  'c' ................ toggle use of color profile\n"
+      "  'b' ................ toggle background color display\n"
+      "  'i' ................ overlay file information\n"
+      "  'd' ................ disable blending & disposal (debug)\n"
+      "  'q' / 'Q' / ESC .... quit\n");
 }
 
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
   int c;
   WebPDecoderConfig* const config = &kParams.config;
   WebPIterator* const curr = &kParams.curr_frame;
 
+  INIT_WARGV(argc, argv);
+
   if (!WebPInitDecoderConfig(config)) {
     fprintf(stderr, "Library version mismatch!\n");
-    return -1;
+    FREE_WARGV_AND_RETURN(-1);
   }
   config->options.dithering_strength = 50;
   config->options.alpha_dithering_strength = 100;
   kParams.use_color_profile = 1;
+  // Background color hidden by default to see transparent areas.
+  kParams.draw_anim_background_color = 0;
 
   for (c = 1; c < argc; ++c) {
     int parse_error = 0;
     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
       Help();
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-noicc")) {
       kParams.use_color_profile = 0;
     } else if (!strcmp(argv[c], "-nofancy")) {
@@ -467,6 +522,8 @@
       config->options.bypass_filtering = 1;
     } else if (!strcmp(argv[c], "-noalphadither")) {
       config->options.alpha_dithering_strength = 0;
+    } else if (!strcmp(argv[c], "-usebgcolor")) {
+      kParams.draw_anim_background_color = 1;
     } else if (!strcmp(argv[c], "-dither") && c + 1 < argc) {
       config->options.dithering_strength =
           ExUtilGetInt(argv[++c], 0, &parse_error);
@@ -479,30 +536,30 @@
              (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
              dec_version & 0xff, (dmux_version >> 16) & 0xff,
              (dmux_version >> 8) & 0xff, dmux_version & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-mt")) {
       config->options.use_threads = 1;
     } else if (!strcmp(argv[c], "--")) {
-      if (c < argc - 1) kParams.file_name = argv[++c];
+      if (c < argc - 1) kParams.file_name = (const char*)GET_WARGV(argv, ++c);
       break;
     } else if (argv[c][0] == '-') {
       printf("Unknown option '%s'\n", argv[c]);
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     } else {
-      kParams.file_name = argv[c];
+      kParams.file_name = (const char*)GET_WARGV(argv, c);
     }
 
     if (parse_error) {
       Help();
-      return -1;
+      FREE_WARGV_AND_RETURN(-1);
     }
   }
 
   if (kParams.file_name == NULL) {
     printf("missing input file!!\n");
     Help();
-    return 0;
+    FREE_WARGV_AND_RETURN(0);
   }
 
   if (!ImgIoUtilReadFile(kParams.file_name,
@@ -577,16 +634,16 @@
 
   // Should only be reached when using FREEGLUT:
   ClearParams();
-  return 0;
+  FREE_WARGV_AND_RETURN(0);
 
  Error:
   ClearParams();
-  return -1;
+  FREE_WARGV_AND_RETURN(-1);
 }
 
 #else   // !WEBP_HAVE_GL
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]);
   (void)argc;
   return 0;
diff --git a/third_party/libwebp/examples/webpinfo.c b/third_party/libwebp/examples/webpinfo.c
index 2dcd277..356abae 100644
--- a/third_party/libwebp/examples/webpinfo.c
+++ b/third_party/libwebp/examples/webpinfo.c
@@ -20,6 +20,7 @@
 #endif
 
 #include "../imageio/imageio_util.h"
+#include "./unicode.h"
 #include "webp/decode.h"
 #include "webp/format_constants.h"
 #include "webp/mux_types.h"
@@ -40,6 +41,7 @@
     if (webp_info->show_diagnosis_) {            \
       fprintf(stderr, "Warning: %s\n", MESSAGE); \
     }                                            \
+    ++webp_info->num_warnings_;                  \
   } while (0)
 
 static const char* const kFormats[3] = {
@@ -115,6 +117,7 @@
   int is_processing_anim_frame_, seen_alpha_subchunk_, seen_image_subchunk_;
   // Print output control.
   int quiet_, show_diagnosis_, show_summary_;
+  int num_warnings_;
   int parse_bitstream_;
 } WebPInfo;
 
@@ -122,16 +125,16 @@
   memset(webp_info, 0, sizeof(*webp_info));
 }
 
-static const char kWebPChunkTags[CHUNK_TYPES][4] = {
-  { 'V', 'P', '8', ' ' },
-  { 'V', 'P', '8', 'L' },
-  { 'V', 'P', '8', 'X' },
-  { 'A', 'L', 'P', 'H' },
-  { 'A', 'N', 'I', 'M' },
-  { 'A', 'N', 'M', 'F' },
-  { 'I', 'C', 'C', 'P' },
-  { 'E', 'X', 'I', 'F' },
-  { 'X', 'M', 'P', ' ' },
+static const uint32_t kWebPChunkTags[CHUNK_TYPES] = {
+  MKFOURCC('V', 'P', '8', ' '),
+  MKFOURCC('V', 'P', '8', 'L'),
+  MKFOURCC('V', 'P', '8', 'X'),
+  MKFOURCC('A', 'L', 'P', 'H'),
+  MKFOURCC('A', 'N', 'I', 'M'),
+  MKFOURCC('A', 'N', 'M', 'F'),
+  MKFOURCC('I', 'C', 'C', 'P'),
+  MKFOURCC('E', 'X', 'I', 'F'),
+  MKFOURCC('X', 'M', 'P', ' '),
 };
 
 // -----------------------------------------------------------------------------
@@ -579,7 +582,7 @@
 // -----------------------------------------------------------------------------
 // Chunk parsing.
 
-static WebPInfoStatus ParseRIFFHeader(const WebPInfo* const webp_info,
+static WebPInfoStatus ParseRIFFHeader(WebPInfo* const webp_info,
                                       MemBuffer* const mem) {
   const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
   size_t riff_size;
@@ -641,7 +644,7 @@
       return WEBP_INFO_TRUNCATED_DATA;
     }
     for (i = 0; i < CHUNK_TYPES; ++i) {
-      if (!memcmp(kWebPChunkTags[i], &fourcc, TAG_SIZE)) break;
+      if (kWebPChunkTags[i] == fourcc) break;
     }
     chunk_data->offset_ = chunk_start_offset;
     chunk_data->size_ = chunk_size;
@@ -936,7 +939,13 @@
     LOG_WARN(error_message);
   } else {
     if (!webp_info->quiet_) {
-      const char* tag = kWebPChunkTags[chunk_data->id_];
+      char tag[4];
+      uint32_t fourcc = kWebPChunkTags[chunk_data->id_];
+#ifdef WORDS_BIGENDIAN
+      fourcc = (fourcc >> 24) | ((fourcc >> 8) & 0xff00) |
+               ((fourcc << 8) & 0xff0000) | (fourcc << 24);
+#endif
+      memcpy(tag, &fourcc, sizeof(tag));
       printf("Chunk %c%c%c%c at offset %6d, length %6d\n",
              tag[0], tag[1], tag[2], tag[3], (int)chunk_data->offset_,
              (int)chunk_data->size_);
@@ -987,7 +996,7 @@
   return status;
 }
 
-static WebPInfoStatus Validate(const WebPInfo* const webp_info) {
+static WebPInfoStatus Validate(WebPInfo* const webp_info) {
   if (webp_info->num_frames_ < 1) {
     LOG_ERROR("No image/frame detected.");
     return WEBP_INFO_MISSING_DATA;
@@ -1092,16 +1101,14 @@
     } else {
       printf("Errors detected.\n");
     }
+    if (webp_info->num_warnings_ > 0) {
+      printf("There were %d warning(s).\n", webp_info->num_warnings_);
+    }
   }
   return webp_info_status;
 }
 
-static void HelpShort(void) {
-  printf("Usage: webpinfo [options] in_files\n"
-         "Try -longhelp for an exhaustive list of options.\n");
-}
-
-static void HelpLong(void) {
+static void Help(void) {
   printf("Usage: webpinfo [options] in_files\n"
          "Note: there could be multiple input files;\n"
          "      options must come before input files.\n"
@@ -1119,19 +1126,19 @@
   WebPInfoStatus webp_info_status = WEBP_INFO_OK;
   WebPInfo webp_info;
 
+  INIT_WARGV(argc, argv);
+
   if (argc == 1) {
-    HelpShort();
-    return WEBP_INFO_OK;
+    Help();
+    FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
   }
 
   // Parse command-line input.
   for (c = 1; c < argc; ++c) {
-    if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
-      HelpShort();
-      return WEBP_INFO_OK;
-    } else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
-      HelpLong();
-      return WEBP_INFO_OK;
+    if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help") ||
+        !strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
+      Help();
+      FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
     } else if (!strcmp(argv[c], "-quiet")) {
       quiet = 1;
     } else if (!strcmp(argv[c], "-diag")) {
@@ -1144,35 +1151,36 @@
       const int version = WebPGetDecoderVersion();
       printf("WebP Decoder version: %d.%d.%d\n",
              (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else {  // Assume the remaining are all input files.
       break;
     }
   }
 
   if (c == argc) {
-    HelpShort();
-    return WEBP_INFO_INVALID_COMMAND;
+    Help();
+    FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
   }
 
   // Process input files one by one.
   for (; c < argc; ++c) {
     WebPData webp_data;
-    const char* in_file = NULL;
+    const W_CHAR* in_file = NULL;
     WebPInfoInit(&webp_info);
     webp_info.quiet_ = quiet;
     webp_info.show_diagnosis_ = show_diag;
     webp_info.show_summary_ = show_summary;
     webp_info.parse_bitstream_ = parse_bitstream;
-    in_file = argv[c];
-    if (in_file == NULL || !ReadFileToWebPData(in_file, &webp_data)) {
+    in_file = GET_WARGV(argv, c);
+    if (in_file == NULL ||
+        !ReadFileToWebPData((const char*)in_file, &webp_data)) {
       webp_info_status = WEBP_INFO_INVALID_COMMAND;
-      fprintf(stderr, "Failed to open input file %s.\n", in_file);
+      WFPRINTF(stderr, "Failed to open input file %s.\n", in_file);
       continue;
     }
-    if (!webp_info.quiet_) printf("File: %s\n", in_file);
+    if (!webp_info.quiet_) WPRINTF("File: %s\n", in_file);
     webp_info_status = AnalyzeWebP(&webp_info, &webp_data);
     WebPDataClear(&webp_data);
   }
-  return webp_info_status;
+  FREE_WARGV_AND_RETURN(webp_info_status);
 }
diff --git a/third_party/libwebp/examples/webpmux.c b/third_party/libwebp/examples/webpmux.c
index 55e8d21..b61eed6 100644
--- a/third_party/libwebp/examples/webpmux.c
+++ b/third_party/libwebp/examples/webpmux.c
@@ -26,6 +26,7 @@
     webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
     webpmux -set exif image_metadata.exif in.webp -o out_exif_container.webp
     webpmux -set xmp image_metadata.xmp in.webp -o out_xmp_container.webp
+    webpmux -set loop 1 in.webp -o out_looped.webp
 
   Extract relevant data from WebP container file:
     webpmux -get frame n in.webp -o out_frame.webp
@@ -62,6 +63,7 @@
 #include "webp/mux.h"
 #include "../examples/example_util.h"
 #include "../imageio/imageio_util.h"
+#include "./unicode.h"
 
 //------------------------------------------------------------------------------
 // Config object to parse command-line arguments.
@@ -96,6 +98,8 @@
   FEATURE_ICCP,
   FEATURE_ANMF,
   FEATURE_DURATION,
+  FEATURE_LOOP,
+  FEATURE_BGCOLOR,
   LAST_FEATURE
 } FeatureType;
 
@@ -312,10 +316,12 @@
 
   printf("\n");
   printf("SET_OPTIONS:\n");
-  printf(" Set color profile/metadata:\n");
-  printf("   icc  file.icc     set ICC profile\n");
-  printf("   exif file.exif    set EXIF metadata\n");
-  printf("   xmp  file.xmp     set XMP metadata\n");
+  printf(" Set color profile/metadata/parameters:\n");
+  printf("   loop LOOP_COUNT            set the loop count\n");
+  printf("   bgcolor BACKGROUND_COLOR   set the animation background color\n");
+  printf("   icc  file.icc              set ICC profile\n");
+  printf("   exif file.exif             set EXIF metadata\n");
+  printf("   xmp  file.xmp              set XMP metadata\n");
   printf("   where:    'file.icc' contains the ICC profile to be set,\n");
   printf("             'file.exif' contains the EXIF metadata to be set\n");
   printf("             'file.xmp' contains the XMP metadata to be set\n");
@@ -323,7 +329,7 @@
   printf("\n");
   printf("DURATION_OPTIONS:\n");
   printf(" Set duration of selected frames:\n");
-  printf("   duration            set duration for each frames\n");
+  printf("   duration            set duration for all frames\n");
   printf("   duration,frame      set duration of a particular frame\n");
   printf("   duration,start,end  set duration of frames in the\n");
   printf("                        interval [start,end])\n");
@@ -342,7 +348,7 @@
   printf("\n");
   printf("FRAME_OPTIONS(i):\n");
   printf(" Create animation:\n");
-  printf("   file_i +di+[xi+yi[+mi[bi]]]\n");
+  printf("   file_i +di[+xi+yi[+mi[bi]]]\n");
   printf("   where:    'file_i' is the i'th animation frame (WebP format),\n");
   printf("             'di' is the pause duration before next frame,\n");
   printf("             'xi','yi' specify the image offset for this frame,\n");
@@ -390,23 +396,25 @@
   *mux = WebPMuxCreate(&bitstream, 1);
   WebPDataClear(&bitstream);
   if (*mux != NULL) return 1;
-  fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
+  WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
+           (const W_CHAR*)filename);
   return 0;
 }
 
 static int WriteData(const char* filename, const WebPData* const webpdata) {
   int ok = 0;
-  FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb")
-                                     : ImgIoUtilSetBinaryMode(stdout);
+  FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
+                                      : ImgIoUtilSetBinaryMode(stdout);
   if (fout == NULL) {
-    fprintf(stderr, "Error opening output WebP file %s!\n", filename);
+    WFPRINTF(stderr, "Error opening output WebP file %s!\n",
+             (const W_CHAR*)filename);
     return 0;
   }
   if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
-    fprintf(stderr, "Error writing file %s!\n", filename);
+    WFPRINTF(stderr, "Error writing file %s!\n", (const W_CHAR*)filename);
   } else {
-    fprintf(stderr, "Saved file %s (%d bytes)\n",
-            filename, (int)webpdata->size);
+    WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
+             (const W_CHAR*)filename, (int)webpdata->size);
     ok = 1;
   }
   if (fout != stdout) fclose(fout);
@@ -452,7 +460,8 @@
     if (err == WEBP_MUX_OK && metadata.size > 0) {
       err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
       if (err != WEBP_MUX_OK) {
-        ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End);
+        ERROR_GOTO1("Error transferring metadata in DuplicateMuxHeader().",
+                    End);
       }
     }
   }
@@ -466,11 +475,11 @@
 }
 
 static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
-  int dispose_method, dummy;
+  int dispose_method, unused;
   char plus_minus, blend_method;
   const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration,
                               &info->x_offset, &info->y_offset, &dispose_method,
-                              &plus_minus, &blend_method, &dummy);
+                              &plus_minus, &blend_method, &unused);
   switch (num_args) {
     case 1:
       info->x_offset = info->y_offset = 0;  // fall through
@@ -489,7 +498,7 @@
 
   WarnAboutOddOffset(info);
 
-  // Note: The sanity of the following conversion is checked by
+  // Note: The validity of the following conversion is checked by
   // WebPMuxPushFrame().
   info->dispose_method = (WebPMuxAnimDispose)dispose_method;
 
@@ -595,26 +604,33 @@
 
 #define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
 
-#define CHECK_NUM_ARGS_LESS(NUM, LABEL)                                  \
+#define CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL)                              \
   if (argc < i + (NUM)) {                                                \
     fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]);    \
     goto LABEL;                                                          \
   }
 
-#define CHECK_NUM_ARGS_NOT_EQUAL(NUM, LABEL)                             \
-  if (argc != i + (NUM)) {                                               \
+#define CHECK_NUM_ARGS_AT_MOST(NUM, LABEL)                               \
+  if (argc > i + (NUM)) {                                                \
     fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]);   \
     goto LABEL;                                                          \
   }
 
+#define CHECK_NUM_ARGS_EXACTLY(NUM, LABEL)                               \
+  CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL);                                   \
+  CHECK_NUM_ARGS_AT_MOST(NUM, LABEL);
+
 // Parses command-line arguments to fill up config object. Also performs some
-// semantic checks.
-static int ParseCommandLine(Config* config) {
+// semantic checks. unicode_argv contains wchar_t arguments or is null.
+static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
   int i = 0;
   int feature_arg_index = 0;
   int ok = 1;
   int argc = config->cmd_args_.argc_;
   const char* const* argv = config->cmd_args_.argv_;
+  // Unicode file paths will be used if available.
+  const char* const* wargv =
+      (unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
 
   while (i < argc) {
     FeatureArg* const arg = &config->args_[feature_arg_index];
@@ -627,7 +643,7 @@
         }
         ++i;
       } else if (!strcmp(argv[i], "-duration")) {
-        CHECK_NUM_ARGS_LESS(2, ErrParse);
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
         if (ACTION_IS_NIL || config->action_type_ == ACTION_DURATION) {
           config->action_type_ = ACTION_DURATION;
         } else {
@@ -657,7 +673,7 @@
         }
         ++i;
       } else if (!strcmp(argv[i], "-frame")) {
-        CHECK_NUM_ARGS_LESS(3, ErrParse);
+        CHECK_NUM_ARGS_AT_LEAST(3, ErrParse);
         if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
           config->action_type_ = ACTION_SET;
         } else {
@@ -669,12 +685,12 @@
           ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
         }
         arg->subtype_ = SUBTYPE_ANMF;
-        arg->filename_ = argv[i + 1];
+        arg->filename_ = wargv[i + 1];
         arg->params_ = argv[i + 2];
         ++feature_arg_index;
         i += 3;
       } else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) {
-        CHECK_NUM_ARGS_LESS(2, ErrParse);
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
         if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
           config->action_type_ = ACTION_SET;
         } else {
@@ -691,34 +707,36 @@
         ++feature_arg_index;
         i += 2;
       } else if (!strcmp(argv[i], "-o")) {
-        CHECK_NUM_ARGS_LESS(2, ErrParse);
-        config->output_ = argv[i + 1];
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
+        config->output_ = wargv[i + 1];
         i += 2;
       } else if (!strcmp(argv[i], "-info")) {
-        CHECK_NUM_ARGS_NOT_EQUAL(2, ErrParse);
+        CHECK_NUM_ARGS_EXACTLY(2, ErrParse);
         if (config->action_type_ != NIL_ACTION) {
           ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
         } else {
           config->action_type_ = ACTION_INFO;
           config->arg_count_ = 0;
-          config->input_ = argv[i + 1];
+          config->input_ = wargv[i + 1];
         }
         i += 2;
       } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
         PrintHelp();
         DeleteConfig(config);
+        LOCAL_FREE((W_CHAR** const)unicode_argv);
         exit(0);
       } else if (!strcmp(argv[i], "-version")) {
         const int version = WebPGetMuxVersion();
         printf("%d.%d.%d\n",
                (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
         DeleteConfig(config);
+        LOCAL_FREE((W_CHAR** const)unicode_argv);
         exit(0);
       } else if (!strcmp(argv[i], "--")) {
         if (i < argc - 1) {
           ++i;
           if (config->input_ == NULL) {
-            config->input_ = argv[i];
+            config->input_ = wargv[i];
           } else {
             ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
                         argv[i], ErrParse);
@@ -742,8 +760,8 @@
           ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
         }
         if (config->action_type_ == ACTION_SET) {
-          CHECK_NUM_ARGS_LESS(2, ErrParse);
-          arg->filename_ = argv[i + 1];
+          CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
+          arg->filename_ = wargv[i + 1];
           ++feature_arg_index;
           i += 2;
         } else {
@@ -751,14 +769,28 @@
         }
       } else if (!strcmp(argv[i], "frame") &&
                  (config->action_type_ == ACTION_GET)) {
-        CHECK_NUM_ARGS_LESS(2, ErrParse);
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
         config->type_ = FEATURE_ANMF;
         arg->params_ = argv[i + 1];
         ++feature_arg_index;
         i += 2;
+      } else if (!strcmp(argv[i], "loop") &&
+                 (config->action_type_ == ACTION_SET)) {
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
+        config->type_ = FEATURE_LOOP;
+        arg->params_ = argv[i + 1];
+        ++feature_arg_index;
+        i += 2;
+      } else if (!strcmp(argv[i], "bgcolor") &&
+                 (config->action_type_ == ACTION_SET)) {
+        CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
+        config->type_ = FEATURE_BGCOLOR;
+        arg->params_ = argv[i + 1];
+        ++feature_arg_index;
+        i += 2;
       } else {  // Assume input file.
         if (config->input_ == NULL) {
-          config->input_ = argv[i];
+          config->input_ = wargv[i];
         } else {
           ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
                       argv[i], ErrParse);
@@ -804,8 +836,8 @@
 }
 
 // Create config object from command-line arguments.
-static int InitializeConfig(int argc, const char* argv[],
-                            Config* const config) {
+static int InitializeConfig(int argc, const char* argv[], Config* const config,
+                            const W_CHAR** const unicode_argv) {
   int num_feature_args = 0;
   int ok;
 
@@ -826,7 +858,7 @@
   }
 
   // Parse command-line.
-  if (!ParseCommandLine(config) || !ValidateConfig(config)) {
+  if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
     ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
   }
 
@@ -836,8 +868,9 @@
 
 #undef ACTION_IS_NIL
 #undef FEATURETYPE_IS_NIL
-#undef CHECK_NUM_ARGS_LESS
-#undef CHECK_NUM_ARGS_MORE
+#undef CHECK_NUM_ARGS_AT_LEAST
+#undef CHECK_NUM_ARGS_AT_MOST
+#undef CHECK_NUM_ARGS_EXACTLY
 
 //------------------------------------------------------------------------------
 // Processing.
@@ -998,13 +1031,62 @@
           ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
           if (!ok) goto Err2;
           err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
-          free((void*)chunk.bytes);
+          WebPDataClear(&chunk);
           if (err != WEBP_MUX_OK) {
             ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
                         ErrorString(err), kDescriptions[config->type_], Err2);
           }
           break;
         }
+        case FEATURE_LOOP: {
+          WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
+          int parse_error = 0;
+          const int loop_count =
+              ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
+          if (loop_count < 0 || loop_count > 65535 || parse_error) {
+            ERROR_GOTO1("ERROR: Loop count must be in the range 0 to 65535.\n",
+                        Err2);
+          }
+          ok = CreateMux(config->input_, &mux);
+          if (!ok) goto Err2;
+          ok = (WebPMuxGetAnimationParams(mux, &params) == WEBP_MUX_OK);
+          if (!ok) {
+            ERROR_GOTO1("ERROR: input file does not seem to be an animation.\n",
+                        Err2);
+          }
+          params.loop_count = loop_count;
+          err = WebPMuxSetAnimationParams(mux, &params);
+          ok = (err == WEBP_MUX_OK);
+          if (!ok) {
+            ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
+                        ErrorString(err), Err2);
+          }
+          break;
+        }
+        case FEATURE_BGCOLOR: {
+          WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
+          uint32_t bgcolor;
+          ok = ParseBgcolorArgs(config->args_[0].params_, &bgcolor);
+          if (!ok) {
+            ERROR_GOTO1("ERROR: Could not parse the background color.\n",
+                        Err2);
+          }
+          ok = CreateMux(config->input_, &mux);
+          if (!ok) goto Err2;
+          ok = (WebPMuxGetAnimationParams(mux, &params) == WEBP_MUX_OK);
+          if (!ok) {
+            ERROR_GOTO1("ERROR: input file does not seem to be an animation.\n",
+                        Err2);
+          }
+          params.bgcolor = bgcolor;
+          err = WebPMuxSetAnimationParams(mux, &params);
+          ok = (err == WEBP_MUX_OK);
+          if (!ok) {
+            ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
+                        ErrorString(err), Err2);
+          }
+          break;
+        }
         default: {
           ERROR_GOTO1("ERROR: Invalid feature for action 'set'.\n", Err2);
           break;
@@ -1032,7 +1114,7 @@
         int* durations = NULL;
         WebPMux* new_mux = DuplicateMuxHeader(mux);
         if (new_mux == NULL) goto Err2;
-        durations = (int*)malloc((size_t)num_frames * sizeof(*durations));
+        durations = (int*)WebPMalloc((size_t)num_frames * sizeof(*durations));
         if (durations == NULL) goto Err2;
         for (i = 0; i < num_frames; ++i) durations[i] = -1;
 
@@ -1090,7 +1172,7 @@
         new_mux = NULL;
 
  Err3:
-        free(durations);
+        WebPFree(durations);
         WebPMuxDelete(new_mux);
         if (!ok) goto Err2;
       }
@@ -1135,14 +1217,18 @@
 
 int main(int argc, const char* argv[]) {
   Config config;
-  int ok = InitializeConfig(argc - 1, argv + 1, &config);
+  int ok;
+
+  INIT_WARGV(argc, argv);
+
+  ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
   if (ok) {
     ok = Process(&config);
   } else {
     PrintHelp();
   }
   DeleteConfig(&config);
-  return !ok;
+  FREE_WARGV_AND_RETURN(!ok);
 }
 
 //------------------------------------------------------------------------------
diff --git a/third_party/libwebp/extras/Makefile.am b/third_party/libwebp/extras/Makefile.am
index 14d567a..7e29888 100644
--- a/third_party/libwebp/extras/Makefile.am
+++ b/third_party/libwebp/extras/Makefile.am
@@ -14,7 +14,7 @@
 
 noinst_PROGRAMS =
 noinst_PROGRAMS += webp_quality
-if WANT_DEMUX
+if BUILD_DEMUX
   noinst_PROGRAMS += get_disto
 endif
 if BUILD_VWEBP_SDL
diff --git a/third_party/libwebp/extras/extras.c b/third_party/libwebp/extras/extras.c
index 2feb595..3949b9e 100644
--- a/third_party/libwebp/extras/extras.c
+++ b/third_party/libwebp/extras/extras.c
@@ -12,13 +12,14 @@
 
 #include "extras/extras.h"
 #include "webp/format_constants.h"
+#include "src/dsp/dsp.h"
 
 #include <assert.h>
 #include <string.h>
 
 #define XTRA_MAJ_VERSION 1
-#define XTRA_MIN_VERSION 0
-#define XTRA_REV_VERSION 0
+#define XTRA_MIN_VERSION 3
+#define XTRA_REV_VERSION 1
 
 //------------------------------------------------------------------------------
 
@@ -57,7 +58,7 @@
   for (y = 0; y < pic->height; ++y) {
     const int width = pic->width;
     for (x = 0; x < width; ++x) {
-#ifdef WEBP_SWAP_16BIT_CSP
+#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
       const uint32_t rg = rgb565[2 * x + 1];
       const uint32_t gb = rgb565[2 * x + 0];
 #else
@@ -90,7 +91,7 @@
   for (y = 0; y < pic->height; ++y) {
     const int width = pic->width;
     for (x = 0; x < width; ++x) {
-#ifdef WEBP_SWAP_16BIT_CSP
+#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
       const uint32_t rg = rgb4444[2 * x + 1];
       const uint32_t ba = rgb4444[2 * x + 0];
 #else
@@ -144,3 +145,18 @@
 }
 
 //------------------------------------------------------------------------------
+
+int WebPUnmultiplyARGB(WebPPicture* pic) {
+  int y;
+  uint32_t* dst;
+  if (pic == NULL || pic->use_argb != 1 || pic->argb == NULL) return 0;
+  WebPInitAlphaProcessing();
+  dst = pic->argb;
+  for (y = 0; y < pic->height; ++y) {
+    WebPMultARGBRow(dst, pic->width, /*inverse=*/1);
+    dst += pic->argb_stride;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/third_party/libwebp/extras/extras.h b/third_party/libwebp/extras/extras.h
index fd4437a..c084682 100644
--- a/third_party/libwebp/extras/extras.h
+++ b/third_party/libwebp/extras/extras.h
@@ -19,7 +19,7 @@
 
 #include "webp/encode.h"
 
-#define WEBP_EXTRAS_ABI_VERSION 0x0001    // MAJOR(8b) + MINOR(8b)
+#define WEBP_EXTRAS_ABI_VERSION 0x0002    // MAJOR(8b) + MINOR(8b)
 
 //------------------------------------------------------------------------------
 
@@ -51,6 +51,13 @@
                           const uint32_t palette[], int palette_size,
                           WebPPicture* pic);
 
+// Convert the ARGB content of 'pic' from associated to unassociated.
+// 'pic' can be for instance the result of calling of some WebPPictureImportXXX
+// functions, with pic->use_argb set to 'true'. It is assumed (and not checked)
+// that the pre-multiplied r/g/b values as less or equal than the alpha value.
+// Return false in case of error (invalid parameter, ...).
+WEBP_EXTERN int WebPUnmultiplyARGB(WebPPicture* pic);
+
 //------------------------------------------------------------------------------
 
 // Parse a bitstream, search for VP8 (lossy) header and report a
@@ -67,4 +74,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_EXTRAS_EXTRAS_H_ */
+#endif  // WEBP_EXTRAS_EXTRAS_H_
diff --git a/third_party/libwebp/extras/get_disto.c b/third_party/libwebp/extras/get_disto.c
index b406147..3aa345b 100644
--- a/third_party/libwebp/extras/get_disto.c
+++ b/third_party/libwebp/extras/get_disto.c
@@ -26,6 +26,7 @@
 #include "webp/encode.h"
 #include "imageio/image_dec.h"
 #include "imageio/imageio_util.h"
+#include "../examples/unicode.h"
 
 static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
                           int keep_alpha) {
@@ -48,7 +49,8 @@
 
  End:
   if (!ok) {
-    fprintf(stderr, "Error! Could not process file %s\n", filename);
+    WFPRINTF(stderr, "Error! Could not process file %s\n",
+             (const W_CHAR*)filename);
   }
   free((void*)data);
   return ok ? data_size : 0;
@@ -221,10 +223,11 @@
           "  -o <file> . save the diff map as a WebP lossless file\n"
           "  -scale .... scale the difference map to fit [0..255] range\n"
           "  -gray ..... use grayscale for difference map (-scale)\n"
-          " Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
+          "\nSupported input formats:\n  %s\n",
+          WebPGetEnabledInputFileFormats());
 }
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   WebPPicture pic1, pic2;
   size_t size1 = 0, size2 = 0;
   int ret = 1;
@@ -239,9 +242,11 @@
   const char* name2 = NULL;
   const char* output = NULL;
 
+  INIT_WARGV(argc, argv);
+
   if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
     fprintf(stderr, "Can't init pictures\n");
-    return 1;
+    FREE_WARGV_AND_RETURN(1);
   }
 
   for (c = 1; c < argc; ++c) {
@@ -263,11 +268,11 @@
         fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
         goto End;
       }
-      output = argv[c];
+      output = (const char*)GET_WARGV(argv, c);
     } else if (name1 == NULL) {
-      name1 = argv[c];
+      name1 = (const char*)GET_WARGV(argv, c);
     } else {
-      name2 = argv[c];
+      name2 = (const char*)GET_WARGV(argv, c);
     }
   }
   if (help || name1 == NULL || name2 == NULL) {
@@ -347,5 +352,5 @@
  End:
   WebPPictureFree(&pic1);
   WebPPictureFree(&pic2);
-  return ret;
+  FREE_WARGV_AND_RETURN(ret);
 }
diff --git a/third_party/libwebp/extras/vwebp_sdl.c b/third_party/libwebp/extras/vwebp_sdl.c
index 69171b9..e9554eb 100644
--- a/third_party/libwebp/extras/vwebp_sdl.c
+++ b/third_party/libwebp/extras/vwebp_sdl.c
@@ -25,6 +25,7 @@
 #include "webp_to_sdl.h"
 #include "webp/decode.h"
 #include "imageio/imageio_util.h"
+#include "../examples/unicode.h"
 
 #if defined(WEBP_HAVE_JUST_SDL_H)
 #include <SDL.h>
@@ -51,29 +52,33 @@
 int main(int argc, char* argv[]) {
   int c;
   int ok = 0;
+
+  INIT_WARGV(argc, argv);
+
   for (c = 1; c < argc; ++c) {
     const char* file = NULL;
     const uint8_t* webp = NULL;
     size_t webp_size = 0;
     if (!strcmp(argv[c], "-h")) {
       printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]);
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else {
-      file = argv[c];
+      file = (const char*)GET_WARGV(argv, c);
     }
     if (file == NULL) continue;
     if (!ImgIoUtilReadFile(file, &webp, &webp_size)) {
-      fprintf(stderr, "Error opening file: %s\n", file);
+      WFPRINTF(stderr, "Error opening file: %s\n", (const W_CHAR*)file);
       goto Error;
     }
     if (webp_size != (size_t)(int)webp_size) {
+      free((void*)webp);
       fprintf(stderr, "File too large.\n");
       goto Error;
     }
-    ok = WebpToSDL((const char*)webp, (int)webp_size);
+    ok = WebPToSDL((const char*)webp, (int)webp_size);
     free((void*)webp);
     if (!ok) {
-      fprintf(stderr, "Error decoding file %s\n", file);
+      WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);
       goto Error;
     }
     ProcessEvents();
@@ -82,12 +87,12 @@
 
  Error:
   SDL_Quit();
-  return ok ? 0 : 1;
+  FREE_WARGV_AND_RETURN(ok ? 0 : 1);
 }
 
 #else  // !WEBP_HAVE_SDL
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
   (void)argc;
   return 0;
diff --git a/third_party/libwebp/extras/webp_quality.c b/third_party/libwebp/extras/webp_quality.c
index 3f6ba20..0a3b25f 100644
--- a/third_party/libwebp/extras/webp_quality.c
+++ b/third_party/libwebp/extras/webp_quality.c
@@ -13,26 +13,30 @@
 
 #include "extras/extras.h"
 #include "imageio/imageio_util.h"
+#include "../examples/unicode.h"
 
-int main(int argc, const char *argv[]) {
+int main(int argc, const char* argv[]) {
   int c;
   int quiet = 0;
   int ok = 1;
+
+  INIT_WARGV(argc, argv);
+
   for (c = 1; ok && c < argc; ++c) {
     if (!strcmp(argv[c], "-quiet")) {
       quiet = 1;
     } else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
       printf("webp_quality [-h][-quiet] webp_files...\n");
-      return 0;
+      FREE_WARGV_AND_RETURN(0);
     } else {
-      const char* const filename = argv[c];
+      const char* const filename = (const char*)GET_WARGV(argv, c);
       const uint8_t* data = NULL;
       size_t data_size = 0;
       int q;
       ok = ImgIoUtilReadFile(filename, &data, &data_size);
       if (!ok) break;
       q = VP8EstimateQuality(data, data_size);
-      if (!quiet) printf("[%s] ", filename);
+      if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename);
       if (q < 0) {
         fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
         ok = 0;
@@ -46,5 +50,5 @@
       free((void*)data);
     }
   }
-  return ok ? 0 : 1;
+  FREE_WARGV_AND_RETURN(ok ? 0 : 1);
 }
diff --git a/third_party/libwebp/extras/webp_to_sdl.c b/third_party/libwebp/extras/webp_to_sdl.c
index 2a74715..1e52681 100644
--- a/third_party/libwebp/extras/webp_to_sdl.c
+++ b/third_party/libwebp/extras/webp_to_sdl.c
@@ -29,7 +29,7 @@
 #endif
 
 static int init_ok = 0;
-int WebpToSDL(const char* data, unsigned int data_size) {
+int WebPToSDL(const char* data, unsigned int data_size) {
   int ok = 0;
   VP8StatusCode status;
   WebPDecoderConfig config;
@@ -40,7 +40,7 @@
 
   if (!WebPInitDecoderConfig(&config)) {
     fprintf(stderr, "Library version mismatch!\n");
-    return 1;
+    return 0;
   }
 
   if (!init_ok) {
diff --git a/third_party/libwebp/extras/webp_to_sdl.h b/third_party/libwebp/extras/webp_to_sdl.h
index 1b5ea98..1534f2b 100644
--- a/third_party/libwebp/extras/webp_to_sdl.h
+++ b/third_party/libwebp/extras/webp_to_sdl.h
@@ -14,9 +14,9 @@
 #ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_
 #define WEBP_EXTRAS_WEBP_TO_SDL_H_
 
-// Exports the method WebpToSDL(const char* data, int data_size) which decodes
+// Exports the method WebPToSDL(const char* data, int data_size) which decodes
 // a WebP bitstream into an RGBA SDL surface.
 // Return false on failure.
-extern int WebpToSDL(const char* data, unsigned int data_size);
+extern int WebPToSDL(const char* data, unsigned int data_size);
 
 #endif  // WEBP_EXTRAS_WEBP_TO_SDL_H_
diff --git a/third_party/libwebp/gradle/wrapper/gradle-wrapper.jar b/third_party/libwebp/gradle/wrapper/gradle-wrapper.jar
index ca78035..f3d88b1 100644
--- a/third_party/libwebp/gradle/wrapper/gradle-wrapper.jar
+++ b/third_party/libwebp/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/third_party/libwebp/gradle/wrapper/gradle-wrapper.properties b/third_party/libwebp/gradle/wrapper/gradle-wrapper.properties
index d556104..1b16c34 100644
--- a/third_party/libwebp/gradle/wrapper/gradle-wrapper.properties
+++ b/third_party/libwebp/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu May 12 17:06:25 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
diff --git a/third_party/libwebp/gradlew b/third_party/libwebp/gradlew
index 27309d9..2fe81a7 100755
--- a/third_party/libwebp/gradlew
+++ b/third_party/libwebp/gradlew
@@ -1,4 +1,20 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 
 ##############################################################################
 ##
@@ -28,16 +44,16 @@
 APP_BASE_NAME=`basename "$0"`
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD="maximum"
 
-warn ( ) {
+warn () {
     echo "$*"
 }
 
-die ( ) {
+die () {
     echo
     echo "$*"
     echo
@@ -109,8 +125,8 @@
     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 fi
 
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
     JAVACMD=`cygpath --unix "$JAVACMD"`
@@ -138,27 +154,30 @@
         else
             eval `echo args$i`="\"$arg\""
         fi
-        i=$((i+1))
+        i=`expr $i + 1`
     done
     case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
     esac
 fi
 
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
 }
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=`save "$@"`
 
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/third_party/libwebp/gradlew.bat b/third_party/libwebp/gradlew.bat
index f6d5974..24467a1 100644
--- a/third_party/libwebp/gradlew.bat
+++ b/third_party/libwebp/gradlew.bat
@@ -1,3 +1,19 @@
+@rem

+@rem Copyright 2015 the original author or authors.

+@rem

+@rem Licensed under the Apache License, Version 2.0 (the "License");

+@rem you may not use this file except in compliance with the License.

+@rem You may obtain a copy of the License at

+@rem

+@rem      https://www.apache.org/licenses/LICENSE-2.0

+@rem

+@rem Unless required by applicable law or agreed to in writing, software

+@rem distributed under the License is distributed on an "AS IS" BASIS,

+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+@rem See the License for the specific language governing permissions and

+@rem limitations under the License.

+@rem

+

 @if "%DEBUG%" == "" @echo off

 @rem ##########################################################################

 @rem

@@ -14,7 +30,7 @@
 set APP_HOME=%DIRNAME%

 

 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

-set DEFAULT_JVM_OPTS=

+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

 

 @rem Find java.exe

 if defined JAVA_HOME goto findJavaFromJavaHome

@@ -49,7 +65,6 @@
 @rem Get command-line arguments, handling Windows variants

 

 if not "%OS%" == "Windows_NT" goto win9xME_args

-if "%@eval[2+2]" == "4" goto 4NT_args

 

 :win9xME_args

 @rem Slurp the command line arguments.

@@ -60,11 +75,6 @@
 if "x%~1" == "x" goto execute

 

 set CMD_LINE_ARGS=%*

-goto execute

-

-:4NT_args

-@rem Get arguments from the 4NT Shell from JP Software

-set CMD_LINE_ARGS=%$

 

 :execute

 @rem Setup the command line

diff --git a/third_party/libwebp/imageio/Android.mk b/third_party/libwebp/imageio/Android.mk
index e779f71..1c8b836 100644
--- a/third_party/libwebp/imageio/Android.mk
+++ b/third_party/libwebp/imageio/Android.mk
@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 ################################################################################
@@ -52,3 +54,4 @@
 LOCAL_MODULE := imageenc
 
 include $(BUILD_STATIC_LIBRARY)
+endif  # NDK_ROOT
diff --git a/third_party/libwebp/imageio/Makefile.am b/third_party/libwebp/imageio/Makefile.am
index b0e6d8e..500ec7e 100644
--- a/third_party/libwebp/imageio/Makefile.am
+++ b/third_party/libwebp/imageio/Makefile.am
@@ -1,7 +1,7 @@
 AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
 noinst_LTLIBRARIES =
 noinst_LTLIBRARIES += libimageio_util.la
-if WANT_DEMUX
+if BUILD_DEMUX
   noinst_LTLIBRARIES += libimagedec.la
 endif
 noinst_LTLIBRARIES += libimageenc.la
diff --git a/third_party/libwebp/imageio/image_dec.c b/third_party/libwebp/imageio/image_dec.c
index 08a1b18..5e003fa 100644
--- a/third_party/libwebp/imageio/image_dec.c
+++ b/third_party/libwebp/imageio/image_dec.c
@@ -11,6 +11,24 @@
 
 #include "./image_dec.h"
 
+const char* WebPGetEnabledInputFileFormats(void) {
+  return "WebP"
+#ifdef WEBP_HAVE_JPEG
+         ", JPEG"
+#endif
+#ifdef WEBP_HAVE_PNG
+         ", PNG"
+#endif
+         ", PNM (PGM, PPM, PAM)"
+#ifdef WEBP_HAVE_TIFF
+         ", TIFF"
+#endif
+#ifdef HAVE_WINCODEC_H
+         ", Windows Imaging Component (WIC)"
+#endif
+         "";
+}
+
 static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) {
   return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
 }
diff --git a/third_party/libwebp/imageio/image_dec.h b/third_party/libwebp/imageio/image_dec.h
index df411e1..f09f564 100644
--- a/third_party/libwebp/imageio/image_dec.h
+++ b/third_party/libwebp/imageio/image_dec.h
@@ -41,6 +41,9 @@
   WEBP_UNSUPPORTED_FORMAT
 } WebPInputFileFormat;
 
+// Returns a comma separated list of enabled input formats.
+const char* WebPGetEnabledInputFileFormats(void);
+
 // Try to infer the image format. 'data_size' should be larger than 12.
 // Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely.
 WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
diff --git a/third_party/libwebp/imageio/image_enc.c b/third_party/libwebp/imageio/image_enc.c
index d413490..e06bcaf 100644
--- a/third_party/libwebp/imageio/image_enc.c
+++ b/third_party/libwebp/imageio/image_enc.c
@@ -29,11 +29,13 @@
                          // code with COBJMACROS.
 #include <ole2.h>  // CreateStreamOnHGlobal()
 #include <shlwapi.h>
+#include <tchar.h>
 #include <windows.h>
 #include <wincodec.h>
 #endif
 
 #include "./imageio_util.h"
+#include "../examples/unicode.h"
 
 //------------------------------------------------------------------------------
 // PNG
@@ -61,11 +63,12 @@
     // Output to a memory buffer. This is freed when 'stream' is released.
     IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
   } else {
-    IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
+    IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name,
+                             STGM_WRITE | STGM_CREATE, stream));
   }
   if (FAILED(hr)) {
-    fprintf(stderr, "Error opening output file %s (%08lx)\n",
-            out_file_name, hr);
+    _ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"),
+              (const LPTSTR)out_file_name, hr);
   }
   return hr;
 }
@@ -152,8 +155,8 @@
 }
 
 #elif defined(WEBP_HAVE_PNG)    // !HAVE_WINCODEC_H
-static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) {
-  (void)dummy;  // remove variable-unused warning
+static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp unused) {
+  (void)unused;  // remove variable-unused warning
   longjmp(png_jmpbuf(png), 1);
 }
 
@@ -277,7 +280,7 @@
 }
 
 //------------------------------------------------------------------------------
-// BMP
+// BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage)
 
 static void PutLE16(uint8_t* const dst, uint32_t value) {
   dst[0] = (value >> 0) & 0xff;
@@ -290,8 +293,11 @@
 }
 
 #define BMP_HEADER_SIZE 54
+#define BMP_HEADER_ALPHA_EXTRA_SIZE 16  // for alpha info
 int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
   const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
+  const int header_size =
+      BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0);
   const uint32_t width = buffer->width;
   const uint32_t height = buffer->height;
   const uint8_t* rgba = buffer->u.RGBA.rgba;
@@ -300,8 +306,9 @@
   uint32_t y;
   const uint32_t line_size = bytes_per_px * width;
   const uint32_t bmp_stride = (line_size + 3) & ~3;   // pad to 4
-  const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
-  uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
+  const uint32_t image_size = bmp_stride * height;
+  const uint32_t total_size =  image_size + header_size;
+  uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 };
 
   if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
 
@@ -309,30 +316,37 @@
   PutLE16(bmp_header + 0, 0x4d42);                // signature 'BM'
   PutLE32(bmp_header + 2, total_size);            // size including header
   PutLE32(bmp_header + 6, 0);                     // reserved
-  PutLE32(bmp_header + 10, BMP_HEADER_SIZE);      // offset to pixel array
+  PutLE32(bmp_header + 10, header_size);          // offset to pixel array
   // bitmap info header
-  PutLE32(bmp_header + 14, 40);                   // DIB header size
+  PutLE32(bmp_header + 14, header_size - 14);     // DIB header size
   PutLE32(bmp_header + 18, width);                // dimensions
-  PutLE32(bmp_header + 22, -(int)height);         // vertical flip!
+  PutLE32(bmp_header + 22, height);               // no vertical flip
   PutLE16(bmp_header + 26, 1);                    // number of planes
   PutLE16(bmp_header + 28, bytes_per_px * 8);     // bits per pixel
-  PutLE32(bmp_header + 30, 0);                    // no compression (BI_RGB)
-  PutLE32(bmp_header + 34, 0);                    // image size (dummy)
+  PutLE32(bmp_header + 30, has_alpha ? 3 : 0);    // BI_BITFIELDS or BI_RGB
+  PutLE32(bmp_header + 34, image_size);
   PutLE32(bmp_header + 38, 2400);                 // x pixels/meter
   PutLE32(bmp_header + 42, 2400);                 // y pixels/meter
   PutLE32(bmp_header + 46, 0);                    // number of palette colors
   PutLE32(bmp_header + 50, 0);                    // important color count
+  if (has_alpha) {  // BITMAPV3INFOHEADER complement
+    PutLE32(bmp_header + 54, 0x00ff0000);         // red mask
+    PutLE32(bmp_header + 58, 0x0000ff00);         // green mask
+    PutLE32(bmp_header + 62, 0x000000ff);         // blue mask
+    PutLE32(bmp_header + 66, 0xff000000);         // alpha mask
+  }
 
   // TODO(skal): color profile
 
   // write header
-  if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
+  if (fwrite(bmp_header, header_size, 1, fout) != 1) {
     return 0;
   }
 
-  // write pixel array
+  // write pixel array, bottom to top
   for (y = 0; y < height; ++y) {
-    if (fwrite(rgba, line_size, 1, fout) != 1) {
+    const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride];
+    if (fwrite(src, line_size, 1, fout) != 1) {
       return 0;
     }
     // write padding zeroes
@@ -342,11 +356,11 @@
         return 0;
       }
     }
-    rgba += stride;
   }
   return 1;
 }
 #undef BMP_HEADER_SIZE
+#undef BMP_HEADER_ALPHA_EXTRA_SIZE
 
 //------------------------------------------------------------------------------
 // TIFF
@@ -549,7 +563,8 @@
                   const char* const out_file_name) {
   FILE* fout = NULL;
   int needs_open_file = 1;
-  const int use_stdout = (out_file_name != NULL) && !strcmp(out_file_name, "-");
+  const int use_stdout =
+      (out_file_name != NULL) && !WSTRCMP(out_file_name, "-");
   int ok = 1;
 
   if (buffer == NULL || out_file_name == NULL) return 0;
@@ -560,9 +575,10 @@
 
   if (needs_open_file) {
     fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
-                      : fopen(out_file_name, "wb");
+                      : WFOPEN(out_file_name, "wb");
     if (fout == NULL) {
-      fprintf(stderr, "Error opening output file %s\n", out_file_name);
+      WFPRINTF(stderr, "Error opening output file %s\n",
+               (const W_CHAR*)out_file_name);
       return 0;
     }
   }
diff --git a/third_party/libwebp/imageio/image_enc.h b/third_party/libwebp/imageio/image_enc.h
index f8abdac..d31e4bd 100644
--- a/third_party/libwebp/imageio/image_enc.h
+++ b/third_party/libwebp/imageio/image_enc.h
@@ -79,7 +79,7 @@
 int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
 
 // Save as YUV samples as PGM format (using IMC4 layout).
-// See: http://www.fourcc.org/yuv.php#IMC4.
+// See: https://www.fourcc.org/yuv.php#IMC4.
 // (very convenient format for viewing the samples, esp. for odd dimensions).
 int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
 
diff --git a/third_party/libwebp/imageio/imageio_util.c b/third_party/libwebp/imageio/imageio_util.c
index 3a4ade0..df37137 100644
--- a/third_party/libwebp/imageio/imageio_util.c
+++ b/third_party/libwebp/imageio/imageio_util.c
@@ -18,6 +18,7 @@
 #endif
 #include <stdlib.h>
 #include <string.h>
+#include "../examples/unicode.h"
 
 // -----------------------------------------------------------------------------
 // File I/O
@@ -73,7 +74,7 @@
   uint8_t* file_data;
   size_t file_size;
   FILE* in;
-  const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
+  const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-");
 
   if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
 
@@ -81,29 +82,29 @@
   *data = NULL;
   *data_size = 0;
 
-  in = fopen(file_name, "rb");
+  in = WFOPEN(file_name, "rb");
   if (in == NULL) {
-    fprintf(stderr, "cannot open input file '%s'\n", file_name);
+    WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name);
     return 0;
   }
   fseek(in, 0, SEEK_END);
   file_size = ftell(in);
   fseek(in, 0, SEEK_SET);
   // we allocate one extra byte for the \0 terminator
-  file_data = (uint8_t*)malloc(file_size + 1);
+  file_data = (uint8_t*)WebPMalloc(file_size + 1);
   if (file_data == NULL) {
     fclose(in);
-    fprintf(stderr, "memory allocation failure when reading file %s\n",
-            file_name);
+    WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
+             (const W_CHAR*)file_name);
     return 0;
   }
   ok = (fread(file_data, file_size, 1, in) == 1);
   fclose(in);
 
   if (!ok) {
-    fprintf(stderr, "Could not read %d bytes of data from file %s\n",
-            (int)file_size, file_name);
-    free(file_data);
+    WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
+             (int)file_size, (const W_CHAR*)file_name);
+    WebPFree(file_data);
     return 0;
   }
   file_data[file_size] = '\0';  // convenient 0-terminator
@@ -118,14 +119,15 @@
                        const uint8_t* data, size_t data_size) {
   int ok;
   FILE* out;
-  const int to_stdout = (file_name == NULL) || !strcmp(file_name, "-");
+  const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-");
 
   if (data == NULL) {
     return 0;
   }
-  out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(file_name, "wb");
+  out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb");
   if (out == NULL) {
-    fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
+    WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
+             (const W_CHAR*)file_name);
     return 0;
   }
   ok = (fwrite(data, data_size, 1, out) == 1);
@@ -146,9 +148,11 @@
 
 // -----------------------------------------------------------------------------
 
-int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
-  const uint64_t total_size = nmemb * size;
+int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) {
+  const uint64_t total_size = stride * height;
   int ok = (total_size == (size_t)total_size);
+  // check that 'stride' is representable as int:
+  ok = ok && ((uint64_t)(int)stride == stride);
 #if defined(WEBP_MAX_IMAGE_SIZE)
   ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
 #endif
diff --git a/third_party/libwebp/imageio/imageio_util.h b/third_party/libwebp/imageio/imageio_util.h
index 72db159..f135f56 100644
--- a/third_party/libwebp/imageio/imageio_util.h
+++ b/third_party/libwebp/imageio/imageio_util.h
@@ -29,7 +29,7 @@
 
 // Allocates storage for entire file 'file_name' and returns contents and size
 // in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
-// be deleted using free().
+// be deleted using WebPFree().
 // Note: for convenience, the data will be null-terminated with an extra byte
 // (not accounted for in *data_size), in case the file is text and intended
 // to be used as a C-string.
@@ -54,8 +54,8 @@
 
 //------------------------------------------------------------------------------
 
-// Returns 0 in case of overflow of nmemb * size.
-int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size);
+// Returns 0 in case of overflow, memory over-allocation or excessive dimension.
+int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height);
 
 #ifdef __cplusplus
 }    // extern "C"
diff --git a/third_party/libwebp/imageio/jpegdec.c b/third_party/libwebp/imageio/jpegdec.c
index eefe92f..74a4c09 100644
--- a/third_party/libwebp/imageio/jpegdec.c
+++ b/third_party/libwebp/imageio/jpegdec.c
@@ -206,6 +206,7 @@
 
 static void my_error_exit(j_common_ptr dinfo) {
   struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
+  fprintf(stderr, "libjpeg error: ");
   dinfo->err->output_message(dinfo);
   longjmp(myerr->setjmp_buffer, 1);
 }
@@ -273,7 +274,7 @@
   ctx.data = data;
   ctx.data_size = data_size;
 
-  memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo));   // for setjmp sanity
+  memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo));   // for setjmp safety
   dinfo.err = jpeg_std_error(&jerr.pub);
   jerr.pub.error_exit = my_error_exit;
 
@@ -335,7 +336,11 @@
   pic->width = width;
   pic->height = height;
   ok = WebPPictureImportRGB(pic, rgb, (int)stride);
-  if (!ok) goto Error;
+  if (!ok) {
+    pic->width = 0;   // WebPPictureImportRGB() barely touches 'pic' on failure.
+    pic->height = 0;  // Just reset dimensions but keep any 'custom_ptr' etc.
+    MetadataFree(metadata);  // In case the caller forgets to free it on error.
+  }
 
  End:
   free(rgb);
diff --git a/third_party/libwebp/imageio/pngdec.c b/third_party/libwebp/imageio/pngdec.c
index 4622353..cdd9988 100644
--- a/third_party/libwebp/imageio/pngdec.c
+++ b/third_party/libwebp/imageio/pngdec.c
@@ -18,6 +18,9 @@
 #include <stdio.h>
 
 #ifdef WEBP_HAVE_PNG
+#ifndef PNG_USER_MEM_SUPPORTED
+#define PNG_USER_MEM_SUPPORTED  // for png_create_read_struct_2
+#endif
 #include <png.h>
 #include <setjmp.h>   // note: this must be included *after* png.h
 #include <stdlib.h>
@@ -27,11 +30,33 @@
 #include "./imageio_util.h"
 #include "./metadata.h"
 
+#define LOCAL_PNG_VERSION ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR)
+#define LOCAL_PNG_PREREQ(maj, min) \
+   (LOCAL_PNG_VERSION >= (((maj) << 8) | (min)))
+
 static void PNGAPI error_function(png_structp png, png_const_charp error) {
   if (error != NULL) fprintf(stderr, "libpng error: %s\n", error);
   longjmp(png_jmpbuf(png), 1);
 }
 
+#if LOCAL_PNG_PREREQ(1,4)
+typedef png_alloc_size_t LocalPngAllocSize;
+#else
+typedef png_size_t LocalPngAllocSize;
+#endif
+
+static png_voidp MallocFunc(png_structp png_ptr, LocalPngAllocSize size) {
+  (void)png_ptr;
+  if (size != (size_t)size) return NULL;
+  if (!ImgIoUtilCheckSizeArgumentsOverflow(size, 1)) return NULL;
+  return (png_voidp)malloc((size_t)size);
+}
+
+static void FreeFunc(png_structp png_ptr, png_voidp ptr) {
+  (void)png_ptr;
+  free(ptr);
+}
+
 // Converts the NULL terminated 'hexstring' which contains 2-byte character
 // representations of hex values to raw data.
 // 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs,
@@ -108,7 +133,7 @@
                  MetadataPayload* const payload);
   size_t storage_offset;
 } kPNGMetadataMap[] = {
-  // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
+  // https://exiftool.org/TagNames/PNG.html#TextualData
   // See also: ExifTool on CPAN.
   { "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
   { "Raw profile type xmp",  ProcessRawProfile, METADATA_OFFSET(xmp) },
@@ -171,11 +196,10 @@
     {
       png_charp name;
       int comp_type;
-#if ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR << 0) < \
-    ((1 << 8) | (5 << 0))
-      png_charp profile;
-#else  // >= libpng 1.5.0
+#if LOCAL_PNG_PREREQ(1,5)
       png_bytep profile;
+#else
+      png_charp profile;
 #endif
       png_uint_32 len;
 
@@ -211,7 +235,7 @@
   volatile png_infop end_info = NULL;
   PNGReadContext context = { NULL, 0, 0 };
   int color_type, bit_depth, interlaced;
-  int has_alpha;
+  int num_channels;
   int num_passes;
   int p;
   volatile int ok = 0;
@@ -224,7 +248,8 @@
   context.data = data;
   context.data_size = data_size;
 
-  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+  png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
+                                 NULL, MallocFunc, FreeFunc);
   if (png == NULL) goto End;
 
   png_set_error_fn(png, 0, error_function, NULL);
@@ -234,6 +259,15 @@
     goto End;
   }
 
+#if LOCAL_PNG_PREREQ(1,5) || \
+    (LOCAL_PNG_PREREQ(1,4) && PNG_LIBPNG_VER_RELEASE >= 1)
+  // If it looks like the bitstream is going to need more memory than libpng's
+  // internal limit (default: 8M), try to (reasonably) raise it.
+  if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) {
+    png_set_chunk_malloc_max(png, data_size);
+  }
+#endif
+
   info = png_create_info_struct(png);
   if (info == NULL) goto Error;
   end_info = png_create_info_struct(png);
@@ -259,9 +293,6 @@
   }
   if (png_get_valid(png, info, PNG_INFO_tRNS)) {
     png_set_tRNS_to_alpha(png);
-    has_alpha = 1;
-  } else {
-    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
   }
 
   // Apply gamma correction if needed.
@@ -276,13 +307,16 @@
 
   if (!keep_alpha) {
     png_set_strip_alpha(png);
-    has_alpha = 0;
   }
 
   num_passes = png_set_interlace_handling(png);
   png_read_update_info(png, info);
 
-  stride = (int64_t)(has_alpha ? 4 : 3) * width * sizeof(*rgb);
+  num_channels = png_get_channels(png, info);
+  if (num_channels != 3 && num_channels != 4) {
+    goto Error;
+  }
+  stride = (int64_t)num_channels * width * sizeof(*rgb);
   if (stride != (int)stride ||
       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
     goto Error;
@@ -307,8 +341,8 @@
 
   pic->width = (int)width;
   pic->height = (int)height;
-  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, (int)stride)
-                 : WebPPictureImportRGB(pic, rgb, (int)stride);
+  ok = (num_channels == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
+                           : WebPPictureImportRGB(pic, rgb, (int)stride);
 
   if (!ok) {
     goto Error;
diff --git a/third_party/libwebp/imageio/pnmdec.c b/third_party/libwebp/imageio/pnmdec.c
index 8f5a4a0..0d592c3 100644
--- a/third_party/libwebp/imageio/pnmdec.c
+++ b/third_party/libwebp/imageio/pnmdec.c
@@ -20,21 +20,25 @@
 #include "webp/encode.h"
 #include "./imageio_util.h"
 
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+
 typedef enum {
   WIDTH_FLAG      = 1 << 0,
   HEIGHT_FLAG     = 1 << 1,
   DEPTH_FLAG      = 1 << 2,
   MAXVAL_FLAG     = 1 << 3,
   TUPLE_FLAG      = 1 << 4,
-  ALL_NEEDED_FLAGS = 0x1f
+  ALL_NEEDED_FLAGS = WIDTH_FLAG | HEIGHT_FLAG | DEPTH_FLAG | MAXVAL_FLAG
 } PNMFlags;
 
 typedef struct {
   const uint8_t* data;
   size_t data_size;
   int width, height;
-  int bytes_per_px;   // 1, 3, 4
-  int depth;
+  int bytes_per_px;
+  int depth;          // 1 (grayscale), 2 (grayscale + alpha), 3 (rgb), 4 (rgba)
   int max_value;
   int type;           // 5, 6 or 7
   int seen_flags;
@@ -74,6 +78,7 @@
   char out[MAX_LINE_SIZE + 1];
   size_t out_size;
   int tmp;
+  int expected_depth = -1;
   assert(info != NULL);
   while (1) {
     off = ReadLine(info->data, off, info->data_size, out, &out_size);
@@ -95,38 +100,43 @@
       info->seen_flags |= MAXVAL_FLAG;
       info->max_value = tmp;
     } else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
-      info->bytes_per_px = 4;
+      expected_depth = 4;
       info->seen_flags |= TUPLE_FLAG;
     } else if (!strcmp(out, "TUPLTYPE RGB")) {
-      info->bytes_per_px = 3;
+      expected_depth = 3;
+      info->seen_flags |= TUPLE_FLAG;
+    } else if (!strcmp(out, "TUPLTYPE GRAYSCALE_ALPHA")) {
+      expected_depth = 2;
       info->seen_flags |= TUPLE_FLAG;
     } else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
-      info->bytes_per_px = 1;
+      expected_depth = 1;
       info->seen_flags |= TUPLE_FLAG;
     } else if (!strcmp(out, "ENDHDR")) {
       break;
     } else {
       static const char kEllipsis[] = " ...";
+      const size_t kLen = strlen(kEllipsis) + 1;  // +1 = trailing \0
       int i;
-      if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
+      if (out_size > 20) snprintf(out + 20 - kLen, kLen, kEllipsis);
       for (i = 0; i < (int)strlen(out); ++i) {
-        if (!isprint(out[i])) out[i] = ' ';
+        // isprint() might trigger a "char-subscripts" warning if given a char.
+        if (!isprint((int)out[i])) out[i] = ' ';
       }
       fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
       return 0;
     }
   }
-  if (!(info->seen_flags & TUPLE_FLAG)) {
-    if (info->depth > 0 && info->depth <= 4 && info->depth != 2) {
-      info->seen_flags |= TUPLE_FLAG;
-      info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
-    } else {
-      fprintf(stderr, "PAM: invalid bitdepth (%d).\n", info->depth);
-      return 0;
-    }
+  if (!(info->seen_flags & ALL_NEEDED_FLAGS)) {
+    fprintf(stderr, "PAM header error: missing tags%s%s%s%s\n",
+            (info->seen_flags & WIDTH_FLAG) ? "" : " WIDTH",
+            (info->seen_flags & HEIGHT_FLAG) ? "" : " HEIGHT",
+            (info->seen_flags & DEPTH_FLAG) ? "" : " DEPTH",
+            (info->seen_flags & MAXVAL_FLAG) ? "" : " MAXVAL");
+    return 0;
   }
-  if (info->seen_flags != ALL_NEEDED_FLAGS) {
-    fprintf(stderr, "PAM: incomplete header.\n");
+  if (expected_depth != -1 && info->depth != expected_depth) {
+    fprintf(stderr, "PAM header error: expected DEPTH %d but got DEPTH %d\n",
+            expected_depth, info->depth);
     return 0;
   }
   return off;
@@ -160,16 +170,15 @@
 
     // finish initializing missing fields
     info->depth = (info->type == 5) ? 1 : 3;
-    info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
   }
   // perform some basic numerical validation
   if (info->width <= 0 || info->height <= 0 ||
       info->type <= 0 || info->type >= 9 ||
-      info->depth <= 0 || info->depth == 2 || info->depth > 4 ||
-      info->bytes_per_px < info->depth ||
+      info->depth <= 0 || info->depth > 4 ||
       info->max_value <= 0 || info->max_value >= 65536) {
     return 0;
   }
+  info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
   return off;
 }
 
@@ -178,7 +187,7 @@
             struct Metadata* const metadata) {
   int ok = 0;
   int i, j;
-  uint64_t stride, pixel_bytes;
+  uint64_t stride, pixel_bytes, sample_size, depth;
   uint8_t* rgb = NULL, *tmp_rgb;
   size_t offset;
   PNMInfo info;
@@ -209,8 +218,10 @@
     fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
     goto End;
   }
-  stride =
-      (uint64_t)(info.bytes_per_px < 3 ? 3 : info.bytes_per_px) * info.width;
+  sample_size = (info.max_value > 255) ? 2 : 1;
+  // final depth
+  depth = (info.depth == 1 || info.depth == 3 || !keep_alpha) ? 3 : 4;
+  stride = depth * info.width;
   if (stride != (size_t)stride ||
       !ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
     goto End;
@@ -219,30 +230,63 @@
   rgb = (uint8_t*)malloc((size_t)stride * info.height);
   if (rgb == NULL) goto End;
 
-  // Convert input
+  // Convert input.
+  // We only optimize for the sample_size=1, max_value=255, depth=1 case.
   tmp_rgb = rgb;
   for (j = 0; j < info.height; ++j) {
-    assert(offset + info.bytes_per_px * info.width <= data_size);
-    if (info.depth == 1) {
-      // convert grayscale -> RGB
-      for (i = 0; i < info.width; ++i) {
-        const uint8_t v = data[offset + i];
-        tmp_rgb[3 * i + 0] = tmp_rgb[3 * i + 1] = tmp_rgb[3 * i + 2] = v;
-      }
-    } else if (info.depth == 3) {   // RGB
-      memcpy(tmp_rgb, data + offset, 3 * info.width * sizeof(*data));
-    } else if (info.depth == 4) {   // RGBA
-      memcpy(tmp_rgb, data + offset, 4 * info.width * sizeof(*data));
-    }
+    const uint8_t* in = data + offset;
     offset += info.bytes_per_px * info.width;
+    assert(offset <= data_size);
+    if (info.max_value == 255 && info.depth >= 3) {
+      // RGB or RGBA
+      if (info.depth == 3 || keep_alpha) {
+        memcpy(tmp_rgb, in, info.depth * info.width * sizeof(*in));
+      } else {
+        assert(info.depth == 4 && !keep_alpha);
+        for (i = 0; i < info.width; ++i) {
+          tmp_rgb[3 * i + 0] = in[4 * i + 0];
+          tmp_rgb[3 * i + 1] = in[4 * i + 1];
+          tmp_rgb[3 * i + 2] = in[4 * i + 2];
+        }
+      }
+    } else {
+      // Unoptimized case, we need to handle non-trivial operations:
+      //   * convert 16b to 8b (if max_value > 255)
+      //   * rescale to [0..255] range (if max_value != 255)
+      //   * drop the alpha channel (if keep_alpha is false)
+      const uint32_t round = info.max_value / 2;
+      int k = 0;
+      for (i = 0; i < info.width * info.depth; ++i) {
+        uint32_t v = (sample_size == 2) ? 256u * in[2 * i + 0] + in[2 * i + 1]
+                   : in[i];
+        if (info.max_value != 255) v = (v * 255u + round) / info.max_value;
+        if (v > 255u) v = 255u;
+        if (info.depth > 2) {
+          if (!keep_alpha && info.depth == 4 && (i % 4) == 3) {
+            // skip alpha
+          } else {
+            tmp_rgb[k] = v;
+            k += 1;
+          }
+        } else if (info.depth == 1 || (i % 2) == 0) {
+          tmp_rgb[k + 0] = tmp_rgb[k + 1] = tmp_rgb[k + 2] = v;
+          k += 3;
+        } else if (keep_alpha && info.depth == 2) {
+          tmp_rgb[k] = v;
+          k += 1;
+        } else {
+          // skip alpha
+        }
+      }
+    }
     tmp_rgb += stride;
   }
 
   // WebP conversion.
   pic->width = info.width;
   pic->height = info.height;
-  ok = (info.depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
-                         : WebPPictureImportRGB(pic, rgb, (int)stride);
+  ok = (depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
+                    : WebPPictureImportRGB(pic, rgb, (int)stride);
   if (!ok) goto End;
 
   ok = 1;
diff --git a/third_party/libwebp/imageio/tiffdec.c b/third_party/libwebp/imageio/tiffdec.c
index 92eb682..d711fa4 100644
--- a/third_party/libwebp/imageio/tiffdec.c
+++ b/third_party/libwebp/imageio/tiffdec.c
@@ -46,7 +46,7 @@
         (MetadataPayload*)((uint8_t*)metadata +
                            kTIFFMetadataMap[i].storage_offset);
     void* tag_data;
-    uint32 tag_data_len;
+    uint32_t tag_data_len;
 
     if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) &&
         !MetadataCopy((const char*)tag_data, tag_data_len, payload)) {
@@ -121,7 +121,6 @@
 // (we don't want to force a dependency to a libdspdec library).
 #define MFIX 24    // 24bit fixed-point arithmetic
 #define HALF ((1u << MFIX) >> 1)
-#define KINV_255 ((1u << MFIX) / 255u)
 
 static uint32_t Unmult(uint8_t x, uint32_t mult) {
   const uint32_t v = (x * mult + HALF) >> MFIX;
@@ -132,6 +131,9 @@
   return (255u << MFIX) / a;
 }
 
+#undef MFIX
+#undef HALF
+
 static void MultARGBRow(uint8_t* ptr, int width) {
   int x;
   for (x = 0; x < width; ++x, ptr += 4) {
@@ -154,7 +156,8 @@
              Metadata* const metadata) {
   MyData my_data = { data, (toff_t)data_size, 0 };
   TIFF* tif;
-  uint32_t width, height;
+  uint32_t image_width, image_height, tile_width, tile_height;
+  uint64_t stride;
   uint16_t samples_per_px = 0;
   uint16_t extra_samples = 0;
   uint16_t* extra_samples_ptr = NULL;
@@ -185,17 +188,40 @@
     fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
     goto End;
   }
-  if (samples_per_px < 3 || samples_per_px > 4) goto End;  // not supported
+  if (!(samples_per_px == 1 || samples_per_px == 3 || samples_per_px == 4)) {
+    goto End;  // not supported
+  }
 
-  if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
-        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
+  if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) &&
+        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) {
     fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
     goto End;
   }
-  if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height,
-                                           sizeof(*raster))) {
+  stride = (uint64_t)image_width * sizeof(*raster);
+  if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, image_height)) {
+    fprintf(stderr, "Error! TIFF image dimension (%d x %d) is too large.\n",
+            image_width, image_height);
     goto End;
   }
+
+  // According to spec, a tile can be bigger than the image. However it should
+  // be a multiple of 16 and not way too large, so check that it's not more
+  // than twice the image size, for dimensions above some arbitrary minimum
+  // 32. We also check that they respect WebP's dimension and memory limit.
+  // Note that a tile can be 6byte/px in some cases. Here we assume
+  // 4byte/px with sizeof(*raster), to be conservative.
+  if (TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
+      TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) {
+    if ((tile_width > 32 && tile_width / 2 > image_width) ||
+        (tile_height > 32 && tile_height / 2 > image_height) ||
+        !ImgIoUtilCheckSizeArgumentsOverflow(
+            (uint64_t)tile_width * sizeof(*raster), tile_height)) {
+      fprintf(stderr, "Error! TIFF tile dimension (%d x %d) is too large.\n",
+              tile_width, tile_height);
+      goto End;
+    }
+  }
+
   if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
                                           &extra_samples, &extra_samples_ptr)) {
     fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
@@ -203,33 +229,32 @@
   }
 
   // _Tiffmalloc uses a signed type for size.
-  alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster));
+  alloc_size = (int64_t)(stride * image_height);
   if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
 
-  raster = (uint32*)_TIFFmalloc((tsize_t)alloc_size);
+  raster = (uint32_t*)_TIFFmalloc((tsize_t)alloc_size);
   if (raster != NULL) {
-    if (TIFFReadRGBAImageOriented(tif, width, height, raster,
+    if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
                                   ORIENTATION_TOPLEFT, 1)) {
-      const int stride = width * sizeof(*raster);
-      pic->width = width;
-      pic->height = height;
+      pic->width = image_width;
+      pic->height = image_height;
       // TIFF data is ABGR
 #ifdef WORDS_BIGENDIAN
-      TIFFSwabArrayOfLong(raster, width * height);
+      TIFFSwabArrayOfLong(raster, image_width * image_height);
 #endif
       // if we have an alpha channel, we must un-multiply from rgbA to RGBA
       if (extra_samples == 1 && extra_samples_ptr != NULL &&
           extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
         uint32_t y;
         uint8_t* tmp = (uint8_t*)raster;
-        for (y = 0; y < height; ++y) {
-          MultARGBRow(tmp, width);
+        for (y = 0; y < image_height; ++y) {
+          MultARGBRow(tmp, image_width);
           tmp += stride;
         }
       }
       ok = keep_alpha
-         ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
-         : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
+         ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, (int)stride)
+         : WebPPictureImportRGBX(pic, (const uint8_t*)raster, (int)stride);
     }
     _TIFFfree(raster);
   } else {
diff --git a/third_party/libwebp/imageio/webpdec.c b/third_party/libwebp/imageio/webpdec.c
index a9d0654..aed60e1 100644
--- a/third_party/libwebp/imageio/webpdec.c
+++ b/third_party/libwebp/imageio/webpdec.c
@@ -22,6 +22,7 @@
 #include "webp/decode.h"
 #include "webp/demux.h"
 #include "webp/encode.h"
+#include "../examples/unicode.h"
 #include "./imageio_util.h"
 #include "./metadata.h"
 
@@ -43,7 +44,7 @@
 }
 
 void PrintWebPError(const char* const in_file, int status) {
-  fprintf(stderr, "Decoding of %s failed.\n", in_file);
+  WFPRINTF(stderr, "Decoding of %s failed.\n", (const W_CHAR*)in_file);
   fprintf(stderr, "Status: %d", status);
   if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
     fprintf(stderr, "(%s)", kStatusMessages[status]);
@@ -64,7 +65,7 @@
 
   status = WebPGetFeatures(*data, *data_size, bitstream);
   if (status != VP8_STATUS_OK) {
-    free((void*)*data);
+    WebPFree((void*)*data);
     *data = NULL;
     *data_size = 0;
     PrintWebPError(in_file, status);
@@ -94,7 +95,7 @@
   {
     WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
     if (idec == NULL) {
-      fprintf(stderr, "Failed during WebPINewDecoder().\n");
+      fprintf(stderr, "Failed during WebPIDecode().\n");
       return VP8_STATUS_OUT_OF_MEMORY;
     } else {
       status = WebPIUpdate(idec, data, data_size);
diff --git a/third_party/libwebp/imageio/wicdec.c b/third_party/libwebp/imageio/wicdec.c
index 3ee72a8..42001c6 100644
--- a/third_party/libwebp/imageio/wicdec.c
+++ b/third_party/libwebp/imageio/wicdec.c
@@ -29,12 +29,14 @@
                          // code with COBJMACROS.
 #include <ole2.h>  // CreateStreamOnHGlobal()
 #include <shlwapi.h>
+#include <tchar.h>
 #include <windows.h>
 #include <wincodec.h>
 
-#include "webp/encode.h"
+#include "../examples/unicode.h"
 #include "./imageio_util.h"
 #include "./metadata.h"
+#include "webp/encode.h"
 
 #define IFS(fn)                                                     \
   do {                                                              \
@@ -85,7 +87,7 @@
 
 static HRESULT OpenInputStream(const char* filename, IStream** stream) {
   HRESULT hr = S_OK;
-  if (!strcmp(filename, "-")) {
+  if (!WSTRCMP(filename, "-")) {
     const uint8_t* data = NULL;
     size_t data_size = 0;
     const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
@@ -108,11 +110,12 @@
       hr = E_FAIL;
     }
   } else {
-    IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
+    IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream));
   }
 
   if (FAILED(hr)) {
-    fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
+    _ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"),
+              (const LPTSTR)filename, hr);
   }
   return hr;
 }
@@ -131,7 +134,10 @@
   IWICColorContext** color_contexts;
 
   IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
-  if (FAILED(hr) || count == 0) return hr;
+  if (FAILED(hr) || count == 0) {
+    // Treat unsupported operation as a non-fatal error. See crbug.com/webp/506.
+    return (hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) ? S_OK : hr;
+  }
 
   color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
   if (color_contexts == NULL) return E_OUTOFMEMORY;
@@ -267,10 +273,15 @@
   WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
   const WICFormatImporter* importer = NULL;
   GUID src_container_format = GUID_NULL_;
+  // From Windows Kits\10\Include\10.0.19041.0\um\wincodec.h
+  WEBP_DEFINE_GUID(GUID_ContainerFormatWebp_,
+                   0xe094b0e2, 0x67f2, 0x45b3,
+                   0xb0, 0xea, 0x11, 0x53, 0x37, 0xca, 0x7c, 0xf3);
   static const GUID* kAlphaContainers[] = {
     &GUID_ContainerFormatBmp,
     &GUID_ContainerFormatPng,
     &GUID_ContainerFormatTiff,
+    &GUID_ContainerFormatWebp_,
     NULL
   };
   int has_alpha = 0;
@@ -295,9 +306,15 @@
           factory, stream, NULL,
           WICDecodeMetadataCacheOnDemand, &decoder));
   IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
-  if (SUCCEEDED(hr) && frame_count == 0) {
-    fprintf(stderr, "No frame found in input file.\n");
-    hr = E_FAIL;
+  if (SUCCEEDED(hr)) {
+    if (frame_count == 0) {
+      fprintf(stderr, "No frame found in input file.\n");
+      hr = E_FAIL;
+    } else if (frame_count > 1) {
+      // WIC will be tried before native WebP decoding so avoid duplicating the
+      // error message.
+      hr = E_FAIL;
+    }
   }
   IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
   IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
diff --git a/third_party/libwebp/infra/common.sh b/third_party/libwebp/infra/common.sh
new file mode 100644
index 0000000..b4892d5
--- /dev/null
+++ b/third_party/libwebp/infra/common.sh
@@ -0,0 +1,106 @@
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+log_err() {
+  echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
+}
+
+#######################################
+# Create build directory. Build directory will be deleted if it exists.
+# Arguments:
+#   None.
+# Returns:
+#   mkdir result.
+#######################################
+make_build_dir() {
+  if [[ "$#" -ne 1 ]]; then
+    return 1
+  fi
+
+  local build_dir
+  build_dir="$1"
+  rm -rf "${build_dir}"
+  mkdir -p "${build_dir}"
+}
+
+#######################################
+# Cleanup files from the build directory.
+# Globals:
+#   LIBWEBP_ROOT repository's root path.
+# Arguments:
+#   $1 build directory.
+#######################################
+cleanup() {
+  # $1 is not completely removed to allow for binary artifacts to be
+  # extracted.
+  find "${1:?"Build directory not defined"}" \
+    \( -name "*.[ao]" -o -name "*.l[ao]" \) -exec rm -f {} +
+}
+
+#######################################
+# Setup ccache for toolchain.
+# Globals:
+#   PATH
+# Arguments:
+#   None.
+#######################################
+setup_ccache() {
+  if [[ -x "$(command -v ccache)" ]]; then
+    export CCACHE_CPP2=yes
+    export PATH="/usr/lib/ccache:${PATH}"
+  fi
+}
+
+#######################################
+# Detects whether test block should be run in the current test shard.
+# Globals:
+#   TEST_TOTAL_SHARDS: Valid range: [1, N]. Defaults to 1.
+#   TEST_SHARD_INDEX: Valid range: [0, TEST_TOTAL_SHARDS). Defaults to 0.
+#   libwebp_test_id: current test number; incremented with each call.
+# Arguments:
+#   None
+# Returns:
+#   true if the shard is active
+#   false if the shard is inactive
+#######################################
+shard_should_run() {
+  TEST_TOTAL_SHARDS=${TEST_TOTAL_SHARDS:=1}
+  TEST_SHARD_INDEX=${TEST_SHARD_INDEX:=0}
+  libwebp_test_id=${libwebp_test_id:=-1}
+  : $((libwebp_test_id += 1))
+
+  if [[ "${TEST_SHARD_INDEX}" -lt 0 ||
+    "${TEST_SHARD_INDEX}" -ge "${TEST_TOTAL_SHARDS}" ]]; then
+    log_err "Invalid TEST_SHARD_INDEX (${TEST_SHARD_INDEX})!" \
+      "Expected [0, ${TEST_TOTAL_SHARDS})."
+  fi
+
+  [[ "$((libwebp_test_id % TEST_TOTAL_SHARDS))" -eq "${TEST_SHARD_INDEX}" ]]
+}
diff --git a/third_party/libwebp/infra/compile.sh b/third_party/libwebp/infra/compile.sh
new file mode 100755
index 0000000..18e9ebe
--- /dev/null
+++ b/third_party/libwebp/infra/compile.sh
@@ -0,0 +1,401 @@
+#!/bin/bash
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -xe
+LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
+WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.XXX)"}
+
+# shellcheck source=infra/common.sh
+source "${LIBWEBP_ROOT}/infra/common.sh"
+
+usage() {
+  cat << EOF
+Usage: compile.sh BUILD_TYPE TARGET
+Options:
+BUILD_TYPE  supported build type: (shared, static, static-debug)
+TARGET      supported target platforms:
+              aarch64-linux-clang
+              aarch64-linux-gnu
+              arm-linux-gnueabi
+              arm-neon-linux-gnueabi
+              cmake
+              cmake-aarch64
+              cmake-arm
+              cmake-clang
+              disable-near-lossless
+              disable-sse4.1
+              disable-stats
+              force-aligned-32
+              force-aligned-64
+              gradle
+              i686-linux-asan
+              i686-linux-clang
+              i686-linux-gnu
+              i686-w64-mingw32
+              mips2el-linux-gnu
+              mips32dspr2el-linux-gnu
+              mips32eb-linux-gnu
+              mips32el-linux-gnu
+              mips32r2el-linux-gnu
+              mips32r5el-linux-gnu
+              mips64r2el-linux-gnu
+              mips64r6el-linux-gnu
+              native
+              reduce-csp
+              reduce-size
+              reduce-size-disable-stats
+              visibility-default-gnu
+              visibility-hidden-clang
+              visibility-hidden-gnu
+              wasm
+              x86_64-linux-clang
+              x86_64-linux-gnu
+              x86_64-linux-msan
+              x86_64-w64-mingw32
+Environment variables:
+WORKSPACE   directory where the build is done
+EOF
+}
+
+################################################################################
+echo "Building libwebp in ${WORKSPACE}"
+
+if [[ ! -d "${WORKSPACE}" ]]; then
+  log_err "${WORKSPACE} directory does not exist"
+  exit 1
+fi
+
+BUILD_TYPE=${1:?"Build type not defined.$(
+  echo
+  usage
+)"}
+TARGET=${2:?"Target not defined.$(
+  echo
+  usage
+)"}
+readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
+
+trap 'cleanup ${BUILD_DIR}' EXIT
+make_build_dir "${BUILD_DIR}"
+
+config_flags=()
+case "${BUILD_TYPE}" in
+  shared*) ;;  # Valid BUILD_TYPE but no setup required
+  static*) config_flags+=("--disable-shared") ;;
+  experimental) config_flags+=("--enable-experimental") ;;
+  *)
+    log_err "Invalid BUILD_TYPE"
+    usage
+    exit 1
+    ;;
+esac
+
+if grep -m 1 -q "enable-asserts" "${LIBWEBP_ROOT}/configure.ac"; then
+  config_flags+=("--enable-asserts")
+fi
+
+case "${TARGET}" in
+  aarch64-linux-clang)
+    TARGET="aarch64-linux-gnu"
+    CC="clang"
+    CC="${CC} --target=aarch64-linux-gnu"
+    export CC
+    export CFLAGS="-isystem /usr/aarch64-linux-gnu/include"
+    ;;
+  arm-linux-gnueabi)
+    export CFLAGS="-O3 -march=armv7-a -mfloat-abi=softfp -ftree-vectorize"
+    ;;
+  arm-neon-linux-gnueabi)
+    TARGET="arm-linux-gnueabi"
+    CFLAGS="-O3 -march=armv7-a -mfpu=neon -mfloat-abi=softfp -ftree-vectorize"
+    export CFLAGS
+    ;;
+  mips2el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips2"
+    TARGET="mipsel-linux-gnu"
+    ;;
+  mips32el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips32"
+    TARGET="mipsel-linux-gnu"
+    ;;
+  mips32r2el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips32r2"
+    TARGET="mipsel-linux-gnu"
+    ;;
+  mips32dspr2el-linux-gnu)
+    export CFLAGS="-EL -O2 -mdspr2"
+    TARGET="mipsel-linux-gnu"
+    ;;
+  mips32r5el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips32r5 -mmsa"
+    TARGET="mipsel-linux-gnu"
+    ;;
+  mips32eb-linux-gnu)
+    export CFLAGS="-EB -O2 -mips32"
+    TARGET="mips-linux-gnu"
+    ;;
+  mips64r2el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips64r2 -mabi=64"
+    TARGET="mips64el-linux-gnuabi64"
+    ;;
+  mips64r6el-linux-gnu)
+    export CFLAGS="-EL -O2 -mips64r6 -mabi=64 -mmsa"
+    TARGET="mips-img-linux-gnu"
+    ;;
+  i686-linux-gnu)
+    export CC="gcc -m32"
+    ;;
+  i686-linux-clang)
+    TARGET="i686-linux-gnu"
+    export CC="clang -m32"
+    ;;
+  i686-linux-asan)
+    TARGET="i686-linux-gnu"
+    export CC="clang -m32 -fsanitize=address"
+    ;;
+  i686-linux-msan)
+    TARGET="i686-linux-gnu"
+    export CC="clang -m32 -fsanitize=memory"
+    ;;
+  x86_64-linux-clang)
+    TARGET="x86_64-linux-gnu"
+    export CC=clang
+    ;;
+  x86_64-linux-msan)
+    TARGET="x86_64-linux-gnu"
+    export CC="clang -fsanitize=memory"
+    ;;
+  force-aligned-32)
+    config_flags+=("--enable-aligned")
+    TARGET="i686-linux-gnu"
+    export CC="gcc -m32"
+    ;;
+  force-aligned-64)
+    config_flags+=("--enable-aligned")
+    TARGET="x86_64-linux-gnu"
+    ;;
+  visibility-default-*)
+    export CFLAGS="-O2 -g -fvisibility=default"
+    TARGET="x86_64-linux-gnu"
+    ;;
+  visibility-hidden-*)
+    export CFLAGS="-O2 -g -fvisibility=hidden"
+    if [[ "${TARGET}" = "visibility-hidden-clang" ]]; then
+      export CC=clang
+    fi
+    TARGET="x86_64-linux-gnu"
+    ;;
+  disable-sse4.1)
+    grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
+    config_flags+=("--${TARGET}")
+    TARGET="x86_64-linux-gnu"
+    ;;
+  disable-near-lossless)
+    grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
+    config_flags+=("--${TARGET}")
+    TARGET="x86_64-linux-gnu"
+    ;;
+  disable-stats)
+    git -C "${LIBWEBP_ROOT}" grep WEBP_DISABLE_STATS || exit 0
+    export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS"
+    TARGET="x86_64-linux-gnu"
+    ;;
+  reduce-size)
+    git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_SIZE || exit 0
+    export CFLAGS="-O2 -g -DWEBP_REDUCE_SIZE"
+    TARGET="x86_64-linux-gnu"
+    ;;
+  reduce-size-disable-stats)
+    git -C "${LIBWEBP_ROOT}" grep -e WEBP_DISABLE_STATS -e WEBP_REDUCE_SIZE \
+      || exit 0
+    export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS -DWEBP_REDUCE_SIZE"
+    TARGET="x86_64-linux-gnu"
+    ;;
+  reduce-csp)
+    git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_CSP || exit 0
+    export CFLAGS="-O2 -g -DWEBP_REDUCE_CSP"
+    TARGET="x86_64-linux-gnu"
+    ;;
+  x86_64-linux-gnu | *mingw32 | aarch64*) ;;  # Default target configuration
+  # non-configure based builds
+  native)
+    setup_ccache
+    # exercise makefile.unix then quit
+    make -C "${LIBWEBP_ROOT}" -f makefile.unix -j all
+    for tgt in extras examples/anim_diff; do
+      grep -q -m 1 "${tgt}" "${LIBWEBP_ROOT}/makefile.unix" \
+        && make -C "${LIBWEBP_ROOT}" -f makefile.unix -j "${tgt}"
+    done
+    [[ -d "${LIBWEBP_ROOT}/tests/fuzzer" ]] \
+      && make -j -C "${LIBWEBP_ROOT}/tests/fuzzer" -f makefile.unix
+    exit 0
+    ;;
+  cmake*)
+    setup_ccache
+    # exercise cmake then quit
+    opts=()
+    case "${TARGET}" in
+      cmake-clang)
+        opts+=("-DCMAKE_C_COMPILER=clang")
+        ;;
+      cmake-arm)
+        opts+=("-DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc")
+        case "${GERRIT_BRANCH:-}" in
+          portable-intrinsics | 0.6.1) exit 0 ;;
+          *) ;;  # Skip configuration
+        esac
+        ;;
+      cmake-aarch64)
+        opts+=("-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc")
+        case "${GERRIT_BRANCH:-}" in
+          portable-intrinsics | 0.6.1) exit 0 ;;
+          *) ;;  # Skip configuration
+        esac
+        ;;
+      *) ;;  # Skip configuration
+    esac
+    case "${BUILD_TYPE}" in
+      static*)
+        opts+=("-DBUILD_SHARED_LIBS=OFF")
+        ;;
+      experimental)
+        opts+=("-DWEBP_EXPERIMENTAL_FEATURES=ON" "-DBUILD_SHARED_LIBS=ON")
+        ;;
+      *)
+        opts+=("-DBUILD_SHARED_LIBS=ON")
+        ;;
+    esac
+    case "${BUILD_TYPE}" in
+      *debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
+      *) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
+    esac
+    cd "${BUILD_DIR}"
+    opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
+    grep -m 1 -q WEBP_BUILD_GIF2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
+      && opts+=("-DWEBP_BUILD_GIF2WEBP=ON")
+    grep -m 1 -q WEBP_BUILD_IMG2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
+      && opts+=("-DWEBP_BUILD_IMG2WEBP=ON")
+    cmake "${opts[@]}" "${LIBWEBP_ROOT}"
+    make VERBOSE=1 -j
+    case "${BUILD_TYPE}" in
+      static)
+        mkdir -p examples
+        cp [cd]webp examples
+        ;;
+      *) ;;  # Skip configuration.
+    esac
+
+    grep "install" "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
+
+    make DESTDIR="${BUILD_DIR}/webp-install" install/strip
+    mkdir tmp
+    cd tmp
+    cat > CMakeLists.txt << EOF
+cmake_minimum_required(VERSION 2.8.7)
+
+project(libwebp C)
+
+find_package(WebP)
+if (NOT WebP_FOUND)
+  message(FATAL_ERROR "WebP package not found")
+endif ()
+message("WebP_FOUND: \${WebP_FOUND}")
+message("WebP_INCLUDE_DIRS: \${WebP_INCLUDE_DIRS}")
+message("WebP_LIBRARIES: \${WebP_LIBRARIES}")
+message("WEBP_INCLUDE_DIRS: \${WEBP_INCLUDE_DIRS}")
+message("WEBP_LIBRARIES: \${WEBP_LIBRARIES}")
+EOF
+    cmake . "${opts[@]}" \
+      "-DCMAKE_PREFIX_PATH=${BUILD_DIR}/webp-install/usr/local"
+    exit 0
+    ;;
+  gradle)
+    setup_ccache
+    # exercise gradle then quit
+    [[ -f "${LIBWEBP_ROOT}/gradlew" ]] || exit 0
+
+    cd "${BUILD_DIR}"
+    # TODO -g / --gradle-user-home could be used if there's a race between jobs
+    "${LIBWEBP_ROOT}/gradlew" -p "${LIBWEBP_ROOT}" buildAllExecutables
+    exit 0
+    ;;
+  wasm)
+    grep -m 1 -q WEBP_ENABLE_WASM "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
+    opts+=("-DCMAKE_C_COMPILER=clang" "-DWEBP_ENABLE_WASM=ON")
+    opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
+    case "${BUILD_TYPE}" in
+      *debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
+      *) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
+    esac
+    cd "${BUILD_DIR}"
+    cmake "${opts[@]}" "${LIBWEBP_ROOT}"
+    make VERBOSE=1 -j
+    mkdir examples
+    case "${BUILD_TYPE}" in
+      static)
+        mkdir -p examples
+        cp [cd]webp examples
+        ;;
+      *) ;;  # Skip configuration
+    esac
+    exit 0
+    ;;
+  *)
+    log_err "Invalid TARGET"
+    usage
+    exit 1
+    ;;
+esac
+
+case "${TARGET}" in
+  *mingw32) ;;  # Skip configuration
+  *)
+    case "${TARGET}-${CC}" in
+      static-debug-gcc* | static-debug-)
+        CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
+        CXXFLAGS="${CXXFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
+        export CFLAGS CXXFLAGS
+        ;;
+      *) ;;  # This case should not be reached.
+    esac
+    ;;
+esac
+
+setup_ccache
+
+cd "${LIBWEBP_ROOT}"
+./autogen.sh
+
+cd "${BUILD_DIR}"
+"${LIBWEBP_ROOT}/configure" \
+  --host "${TARGET}" --build "$("${LIBWEBP_ROOT}/config.guess")" \
+  --enable-everything "${config_flags[@]}"
+make -j V=1
diff --git a/third_party/libwebp/infra/compile_android.sh b/third_party/libwebp/infra/compile_android.sh
new file mode 100755
index 0000000..013b97c
--- /dev/null
+++ b/third_party/libwebp/infra/compile_android.sh
@@ -0,0 +1,224 @@
+#!/bin/bash
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -xe
+LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
+readonly LIBWEBP_ROOT
+readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.android.XXX)"}
+# shellcheck source=infra/common.sh
+source "${LIBWEBP_ROOT}/infra/common.sh"
+
+usage() {
+  cat << EOF
+Usage: $(basename "$0") BUILD_TYPE APP_ABI
+Options:
+BUILD_TYPE  supported build types:
+              static
+              static-debug
+              shared
+              shared-debug
+APP_ABI     supported application binary interfaces:
+              armeabi-v7a
+              arm64-v8a
+              x86
+              x86_64
+Environment variables:
+WORKSPACE   directory where the build is done.
+ANDROID_NDK_DIR directory where the android ndk tools are.
+EOF
+}
+
+################################################################################
+echo "Building libwebp for Android in ${WORKSPACE}"
+
+if [[ ! -d "${WORKSPACE}" ]]; then
+  log_err "${WORKSPACE} directory does not exist."
+  exit 1
+fi
+
+readonly BUILD_TYPE=${1:?"BUILD_TYPE is not defined.$(
+  echo
+  usage
+)"}
+readonly APP_ABI=${2:?"APP_ABI not defined.$(
+  echo
+  usage
+)"}
+readonly ANDROID_NDK_DIR=${ANDROID_NDK_DIR:?"ANDROID_NDK_DIR is not defined.$(
+  echo
+  usage
+)"}
+readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
+readonly STANDALONE_ANDROID_DIR="${WORKSPACE}/android"
+
+if [[ ! -x "${ANDROID_NDK_DIR}/ndk-build" ]]; then
+  log_err "unable to find ndk-build in ANDROID_NDK_DIR: ${ANDROID_NDK_DIR}."
+  exit 1
+fi
+
+CFLAGS=
+LDFLAGS=
+opts=()
+case "${BUILD_TYPE}" in
+  *debug)
+    readonly APP_OPTIM="debug"
+    CFLAGS="-O0 -g"
+    opts+=("--enable-asserts")
+    ;;
+  static* | shared*)
+    readonly APP_OPTIM="release"
+    CFLAGS="-O2 -g"
+    ;;
+  *)
+    usage
+    exit 1
+    ;;
+esac
+
+case "${BUILD_TYPE}" in
+  shared*) readonly SHARED="1" ;;
+  *)
+    readonly SHARED="0"
+    CFLAGS="${CFLAGS} -fPIE"
+    LDFLAGS="${LDFLAGS} -Wl,-pie"
+    opts+=("--disable-shared")
+    ;;
+esac
+
+# Create a fresh build directory
+make_build_dir "${BUILD_DIR}"
+cd "${BUILD_DIR}"
+ln -s "${LIBWEBP_ROOT}" jni
+
+"${ANDROID_NDK_DIR}/ndk-build" -j2 \
+  APP_ABI="${APP_ABI}" \
+  APP_OPTIM="${APP_OPTIM}" \
+  ENABLE_SHARED="${SHARED}"
+
+cd "${LIBWEBP_ROOT}"
+./autogen.sh
+
+case "${APP_ABI}" in
+  armeabi*) arch="arm" ;;
+  arm64*) arch="arm64" ;;
+  *) arch="${APP_ABI}" ;;
+esac
+# TODO(b/185520507): remove this and use the binaries from
+# toolchains/llvm/prebuilt/ directly.
+rm -rf "${STANDALONE_ANDROID_DIR}"
+"${ANDROID_NDK_DIR}/build/tools/make_standalone_toolchain.py" \
+  --api 24 --arch "${arch}" --stl gnustl --install-dir \
+  "${STANDALONE_ANDROID_DIR}"
+export PATH="${STANDALONE_ANDROID_DIR}/bin:${PATH}"
+
+rm -rf "${BUILD_DIR}"
+make_build_dir "${BUILD_DIR}"
+cd "${BUILD_DIR}"
+
+case "${arch}" in
+  arm)
+    host="arm-linux-androideabi"
+    case "${APP_ABI}" in
+      armeabi) ;;
+      armeabi-v7a)
+        CFLAGS="${CFLAGS} -march=armv7-a -mfpu=neon -mfloat-abi=softfp"
+        ;;
+      *) ;;  # No configuration needed
+    esac
+    ;;
+  arm64)
+    host="aarch64-linux-android"
+    ;;
+  x86)
+    host="i686-linux-android"
+    ;;
+  x86_64)
+    host="x86_64-linux-android"
+    ;;
+  *) ;;  # Skip configuration
+esac
+
+setup_ccache
+CC="clang"
+
+"${LIBWEBP_ROOT}/configure" --host "${host}" --build \
+  "$("${LIBWEBP_ROOT}/config.guess")" CC="${CC}" CFLAGS="${CFLAGS}" \
+  LDFLAGS="${LDFLAGS}" "${opts[@]}"
+make -j
+
+if [[ "${GERRIT_REFSPEC:-}" = "refs/heads/portable-intrinsics" ]] \
+  || [[ "${GERRIT_BRANCH:-}" = "portable-intrinsics" ]]; then
+  cd "${WORKSPACE}"
+  rm -rf build && mkdir build
+  cd build
+  standalone="${WORKSPACE}/android"
+  cmake ../libwebp \
+    -DWEBP_BUILD_DWEBP=1 \
+    -DCMAKE_C_COMPILER="${standalone}/bin/clang" \
+    -DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
+    -DCMAKE_C_FLAGS=-fPIE \
+    -DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DWEBP_ENABLE_WASM=1
+  make -j2
+
+  cd "${WORKSPACE}"
+  make_build_dir "${BUILD_DIR}"
+  cd "${BUILD_DIR}"
+  case "${APP_ABI}" in
+    armeabi-v7a | arm64*)
+      cmake "${LIBWEBP_ROOT}" \
+        -DWEBP_BUILD_DWEBP=1 \
+        -DCMAKE_C_COMPILER="${standalone}/bin/clang" \
+        -DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
+        -DCMAKE_C_FLAGS='-fPIE -DENABLE_NEON_BUILTIN_MULHI_INT16X8' \
+        -DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
+        -DCMAKE_BUILD_TYPE=Release \
+        -DWEBP_ENABLE_WASM=1
+      make -j2
+      ;;
+    x86*)
+      cmake "${LIBWEBP_ROOT}" \
+        -DWEBP_BUILD_DWEBP=1 \
+        -DCMAKE_C_COMPILER="${standalone}/bin/clang" \
+        -DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
+        -DCMAKE_C_FLAGS='-fPIE -DENABLE_X86_BUILTIN_MULHI_INT16X8' \
+        -DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
+        -DCMAKE_BUILD_TYPE=Release \
+        -DWEBP_ENABLE_WASM=1
+      make -j2
+      ;;
+    *)
+      log_err "APP_ABI not supported."
+      exit 1
+      ;;
+  esac
+fi
diff --git a/third_party/libwebp/infra/compile_js.sh b/third_party/libwebp/infra/compile_js.sh
new file mode 100755
index 0000000..6a13fe6
--- /dev/null
+++ b/third_party/libwebp/infra/compile_js.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+readonly WORKSPACE="${WORKSPACE:-"$(mktemp -d -t webp.js.XXX)"}"
+readonly BUILD_DIR="${WORKSPACE}/webp_js/"
+readonly LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
+
+# shellcheck source=infra/common.sh
+source "${LIBWEBP_ROOT}/infra/common.sh"
+
+usage() {
+  cat << EOF
+Usage: $(basename "$0")
+Environment variables:
+WORKSPACE directory where the build is done
+EMSDK_DIR directory where emsdk is installed
+EOF
+}
+
+[[ -d "${EMSDK_DIR:?Not defined}" ]] \
+  || (log_err "${EMSDK_DIR} is not a valid directory." && exit 1)
+
+# shellcheck source=/opt/emsdk/emsdk_env.sh
+source "${EMSDK_DIR}/emsdk_env.sh"
+
+readonly EMSCRIPTEN=${EMSCRIPTEN:-"${EMSDK}/upstream/emscripten"}
+readonly \
+  EMSCRIPTEN_CMAKE_FILE="${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake"
+make_build_dir "${BUILD_DIR}"
+
+pushd "${BUILD_DIR}"
+opts=("-GUnix Makefiles" "-DWEBP_BUILD_WEBP_JS=ON")
+if [[ -z "$(command -v emcmake)" ]]; then
+  opts+=("-DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_CMAKE_FILE}")
+  cmake \
+    "${opts[@]}" \
+    "${LIBWEBP_ROOT}"
+  make -j
+else
+  emcmake cmake \
+    "${opts[@]}" \
+    "${LIBWEBP_ROOT}"
+  emmake make -j
+fi
+popd
diff --git a/third_party/libwebp/infra/run_static_analysis.sh b/third_party/libwebp/infra/run_static_analysis.sh
new file mode 100755
index 0000000..fa8445c
--- /dev/null
+++ b/third_party/libwebp/infra/run_static_analysis.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#
+#   * Neither the name of Google nor the names of its contributors may
+#     be used to endorse or promote products derived from this software
+#     without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -xe
+
+LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
+readonly LIBWEBP_ROOT
+readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.scanbuild.XXX)"}
+
+# shellcheck source=infra/common.sh
+source "${LIBWEBP_ROOT}/infra/common.sh"
+
+usage() {
+  cat << EOF
+Usage: $(basename "$0") MODE
+Options:
+MODE supported scan modes: (shallow|deep)
+Environment variables:
+WORKSPACE directory where the build is done.
+EOF
+}
+
+#######################################
+# Wrap clang-tools scan-build.
+# Globals:
+#   OUTPUT_DIR target directory where scan-build report is generated.
+#   MODE scan-build mode
+# Arguments:
+#   $* scan-build additional args.
+# Returns:
+#   scan-build retcode
+#######################################
+scan_build() {
+  scan-build -o "${OUTPUT_DIR}" --use-analyzer="$(command -v clang)" \
+    -analyzer-config mode="${MODE}" "$*"
+}
+
+MODE=${1:?"MODE is not specified.$(
+  echo
+  usage
+)"}
+
+readonly OUTPUT_DIR="${WORKSPACE}/output-${MODE}"
+readonly BUILD_DIR="${WORKSPACE}/build"
+
+make_build_dir "${OUTPUT_DIR}"
+make_build_dir "${BUILD_DIR}"
+
+cd "${LIBWEBP_ROOT}"
+./autogen.sh
+
+cd "${BUILD_DIR}"
+grep -m 1 -q 'enable-asserts' "${LIBWEBP_ROOT}/configure.ac" \
+    && args='--enable-asserts'
+scan_build "${LIBWEBP_ROOT}/configure" --enable-everything "${args}"
+scan_build make -j4
+
+index="$(find "${OUTPUT_DIR}" -name index.html)"
+if [[ -f "${index}" ]]; then
+  mv "$(dirname "${index}")/"* "${OUTPUT_DIR}"
+else
+  # make a empty report to wipe out any old bug reports.
+  cat << EOT > "${OUTPUT_DIR}/index.html"
+<html>
+<body>
+No bugs reported.
+</body>
+</html>
+EOT
+fi
diff --git a/third_party/libwebp/iosbuild.sh b/third_party/libwebp/iosbuild.sh
index 971efc8..cd3a24c 100755
--- a/third_party/libwebp/iosbuild.sh
+++ b/third_party/libwebp/iosbuild.sh
@@ -1,17 +1,21 @@
 #!/bin/bash
 #
-# This script generates 'WebP.framework' and 'WebPDecoder.framework'. An iOS
-# app can decode WebP images by including 'WebPDecoder.framework' and both
-# encode and decode WebP images by including 'WebP.framework'.
+# This script generates 'WebP.framework' and 'WebPDecoder.framework',
+# 'WebPDemux.framework' and 'WebPMux.framework'.
+# An iOS app can decode WebP images by including 'WebPDecoder.framework' and
+# both encode and decode WebP images by including 'WebP.framework'.
 #
 # Run ./iosbuild.sh to generate the frameworks under the current directory
 # (the previous build will be erased if it exists).
 #
 # This script is inspired by the build script written by Carson McDonald.
-# (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
+# (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
 
 set -e
 
+# Set this variable based on the desired minimum deployment target.
+readonly IOS_MIN_VERSION=6.0
+
 # Extract the latest SDK version from the final field of the form: iphoneosX.Y
 readonly SDK=$(xcodebuild -showsdks \
   | grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
@@ -35,35 +39,55 @@
 readonly BUILDDIR="${TOPDIR}/iosbuild"
 readonly TARGETDIR="${TOPDIR}/WebP.framework"
 readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
+readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
+readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
 readonly DEVELOPER=$(xcode-select --print-path)
 readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
 readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
 LIBLIST=''
 DECLIBLIST=''
+MUXLIBLIST=''
+DEMUXLIBLIST=''
 
 if [[ -z "${SDK}" ]]; then
   echo "iOS SDK not available"
   exit 1
 elif [[ ${SDK%%.*} -gt 8 ]]; then
   EXTRA_CFLAGS="-fembed-bitcode"
-elif [[ ${SDK} < 6.0 ]]; then
+elif [[ ${SDK%%.*} -le 6 ]]; then
   echo "You need iOS SDK version 6.0 or above"
   exit 1
-else
-  echo "iOS SDK Version ${SDK}"
 fi
 
-rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR}
-mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/
+echo "Xcode Version: ${XCODE}"
+echo "iOS SDK Version: ${SDK}"
+
+if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
+      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
+  cat << EOF
+WARNING: The following directories will be deleted:
+WARNING:   ${BUILDDIR}
+WARNING:   ${TARGETDIR}
+WARNING:   ${DECTARGETDIR}
+WARNING:   ${MUXTARGETDIR}
+WARNING:   ${DEMUXTARGETDIR}
+WARNING: The build will continue in 5 seconds...
+EOF
+  sleep 5
+fi
+rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
+    ${MUXTARGETDIR} ${DEMUXTARGETDIR}
+mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
+    ${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
 
 if [[ ! -e ${SRCDIR}/configure ]]; then
   if ! (cd ${SRCDIR} && sh autogen.sh); then
-    cat <<EOT
+    cat << EOF
 Error creating configure script!
 This script requires the autoconf/automake and libtool to build. MacPorts can
 be used to obtain these:
-http://www.macports.org/install.php
-EOT
+https://www.macports.org/install.php
+EOF
     exit 1
   fi
 fi
@@ -97,7 +121,7 @@
   SDKROOT="${PLATFORMSROOT}/"
   SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/"
   CFLAGS="-arch ${ARCH2:-${ARCH}} -pipe -isysroot ${SDKROOT} -O3 -DNDEBUG"
-  CFLAGS+=" -miphoneos-version-min=6.0 ${EXTRA_CFLAGS}"
+  CFLAGS+=" -miphoneos-version-min=${IOS_MIN_VERSION} ${EXTRA_CFLAGS}"
 
   set -x
   export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
@@ -105,25 +129,40 @@
     --build=$(${SRCDIR}/config.guess) \
     --disable-shared --enable-static \
     --enable-libwebpdecoder --enable-swap-16bit-csp \
+    --enable-libwebpmux \
     CFLAGS="${CFLAGS}"
   set +x
 
-  # run make only in the src/ directory to create libwebp.a/libwebpdecoder.a
-  cd src/
-  make V=0
-  make install
+  # Build only the libraries, skip the examples.
+  make V=0 -C sharpyuv
+  make V=0 -C src install
 
   LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
   DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
+  MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
+  DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
 
   make clean
-  cd ..
 
   export PATH=${OLDPATH}
 done
 
+echo "LIBLIST = ${LIBLIST}"
 cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
 ${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
 
+echo "DECLIBLIST = ${DECLIBLIST}"
 cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
 ${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder
+
+echo "MUXLIBLIST = ${MUXLIBLIST}"
+cp -a ${SRCDIR}/src/webp/{types,mux,mux_types}.h \
+    ${MUXTARGETDIR}/Headers/
+${LIPO} -create ${MUXLIBLIST} -output ${MUXTARGETDIR}/WebPMux
+
+echo "DEMUXLIBLIST = ${DEMUXLIBLIST}"
+cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
+    ${DEMUXTARGETDIR}/Headers/
+${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
+
+echo  "SUCCESS"
diff --git a/third_party/libwebp/libwebp.gni b/third_party/libwebp/libwebp.gni
index cba22f5..4cd75f6 100644
--- a/third_party/libwebp/libwebp.gni
+++ b/third_party/libwebp/libwebp.gni
@@ -97,9 +97,9 @@
   "src/dsp/cost.c",
   "src/dsp/cost_mips32.c",
   "src/dsp/cost_mips_dsp_r2.c",
+  "src/dsp/cost_neon.c",
   "src/dsp/cost_sse2.c",
   "src/dsp/enc.c",
-  "src/dsp/enc_avx2.c",
   "src/dsp/enc_mips32.c",
   "src/dsp/enc_mips_dsp_r2.c",
   "src/dsp/enc_msa.c",
@@ -113,6 +113,7 @@
   "src/dsp/lossless_enc_neon.c",
   "src/dsp/lossless_enc_sse2.c",
   "src/dsp/lossless_enc_sse41.c",
+  "src/dsp/lossless_sse41.c",
   "src/dsp/ssim.c",
   "src/dsp/ssim_sse2.c",
 ]
@@ -143,6 +144,16 @@
   "src/enc/webp_enc.c",
 ]
 
+libwebp_sharpyuv_sources = [
+  "sharpyuv/sharpyuv.c",
+  "sharpyuv/sharpyuv_cpu.c",
+  "sharpyuv/sharpyuv_csp.c",
+  "sharpyuv/sharpyuv_dsp.c",
+  "sharpyuv/sharpyuv_gamma.c",
+  "sharpyuv/sharpyuv_neon.c",
+  "sharpyuv/sharpyuv_sse2.c",
+]
+
 libwebp_format_dec_sources = [
   "imageio/image_dec.c",
   "imageio/jpegdec.c",
diff --git a/third_party/libwebp/makefile.unix b/third_party/libwebp/makefile.unix
index cc0035d..8348d10 100644
--- a/third_party/libwebp/makefile.unix
+++ b/third_party/libwebp/makefile.unix
@@ -3,7 +3,8 @@
 # It will not install the libraries system-wide, but just create the 'cwebp'
 # and 'dwebp' tools in the examples/ directory, along with the static
 # libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a',
-# 'src/demux/libwebpdemux.a' and 'extras/libwebpextras.a'.
+# 'src/demux/libwebpdemux.a', 'extras/libwebpextras.a' and
+# 'sharpyuv/libsharpyuv.a'.
 #
 # To build the library and examples, use:
 #    make -f makefile.unix
@@ -47,7 +48,7 @@
 endif
 
 # To install libraries on Mac OS X:
-# 1. Install MacPorts (http://www.macports.org/install.php)
+# 1. Install MacPorts (https://www.macports.org/install.php)
 # 2. Run "sudo port install jpeg"
 # 3. Run "sudo port install libpng"
 # 4. Run "sudo port install tiff"
@@ -89,12 +90,6 @@
 src/dsp/%_sse41.o: EXTRA_FLAGS += -msse4.1
 endif
 
-# AVX2-specific flags:
-ifeq ($(HAVE_AVX2), 1)
-EXTRA_FLAGS += -DWEBP_HAVE_AVX2
-src/dsp/%_avx2.o: EXTRA_FLAGS += -mavx2
-endif
-
 # NEON-specific flags:
 # EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
 # -> seems to make the overall lib slower: -fno-split-wide-types
@@ -124,9 +119,22 @@
 COL = /usr/bin/col
 LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
 
+ifdef BITTRACE
+CFLAGS += -DBITTRACE=$(BITTRACE)
+endif
+
 ANIM_UTIL_OBJS = \
     examples/anim_util.o \
 
+SHARPYUV_OBJS = \
+    sharpyuv/sharpyuv.o \
+    sharpyuv/sharpyuv_cpu.o \
+    sharpyuv/sharpyuv_csp.o \
+    sharpyuv/sharpyuv_dsp.o \
+    sharpyuv/sharpyuv_gamma.o \
+    sharpyuv/sharpyuv_neon.o \
+    sharpyuv/sharpyuv_sse2.o \
+
 DEC_OBJS = \
     src/dec/alpha_dec.o \
     src/dec/buffer_dec.o \
@@ -168,6 +176,7 @@
     src/dsp/lossless_msa.o \
     src/dsp/lossless_neon.o \
     src/dsp/lossless_sse2.o \
+    src/dsp/lossless_sse41.o \
     src/dsp/rescaler.o \
     src/dsp/rescaler_mips32.o \
     src/dsp/rescaler_mips_dsp_r2.o \
@@ -191,9 +200,9 @@
     src/dsp/cost.o \
     src/dsp/cost_mips32.o \
     src/dsp/cost_mips_dsp_r2.o \
+    src/dsp/cost_neon.o \
     src/dsp/cost_sse2.o \
     src/dsp/enc.o \
-    src/dsp/enc_avx2.o \
     src/dsp/enc_mips32.o \
     src/dsp/enc_mips_dsp_r2.o \
     src/dsp/enc_msa.o \
@@ -283,11 +292,12 @@
     extras/quality_estimate.o \
 
 LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
-               $(UTILS_ENC_OBJS)
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
+               $(DSP_ENC_OBJS) $(UTILS_ENC_OBJS)
 LIBWEBPMUX_OBJS = $(MUX_OBJS)
 LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
 LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
 
 HDRS_INSTALLED = \
     src/webp/decode.h \
@@ -297,6 +307,11 @@
     src/webp/mux_types.h \
     src/webp/types.h \
 
+SHARPYUV_HDRS_INSTALLED = \
+    sharpyuv/sharpyuv.h \
+    sharpyuv/sharpyuv_cpu.h \
+    sharpyuv/sharpyuv_csp.h \
+
 HDRS = \
     src/dec/alphai_dec.h \
     src/dec/common_dec.h \
@@ -305,6 +320,7 @@
     src/dec/vp8li_dec.h \
     src/dec/webpi_dec.h \
     src/dsp/common_sse2.h \
+    src/dsp/cpu.h \
     src/dsp/dsp.h \
     src/dsp/lossless.h \
     src/dsp/lossless_common.h \
@@ -335,6 +351,7 @@
     src/utils/utils.h \
     src/webp/format_constants.h \
     $(HDRS_INSTALLED) \
+    $(SHARPYUV_HDRS_INSTALLED) \
 
 OUT_LIBS = examples/libexample_util.a
 OUT_LIBS += imageio/libimageio_util.a
@@ -342,6 +359,7 @@
 OUT_LIBS += imageio/libimageenc.a
 OUT_LIBS += src/libwebpdecoder.a
 OUT_LIBS += src/libwebp.a
+OUT_LIBS += sharpyuv/libsharpyuv.a
 EXTRA_LIB = extras/libwebpextras.a
 OUT_EXAMPLES = examples/cwebp examples/dwebp
 EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
@@ -387,12 +405,13 @@
 src/libwebp.a: $(LIBWEBP_OBJS)
 src/mux/libwebpmux.a: $(LIBWEBPMUX_OBJS)
 src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
+sharpyuv/libsharpyuv.a: $(LIBSHARPYUV_OBJS)
 
 %.a:
 	$(AR) $(ARFLAGS) $@ $^
 
 examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
-examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS)
+examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
 examples/cwebp: examples/cwebp.o
 examples/dwebp: examples/dwebp.o
 examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
@@ -404,43 +423,51 @@
 examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
 examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
 examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
-examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
+examples/anim_diff: sharpyuv/libsharpyuv.a
+examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS)
 examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
-examples/anim_dump: examples/libanim_util.a
+examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
 examples/anim_dump: src/demux/libwebpdemux.a
 examples/anim_dump: examples/libexample_util.a
 examples/anim_dump: imageio/libimageio_util.a
 examples/anim_dump: imageio/libimageenc.a
 examples/anim_dump: src/libwebp.a
-examples/anim_dump: EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
+examples/anim_dump: sharpyuv/libsharpyuv.a
+examples/anim_dump: override EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
 examples/cwebp: examples/libexample_util.a
 examples/cwebp: imageio/libimagedec.a
 examples/cwebp: src/demux/libwebpdemux.a
 examples/cwebp: imageio/libimageio_util.a
 examples/cwebp: src/libwebp.a
-examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
+examples/cwebp: sharpyuv/libsharpyuv.a
+examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS)
 examples/dwebp: examples/libexample_util.a
 examples/dwebp: imageio/libimagedec.a
 examples/dwebp: src/demux/libwebpdemux.a
 examples/dwebp: imageio/libimageenc.a
 examples/dwebp: imageio/libimageio_util.a
 examples/dwebp: src/libwebp.a
-examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS)
+examples/dwebp: sharpyuv/libsharpyuv.a
+examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS)
 examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
 examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
-examples/gif2webp: EXTRA_LIBS += $(GIF_LIBS)
+examples/gif2webp: sharpyuv/libsharpyuv.a
+examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS)
 examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
 examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
 examples/vwebp: imageio/libimageio_util.a src/libwebp.a
-examples/vwebp: EXTRA_LIBS += $(GL_LIBS)
+examples/vwebp: sharpyuv/libsharpyuv.a
+examples/vwebp: override EXTRA_LIBS += $(GL_LIBS)
 examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
 examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
 examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
 examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
 examples/img2webp: imageio/libimagedec.a
 examples/img2webp: src/demux/libwebpdemux.a
-examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
-examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
+examples/img2webp: src/mux/libwebpmux.a
+examples/img2webp: src/libwebp.a
+examples/img2webp: sharpyuv/libsharpyuv.a
+examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
 examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
 examples/webpinfo: src/libwebpdecoder.a
 
@@ -449,18 +476,21 @@
 extras/get_disto: src/demux/libwebpdemux.a
 extras/get_disto: imageio/libimageio_util.a
 extras/get_disto: src/libwebp.a
-extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
+extras/get_disto: sharpyuv/libsharpyuv.a
+extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
 
 extras/webp_quality: extras/webp_quality.o
 extras/webp_quality: imageio/libimageio_util.a
 extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
+extras/webp_quality: sharpyuv/libsharpyuv.a
 
 extras/vwebp_sdl: extras/vwebp_sdl.o
 extras/vwebp_sdl: extras/webp_to_sdl.o
 extras/vwebp_sdl: imageio/libimageio_util.a
 extras/vwebp_sdl: src/libwebp.a
+extras/vwebp_sdl: sharpyuv/libsharpyuv.a
 extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
-extras/vwebp_sdl: EXTRA_LIBS += $(SDL_LIBS)
+extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
 
 $(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
 	$(CC) -o $@ $^ $(LDFLAGS)
@@ -469,12 +499,15 @@
 dist: OUT_EXAMPLES += $(EXTRA_EXAMPLES)
 dist: all
 	$(INSTALL) -m755 -d $(DESTDIR)/include/webp \
-	           $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
+	            $(DESTDIR)/include/webp/sharpyuv \
+	            $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
 	$(INSTALL) -m755 -s $(OUT_EXAMPLES) $(DESTDIR)/bin
 	$(INSTALL) -m644 $(HDRS_INSTALLED) $(DESTDIR)/include/webp
+	$(INSTALL) -m644 $(SHARPYUV_HDRS_INSTALLED) $(DESTDIR)/include/webp/sharpyuv
 	$(INSTALL) -m644 src/libwebp.a $(DESTDIR)/lib
 	$(INSTALL) -m644 src/demux/libwebpdemux.a $(DESTDIR)/lib
 	$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
+	$(INSTALL) -m644 sharpyuv/libsharpyuv.a $(DESTDIR)/lib
 	umask 022; \
 	for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
                  man/img2webp.1 man/webpinfo.1; do \
@@ -490,6 +523,7 @@
               examples/*.o examples/*~ \
               extras/*.o extras/*~ \
               imageio/*.o imageio/*~ \
+              sharpyuv/*.o sharpyuv/*~ \
               src/dec/*.o src/dec/*~ \
               src/demux/*.o src/demux/*~ \
               src/dsp/*.o src/dsp/*~ \
diff --git a/third_party/libwebp/man/Makefile.am b/third_party/libwebp/man/Makefile.am
index a7ef77f..57e2483 100644
--- a/third_party/libwebp/man/Makefile.am
+++ b/third_party/libwebp/man/Makefile.am
@@ -1,10 +1,13 @@
 man_MANS = cwebp.1 dwebp.1
-if WANT_MUX
+if BUILD_MUX
   man_MANS += webpmux.1
 endif
 if BUILD_GIF2WEBP
   man_MANS += gif2webp.1
 endif
+if BUILD_IMG2WEBP
+  man_MANS += img2webp.1
+endif
 if BUILD_VWEBP
   man_MANS += vwebp.1
 endif
diff --git a/third_party/libwebp/man/cwebp.1 b/third_party/libwebp/man/cwebp.1
index c943324..28de4c9 100644
--- a/third_party/libwebp/man/cwebp.1
+++ b/third_party/libwebp/man/cwebp.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH CWEBP 1 "January 20, 2017"
+.TH CWEBP 1 "March 17, 2022"
 .SH NAME
 cwebp \- compress an image file to a WebP file
 .SH SYNOPSIS
@@ -13,6 +13,7 @@
 .PP
 \fBcwebp\fP compresses an image using the WebP format.
 Input format can be either PNG, JPEG, TIFF, WebP or raw Y'CbCr samples.
+Note: Animated PNG and WebP files are not supported.
 .SH OPTIONS
 The basic options are:
 .TP
@@ -41,10 +42,12 @@
 \-exact option is used.
 .TP
 .BI \-near_lossless " int
-Use near\-lossless image preprocessing. This option adjusts pixel values
-to help compressibility, but has minimal impact on the visual quality.
-It triggers lossless compression mode automatically.
-Range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).
+Specify the level of near\-lossless image preprocessing. This option adjusts
+pixel values to help compressibility, but has minimal impact on the visual
+quality. It triggers lossless compression mode automatically. The range is 0
+(maximum preprocessing) to 100 (no preprocessing, the default). The typical
+value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
+better results.
 .TP
 .BI \-q " float
 Specify the compression factor for RGB channels between 0 and 100. The default
@@ -87,15 +90,17 @@
 Lower value can result in faster processing time at the expense of
 larger file size and lower compression quality.
 .TP
-.BI \-resize " width height
-Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
-If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
-the value will be calculated preserving the aspect\-ratio.
-.TP
 .BI \-crop " x_position y_position width height
 Crop the source to a rectangle with top\-left corner at coordinates
 (\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP.
 This cropping area must be fully contained within the source rectangle.
+Note: the cropping is applied \fIbefore\fP any scaling.
+.TP
+.BI \-resize " width height
+Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
+If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
+the value will be calculated preserving the aspect\-ratio. Note: scaling
+is applied \fIafter\fP cropping.
 .TP
 .B \-mt
 Use multi\-threading for encoding, if possible.
@@ -132,6 +137,13 @@
 If options \fB\-size\fP or \fB\-psnr\fP were used, but \fB\-pass\fP wasn't
 specified, a default value of '6' passes will be used.
 .TP
+.BI \-qrange " int int
+Specifies the permissible interval for the quality factor. This is particularly
+useful when using multi-pass (\fB\-size\fP or \fB\-psnr\fP options).
+Default is 0 100.
+If the quality factor is outside this range, it will be clamped.
+If the minimum value must be less or equal to the maximum one.
+.TP
 .B \-af
 Turns auto\-filter on. This algorithm will spend additional time optimizing
 the filtering strength to reach a well\-balanced quality.
@@ -212,7 +224,7 @@
 .TP
 .B \-print_ssim
 Compute and report average SSIM (structural similarity
-metric, see http://en.wikipedia.org/wiki/SSIM for additional details).
+metric, see https://en.wikipedia.org/wiki/SSIM for additional details).
 .TP
 .B \-print_lsim
 Compute and report local similarity metric (sum of lowest error amongst the
@@ -288,7 +300,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting\-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
@@ -312,5 +324,5 @@
 .BR dwebp (1),
 .BR gif2webp (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/man/dwebp.1 b/third_party/libwebp/man/dwebp.1
index d4b60ed..e718aba 100644
--- a/third_party/libwebp/man/dwebp.1
+++ b/third_party/libwebp/man/dwebp.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH DWEBP 1 "June 23, 2016"
+.TH DWEBP 1 "November 17, 2021"
 .SH NAME
 dwebp \- decompress a WebP file to an image file
 .SH SYNOPSIS
@@ -12,6 +12,7 @@
 command.
 .PP
 \fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images.
+Note: Animated WebP files are not supported.
 .SH OPTIONS
 The basic options are:
 .TP
@@ -112,7 +113,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 dwebp picture.webp \-o output.png
@@ -137,7 +138,7 @@
 .BR gif2webp (1),
 .BR webpmux (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
 .SS Output file format details
 PAM: http://netpbm.sourceforge.net/doc/pam.html
diff --git a/third_party/libwebp/man/gif2webp.1 b/third_party/libwebp/man/gif2webp.1
index a94f2ee..3bf43bc 100644
--- a/third_party/libwebp/man/gif2webp.1
+++ b/third_party/libwebp/man/gif2webp.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH GIF2WEBP 1 "January 25, 2018"
+.TH GIF2WEBP 1 "November 17, 2021"
 .SH NAME
 gif2webp \- Convert a GIF image to WebP
 .SH SYNOPSIS
@@ -62,9 +62,9 @@
 .TP
 .BI \-min_size
 Encode image to achieve smallest size. This disables key frame insertion and
-picks the dispose method resulting in smallest output for each frame. It uses
-lossless compression by default, but can be combined with \-q, \-m, \-lossy or
-\-mixed options.
+picks the dispose method resulting in the smallest output for each frame. It
+uses lossless compression by default, but can be combined with \-q, \-m,
+\-lossy or \-mixed options.
 .TP
 .BI \-kmin " int
 .TP
@@ -131,7 +131,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 gif2webp picture.gif \-o picture.webp
@@ -160,5 +160,5 @@
 .BR dwebp (1),
 .BR webpmux (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/man/img2webp.1 b/third_party/libwebp/man/img2webp.1
index da1d91d..fc493e1 100644
--- a/third_party/libwebp/man/img2webp.1
+++ b/third_party/libwebp/man/img2webp.1
@@ -1,10 +1,10 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH IMG2WEBP 1 "April 3, 2018"
+.TH IMG2WEBP 1 "March 17, 2023"
 .SH NAME
 img2webp \- create animated WebP file from a sequence of input images.
 .SH SYNOPSIS
 .B img2webp
-[file_level_options] [files] [per_frame_options...]
+[file_options] [[frame_options] frame_file]... [\-o webp_file]
 .br
 .B img2webp argument_file_name
 .br
@@ -16,8 +16,8 @@
 \fBimg2webp\fP compresses a sequence of images using the animated WebP format.
 Input images can either be PNG, JPEG, TIFF or WebP.
 If a single file name (not starting with the character '\-') is supplied as
-the argument, the command line argument are actually tokenized from this file.
-This allows for easy scripting or using large number of arguments.
+the argument, the command line arguments are actually tokenized from this file.
+This allows for easy scripting or using a large number of arguments.
 .SH FILE-LEVEL OPTIONS
 The file-level options are applied at the beginning of the compression process,
 before the input frames are read.
@@ -27,7 +27,7 @@
 .TP
 .BI \-min_size
 Encode images to achieve smallest size. This disables key frame insertion and
-picks the parameters resulting in smallest output for each frame. It uses
+picks the parameters resulting in the smallest output for each frame. It uses
 lossless compression by default, but can be combined with \-q, \-m, \-lossy or
 \-mixed options.
 .TP
@@ -44,6 +44,18 @@
 lossy or lossless compression for each frame heuristically. This global
 option disables the local option \fB-lossy\fP and \fB-lossless\fP .
 .TP
+.BI \-near_lossless " int
+Specify the level of near\-lossless image preprocessing. This option adjusts
+pixel values to help compressibility, but has minimal impact on the visual
+quality. It triggers lossless compression mode automatically. The range is 0
+(maximum preprocessing) to 100 (no preprocessing, the default). The typical
+value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
+better results.
+.TP
+.B \-sharp_yuv
+Use more accurate and sharper RGB->YUV conversion if needed. Note that this
+process is slower than the default 'fast' RGB->YUV conversion.
+.TP
 .BI \-loop " int
 Specifies the number of times the animation should loop. Using '0'
 means 'loop indefinitely'.
@@ -86,7 +98,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting\-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH AUTHORS
 \fBimg2webp\fP is a part of libwebp and was written by the WebP team.
@@ -101,5 +113,5 @@
 .BR webpmux (1),
 .BR gif2webp (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/man/vwebp.1 b/third_party/libwebp/man/vwebp.1
index 4ec346a..fa48db6 100644
--- a/third_party/libwebp/man/vwebp.1
+++ b/third_party/libwebp/man/vwebp.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH VWEBP 1 "November 25, 2016"
+.TH VWEBP 1 "November 17, 2021"
 .SH NAME
 vwebp \- decompress a WebP file and display it in a window
 .SH SYNOPSIS
@@ -38,6 +38,10 @@
 By default, quantized transparency planes are dithered during decompression,
 to smooth the gradients. This flag will prevent this dithering.
 .TP
+.B \-usebgcolor
+Fill transparent areas with the bitstream's own background color instead of
+checkerboard only. Default is white for non-animated images.
+.TP
 .B \-mt
 Use multi-threading for decoding, if possible.
 .TP
@@ -56,6 +60,9 @@
 .B 'c'
 Toggle use of color profile.
 .TP
+.B 'b'
+Toggle display of background color.
+.TP
 .B 'i'
 Overlay file information.
 .TP
@@ -70,7 +77,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 vwebp picture.webp
@@ -90,5 +97,5 @@
 .SH SEE ALSO
 .BR dwebp (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/man/webpinfo.1 b/third_party/libwebp/man/webpinfo.1
index 902ba9e..35d6d92 100644
--- a/third_party/libwebp/man/webpinfo.1
+++ b/third_party/libwebp/man/webpinfo.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH WEBPINFO 1 "November 24, 2017"
+.TH WEBPINFO 1 "November 17, 2021"
 .SH NAME
 webpinfo \- print out the chunk level structure of WebP files
 along with basic integrity checks.
@@ -52,7 +52,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting\-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 .br
@@ -76,5 +76,5 @@
 .SH SEE ALSO
 .BR webpmux (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/man/webpmux.1 b/third_party/libwebp/man/webpmux.1
index eb41a61..07e8738 100644
--- a/third_party/libwebp/man/webpmux.1
+++ b/third_party/libwebp/man/webpmux.1
@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH WEBPMUX 1 "December 1, 2017"
+.TH WEBPMUX 1 "November 17, 2021"
 .SH NAME
 webpmux \- create animated WebP files from non\-animated WebP images, extract
 frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
@@ -58,8 +58,8 @@
 \fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
 to add/extract/strip XMP/EXIF metadata and ICC profile.
 If a single file name (not starting with the character '\-') is supplied as
-the argument, the command line argument are actually tokenized from this file.
-This allows for easy scripting or using large number of arguments.
+the argument, the command line arguments are actually tokenized from this file.
+This allows for easy scripting or using a large number of arguments.
 .SH OPTIONS
 .SS GET_OPTIONS (\-get):
 .TP
@@ -77,6 +77,17 @@
 
 .SS SET_OPTIONS (\-set)
 .TP
+.BI loop " loop_count
+Set loop count on an animated file.
+.P
+Where: 'loop_count' must be in range [0, 65535].
+.TP
+.BI bgcolor " A,R,G,B
+Set the background color of the canvas on an animated file.
+.P
+where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying the
+Alpha, Red, Green and Blue component values respectively.
+.TP
 .BI icc " file.icc
 Set ICC profile.
 .P
@@ -180,7 +191,7 @@
 https://bugs.chromium.org/p/webp
 .br
 Patches welcome! See this page to get started:
-http://www.webmproject.org/code/contribute/submitting\-patches/
+https://www.webmproject.org/code/contribute/submitting\-patches/
 
 .SH EXAMPLES
 .P
@@ -256,5 +267,5 @@
 .BR dwebp (1),
 .BR gif2webp (1)
 .br
-Please refer to http://developers.google.com/speed/webp/ for additional
+Please refer to https://developers.google.com/speed/webp/ for additional
 information.
diff --git a/third_party/libwebp/sharpyuv/Makefile.am b/third_party/libwebp/sharpyuv/Makefile.am
new file mode 100644
index 0000000..8d9ba7c
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/Makefile.am
@@ -0,0 +1,41 @@
+AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
+AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
+
+lib_LTLIBRARIES = libsharpyuv.la
+
+noinst_LTLIBRARIES =
+noinst_LTLIBRARIES += libsharpyuv_sse2.la
+noinst_LTLIBRARIES += libsharpyuv_neon.la
+
+libsharpyuvinclude_HEADERS =
+libsharpyuvinclude_HEADERS += sharpyuv.h
+libsharpyuvinclude_HEADERS += sharpyuv_csp.h
+noinst_HEADERS =
+noinst_HEADERS += ../src/dsp/cpu.c
+noinst_HEADERS += ../src/dsp/cpu.h
+noinst_HEADERS += ../src/webp/types.h
+
+libsharpyuv_sse2_la_SOURCES =
+libsharpyuv_sse2_la_SOURCES += sharpyuv_sse2.c
+libsharpyuv_sse2_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
+libsharpyuv_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS)
+
+libsharpyuv_neon_la_SOURCES =
+libsharpyuv_neon_la_SOURCES += sharpyuv_neon.c
+libsharpyuv_neon_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
+libsharpyuv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS)
+
+libsharpyuv_la_SOURCES =
+libsharpyuv_la_SOURCES += sharpyuv_cpu.c sharpyuv_cpu.h
+libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h
+libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h
+libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h
+libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h
+
+libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS)
+libsharpyuv_la_LDFLAGS = -no-undefined -version-info 0:1:0 -lm
+libsharpyuv_la_LIBADD =
+libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
+libsharpyuv_la_LIBADD += libsharpyuv_neon.la
+libsharpyuvincludedir = $(includedir)/webp/sharpyuv
+pkgconfig_DATA = libsharpyuv.pc
diff --git a/third_party/libwebp/sharpyuv/libsharpyuv.pc.in b/third_party/libwebp/sharpyuv/libsharpyuv.pc.in
new file mode 100644
index 0000000..0fb565a
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/libsharpyuv.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/webp
+
+Name: libsharpyuv
+Description: Library for sharp RGB to YUV conversion
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@webp_libname_prefix@sharpyuv
+Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/third_party/libwebp/sharpyuv/libsharpyuv.rc b/third_party/libwebp/sharpyuv/libsharpyuv.rc
new file mode 100644
index 0000000..49c338a
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/libsharpyuv.rc
@@ -0,0 +1,41 @@
+#define APSTUDIO_READONLY_SYMBOLS
+#include "winres.h"
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,2,1
+ PRODUCTVERSION 0,0,2,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Google, Inc."
+            VALUE "FileDescription", "libsharpyuv DLL"
+            VALUE "FileVersion", "0.2.1"
+            VALUE "InternalName", "libsharpyuv.dll"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
+            VALUE "OriginalFilename", "libsharpyuv.dll"
+            VALUE "ProductName", "SharpYuv Library"
+            VALUE "ProductVersion", "0.2.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (United States) resources
diff --git a/third_party/libwebp/sharpyuv/sharpyuv.c b/third_party/libwebp/sharpyuv/sharpyuv.c
new file mode 100644
index 0000000..a074564
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv.c
@@ -0,0 +1,527 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Sharp RGB to YUV conversion.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "sharpyuv/sharpyuv.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/webp/types.h"
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "sharpyuv/sharpyuv_dsp.h"
+#include "sharpyuv/sharpyuv_gamma.h"
+
+//------------------------------------------------------------------------------
+
+int SharpYuvGetVersion(void) {
+  return SHARPYUV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// Sharp RGB->YUV conversion
+
+static const int kNumIterations = 4;
+
+#define YUV_FIX 16  // fixed-point precision for RGB->YUV
+static const int kYuvHalf = 1 << (YUV_FIX - 1);
+
+// Max bit depth so that intermediate calculations fit in 16 bits.
+static const int kMaxBitDepth = 14;
+
+// Returns the precision shift to use based on the input rgb_bit_depth.
+static int GetPrecisionShift(int rgb_bit_depth) {
+  // Try to add 2 bits of precision if it fits in kMaxBitDepth. Otherwise remove
+  // bits if needed.
+  return ((rgb_bit_depth + 2) <= kMaxBitDepth) ? 2
+                                               : (kMaxBitDepth - rgb_bit_depth);
+}
+
+typedef int16_t fixed_t;      // signed type with extra precision for UV
+typedef uint16_t fixed_y_t;   // unsigned type with extra precision for W
+
+//------------------------------------------------------------------------------
+
+static uint8_t clip_8b(fixed_t v) {
+  return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
+}
+
+static uint16_t clip(fixed_t v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static fixed_y_t clip_bit_depth(int y, int bit_depth) {
+  const int max = (1 << bit_depth) - 1;
+  return (!(y & ~max)) ? (fixed_y_t)y : (y < 0) ? 0 : max;
+}
+
+//------------------------------------------------------------------------------
+
+static int RGBToGray(int64_t r, int64_t g, int64_t b) {
+  const int64_t luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
+  return (int)(luma >> YUV_FIX);
+}
+
+static uint32_t ScaleDown(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
+                          int rgb_bit_depth) {
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  const uint32_t A = SharpYuvGammaToLinear(a, bit_depth);
+  const uint32_t B = SharpYuvGammaToLinear(b, bit_depth);
+  const uint32_t C = SharpYuvGammaToLinear(c, bit_depth);
+  const uint32_t D = SharpYuvGammaToLinear(d, bit_depth);
+  return SharpYuvLinearToGamma((A + B + C + D + 2) >> 2, bit_depth);
+}
+
+static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w,
+                                int rgb_bit_depth) {
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  int i;
+  for (i = 0; i < w; ++i) {
+    const uint32_t R = SharpYuvGammaToLinear(src[0 * w + i], bit_depth);
+    const uint32_t G = SharpYuvGammaToLinear(src[1 * w + i], bit_depth);
+    const uint32_t B = SharpYuvGammaToLinear(src[2 * w + i], bit_depth);
+    const uint32_t Y = RGBToGray(R, G, B);
+    dst[i] = (fixed_y_t)SharpYuvLinearToGamma(Y, bit_depth);
+  }
+}
+
+static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
+                         fixed_t* dst, int uv_w, int rgb_bit_depth) {
+  int i;
+  for (i = 0; i < uv_w; ++i) {
+    const int r =
+        ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1], src2[0 * uv_w + 0],
+                  src2[0 * uv_w + 1], rgb_bit_depth);
+    const int g =
+        ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1], src2[2 * uv_w + 0],
+                  src2[2 * uv_w + 1], rgb_bit_depth);
+    const int b =
+        ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1], src2[4 * uv_w + 0],
+                  src2[4 * uv_w + 1], rgb_bit_depth);
+    const int W = RGBToGray(r, g, b);
+    dst[0 * uv_w] = (fixed_t)(r - W);
+    dst[1 * uv_w] = (fixed_t)(g - W);
+    dst[2 * uv_w] = (fixed_t)(b - W);
+    dst  += 1;
+    src1 += 2;
+    src2 += 2;
+  }
+}
+
+static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
+  int i;
+  assert(w > 0);
+  for (i = 0; i < w; ++i) {
+    y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0, int bit_depth) {
+  const int v0 = (A * 3 + B + 2) >> 2;
+  return clip_bit_depth(v0 + W0, bit_depth);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int Shift(int v, int shift) {
+  return (shift >= 0) ? (v << shift) : (v >> -shift);
+}
+
+static void ImportOneRow(const uint8_t* const r_ptr,
+                         const uint8_t* const g_ptr,
+                         const uint8_t* const b_ptr,
+                         int rgb_step,
+                         int rgb_bit_depth,
+                         int pic_width,
+                         fixed_y_t* const dst) {
+  // Convert the rgb_step from a number of bytes to a number of uint8_t or
+  // uint16_t values depending the bit depth.
+  const int step = (rgb_bit_depth > 8) ? rgb_step / 2 : rgb_step;
+  int i;
+  const int w = (pic_width + 1) & ~1;
+  for (i = 0; i < pic_width; ++i) {
+    const int off = i * step;
+    const int shift = GetPrecisionShift(rgb_bit_depth);
+    if (rgb_bit_depth == 8) {
+      dst[i + 0 * w] = Shift(r_ptr[off], shift);
+      dst[i + 1 * w] = Shift(g_ptr[off], shift);
+      dst[i + 2 * w] = Shift(b_ptr[off], shift);
+    } else {
+      dst[i + 0 * w] = Shift(((uint16_t*)r_ptr)[off], shift);
+      dst[i + 1 * w] = Shift(((uint16_t*)g_ptr)[off], shift);
+      dst[i + 2 * w] = Shift(((uint16_t*)b_ptr)[off], shift);
+    }
+  }
+  if (pic_width & 1) {  // replicate rightmost pixel
+    dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
+    dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
+    dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
+  }
+}
+
+static void InterpolateTwoRows(const fixed_y_t* const best_y,
+                               const fixed_t* prev_uv,
+                               const fixed_t* cur_uv,
+                               const fixed_t* next_uv,
+                               int w,
+                               fixed_y_t* out1,
+                               fixed_y_t* out2,
+                               int rgb_bit_depth) {
+  const int uv_w = w >> 1;
+  const int len = (w - 1) >> 1;   // length to filter
+  int k = 3;
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  while (k-- > 0) {   // process each R/G/B segments in turn
+    // special boundary case for i==0
+    out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0], bit_depth);
+    out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w], bit_depth);
+
+    SharpYuvFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1,
+                      bit_depth);
+    SharpYuvFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1,
+                      bit_depth);
+
+    // special boundary case for i == w - 1 when w is even
+    if (!(w & 1)) {
+      out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
+                            best_y[w - 1 + 0], bit_depth);
+      out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
+                            best_y[w - 1 + w], bit_depth);
+    }
+    out1 += w;
+    out2 += w;
+    prev_uv += uv_w;
+    cur_uv  += uv_w;
+    next_uv += uv_w;
+  }
+}
+
+static WEBP_INLINE int RGBToYUVComponent(int r, int g, int b,
+                                         const int coeffs[4], int sfix) {
+  const int srounder = 1 << (YUV_FIX + sfix - 1);
+  const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
+                   coeffs[3] + srounder;
+  return (luma >> (YUV_FIX + sfix));
+}
+
+static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
+                            uint8_t* y_ptr, int y_stride, uint8_t* u_ptr,
+                            int u_stride, uint8_t* v_ptr, int v_stride,
+                            int rgb_bit_depth,
+                            int yuv_bit_depth, int width, int height,
+                            const SharpYuvConversionMatrix* yuv_matrix) {
+  int i, j;
+  const fixed_t* const best_uv_base = best_uv;
+  const int w = (width + 1) & ~1;
+  const int h = (height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  const int sfix = GetPrecisionShift(rgb_bit_depth);
+  const int yuv_max = (1 << yuv_bit_depth) - 1;
+
+  for (best_uv = best_uv_base, j = 0; j < height; ++j) {
+    for (i = 0; i < width; ++i) {
+      const int off = (i >> 1);
+      const int W = best_y[i];
+      const int r = best_uv[off + 0 * uv_w] + W;
+      const int g = best_uv[off + 1 * uv_w] + W;
+      const int b = best_uv[off + 2 * uv_w] + W;
+      const int y = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_y, sfix);
+      if (yuv_bit_depth <= 8) {
+        y_ptr[i] = clip_8b(y);
+      } else {
+        ((uint16_t*)y_ptr)[i] = clip(y, yuv_max);
+      }
+    }
+    best_y += w;
+    best_uv += (j & 1) * 3 * uv_w;
+    y_ptr += y_stride;
+  }
+  for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
+    for (i = 0; i < uv_w; ++i) {
+      const int off = i;
+      // Note r, g and b values here are off by W, but a constant offset on all
+      // 3 components doesn't change the value of u and v with a YCbCr matrix.
+      const int r = best_uv[off + 0 * uv_w];
+      const int g = best_uv[off + 1 * uv_w];
+      const int b = best_uv[off + 2 * uv_w];
+      const int u = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_u, sfix);
+      const int v = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_v, sfix);
+      if (yuv_bit_depth <= 8) {
+        u_ptr[i] = clip_8b(u);
+        v_ptr[i] = clip_8b(v);
+      } else {
+        ((uint16_t*)u_ptr)[i] = clip(u, yuv_max);
+        ((uint16_t*)v_ptr)[i] = clip(v, yuv_max);
+      }
+    }
+    best_uv += 3 * uv_w;
+    u_ptr += u_stride;
+    v_ptr += v_stride;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Main function
+
+static void* SafeMalloc(uint64_t nmemb, size_t size) {
+  const uint64_t total_size = nmemb * (uint64_t)size;
+  if (total_size != (size_t)total_size) return NULL;
+  return malloc((size_t)total_size);
+}
+
+#define SAFE_ALLOC(W, H, T) ((T*)SafeMalloc((W) * (H), sizeof(T)))
+
+static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
+                            const uint8_t* b_ptr, int rgb_step, int rgb_stride,
+                            int rgb_bit_depth, uint8_t* y_ptr, int y_stride,
+                            uint8_t* u_ptr, int u_stride, uint8_t* v_ptr,
+                            int v_stride, int yuv_bit_depth, int width,
+                            int height,
+                            const SharpYuvConversionMatrix* yuv_matrix) {
+  // we expand the right/bottom border if needed
+  const int w = (width + 1) & ~1;
+  const int h = (height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  uint64_t prev_diff_y_sum = ~0;
+  int j, iter;
+
+  // TODO(skal): allocate one big memory chunk. But for now, it's easier
+  // for valgrind debugging to have several chunks.
+  fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t);   // scratch
+  fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
+  fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
+  fixed_y_t* best_y = best_y_base;
+  fixed_y_t* target_y = target_y_base;
+  fixed_t* best_uv = best_uv_base;
+  fixed_t* target_uv = target_uv_base;
+  const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
+  int ok;
+  assert(w > 0);
+  assert(h > 0);
+
+  if (best_y_base == NULL || best_uv_base == NULL ||
+      target_y_base == NULL || target_uv_base == NULL ||
+      best_rgb_y == NULL || best_rgb_uv == NULL ||
+      tmp_buffer == NULL) {
+    ok = 0;
+    goto End;
+  }
+
+  // Import RGB samples to W/RGB representation.
+  for (j = 0; j < height; j += 2) {
+    const int is_last_row = (j == height - 1);
+    fixed_y_t* const src1 = tmp_buffer + 0 * w;
+    fixed_y_t* const src2 = tmp_buffer + 3 * w;
+
+    // prepare two rows of input
+    ImportOneRow(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, width,
+                 src1);
+    if (!is_last_row) {
+      ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
+                   rgb_step, rgb_bit_depth, width, src2);
+    } else {
+      memcpy(src2, src1, 3 * w * sizeof(*src2));
+    }
+    StoreGray(src1, best_y + 0, w);
+    StoreGray(src2, best_y + w, w);
+
+    UpdateW(src1, target_y, w, rgb_bit_depth);
+    UpdateW(src2, target_y + w, w, rgb_bit_depth);
+    UpdateChroma(src1, src2, target_uv, uv_w, rgb_bit_depth);
+    memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
+    best_y += 2 * w;
+    best_uv += 3 * uv_w;
+    target_y += 2 * w;
+    target_uv += 3 * uv_w;
+    r_ptr += 2 * rgb_stride;
+    g_ptr += 2 * rgb_stride;
+    b_ptr += 2 * rgb_stride;
+  }
+
+  // Iterate and resolve clipping conflicts.
+  for (iter = 0; iter < kNumIterations; ++iter) {
+    const fixed_t* cur_uv = best_uv_base;
+    const fixed_t* prev_uv = best_uv_base;
+    uint64_t diff_y_sum = 0;
+
+    best_y = best_y_base;
+    best_uv = best_uv_base;
+    target_y = target_y_base;
+    target_uv = target_uv_base;
+    for (j = 0; j < h; j += 2) {
+      fixed_y_t* const src1 = tmp_buffer + 0 * w;
+      fixed_y_t* const src2 = tmp_buffer + 3 * w;
+      {
+        const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
+        InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w,
+                           src1, src2, rgb_bit_depth);
+        prev_uv = cur_uv;
+        cur_uv = next_uv;
+      }
+
+      UpdateW(src1, best_rgb_y + 0 * w, w, rgb_bit_depth);
+      UpdateW(src2, best_rgb_y + 1 * w, w, rgb_bit_depth);
+      UpdateChroma(src1, src2, best_rgb_uv, uv_w, rgb_bit_depth);
+
+      // update two rows of Y and one row of RGB
+      diff_y_sum +=
+          SharpYuvUpdateY(target_y, best_rgb_y, best_y, 2 * w,
+                          rgb_bit_depth + GetPrecisionShift(rgb_bit_depth));
+      SharpYuvUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
+
+      best_y += 2 * w;
+      best_uv += 3 * uv_w;
+      target_y += 2 * w;
+      target_uv += 3 * uv_w;
+    }
+    // test exit condition
+    if (iter > 0) {
+      if (diff_y_sum < diff_y_threshold) break;
+      if (diff_y_sum > prev_diff_y_sum) break;
+    }
+    prev_diff_y_sum = diff_y_sum;
+  }
+
+  // final reconstruction
+  ok = ConvertWRGBToYUV(best_y_base, best_uv_base, y_ptr, y_stride, u_ptr,
+                        u_stride, v_ptr, v_stride, rgb_bit_depth, yuv_bit_depth,
+                        width, height, yuv_matrix);
+
+ End:
+  free(best_y_base);
+  free(best_uv_base);
+  free(target_y_base);
+  free(target_uv_base);
+  free(best_rgb_y);
+  free(best_rgb_uv);
+  free(tmp_buffer);
+  return ok;
+}
+#undef SAFE_ALLOC
+
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h>  // NOLINT
+
+#define LOCK_ACCESS \
+    static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \
+    if (pthread_mutex_lock(&sharpyuv_lock)) return
+#define UNLOCK_ACCESS_AND_RETURN                  \
+    do {                                          \
+      (void)pthread_mutex_unlock(&sharpyuv_lock); \
+      return;                                     \
+    } while (0)
+#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define LOCK_ACCESS do {} while (0)
+#define UNLOCK_ACCESS_AND_RETURN return
+#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
+// Hidden exported init function.
+// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed,
+// users can declare it as extern and call it with an alternate VP8CPUInfo
+// function.
+extern VP8CPUInfo SharpYuvGetCPUInfo;
+SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func);
+void SharpYuvInit(VP8CPUInfo cpu_info_func) {
+  static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
+      (VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
+  LOCK_ACCESS;
+  // Only update SharpYuvGetCPUInfo when called from external code to avoid a
+  // race on reading the value in SharpYuvConvert().
+  if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) {
+    SharpYuvGetCPUInfo = cpu_info_func;
+  }
+  if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) {
+    UNLOCK_ACCESS_AND_RETURN;
+  }
+
+  SharpYuvInitDsp();
+  SharpYuvInitGammaTables();
+
+  sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo;
+  UNLOCK_ACCESS_AND_RETURN;
+}
+
+int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+                    const void* b_ptr, int rgb_step, int rgb_stride,
+                    int rgb_bit_depth, void* y_ptr, int y_stride,
+                    void* u_ptr, int u_stride, void* v_ptr,
+                    int v_stride, int yuv_bit_depth, int width,
+                    int height, const SharpYuvConversionMatrix* yuv_matrix) {
+  SharpYuvConversionMatrix scaled_matrix;
+  const int rgb_max = (1 << rgb_bit_depth) - 1;
+  const int rgb_round = 1 << (rgb_bit_depth - 1);
+  const int yuv_max = (1 << yuv_bit_depth) - 1;
+  const int sfix = GetPrecisionShift(rgb_bit_depth);
+
+  if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX ||
+      r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || y_ptr == NULL ||
+      u_ptr == NULL || v_ptr == NULL) {
+    return 0;
+  }
+  if (rgb_bit_depth != 8 && rgb_bit_depth != 10 && rgb_bit_depth != 12 &&
+      rgb_bit_depth != 16) {
+    return 0;
+  }
+  if (yuv_bit_depth != 8 && yuv_bit_depth != 10 && yuv_bit_depth != 12) {
+    return 0;
+  }
+  if (rgb_bit_depth > 8 && (rgb_step % 2 != 0 || rgb_stride %2 != 0)) {
+    // Step/stride should be even for uint16_t buffers.
+    return 0;
+  }
+  if (yuv_bit_depth > 8 &&
+      (y_stride % 2 != 0 || u_stride % 2 != 0 || v_stride % 2 != 0)) {
+    // Stride should be even for uint16_t buffers.
+    return 0;
+  }
+  // The address of the function pointer is used to avoid a read race.
+  SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo);
+
+  // Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
+  // rgb->yuv conversion matrix.
+  if (rgb_bit_depth == yuv_bit_depth) {
+    memcpy(&scaled_matrix, yuv_matrix, sizeof(scaled_matrix));
+  } else {
+    int i;
+    for (i = 0; i < 3; ++i) {
+      scaled_matrix.rgb_to_y[i] =
+          (yuv_matrix->rgb_to_y[i] * yuv_max + rgb_round) / rgb_max;
+      scaled_matrix.rgb_to_u[i] =
+          (yuv_matrix->rgb_to_u[i] * yuv_max + rgb_round) / rgb_max;
+      scaled_matrix.rgb_to_v[i] =
+          (yuv_matrix->rgb_to_v[i] * yuv_max + rgb_round) / rgb_max;
+    }
+  }
+  // Also incorporate precision change scaling.
+  scaled_matrix.rgb_to_y[3] = Shift(yuv_matrix->rgb_to_y[3], sfix);
+  scaled_matrix.rgb_to_u[3] = Shift(yuv_matrix->rgb_to_u[3], sfix);
+  scaled_matrix.rgb_to_v[3] = Shift(yuv_matrix->rgb_to_v[3], sfix);
+
+  return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride,
+                          rgb_bit_depth, y_ptr, y_stride, u_ptr, u_stride,
+                          v_ptr, v_stride, yuv_bit_depth, width, height,
+                          &scaled_matrix);
+}
+
+//------------------------------------------------------------------------------
diff --git a/third_party/libwebp/sharpyuv/sharpyuv.h b/third_party/libwebp/sharpyuv/sharpyuv.h
new file mode 100644
index 0000000..7b9904d
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv.h
@@ -0,0 +1,103 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Sharp RGB to YUV conversion.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_H_
+#define WEBP_SHARPYUV_SHARPYUV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SHARPYUV_EXTERN
+#ifdef WEBP_EXTERN
+#define SHARPYUV_EXTERN WEBP_EXTERN
+#else
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define SHARPYUV_EXTERN extern __attribute__((visibility("default")))
+#else
+#if defined(_MSC_VER) && defined(WEBP_DLL)
+#define SHARPYUV_EXTERN __declspec(dllexport)
+#else
+#define SHARPYUV_EXTERN extern
+#endif /* _MSC_VER && WEBP_DLL */
+#endif /* __GNUC__ >= 4 */
+#endif /* WEBP_EXTERN */
+#endif /* SHARPYUV_EXTERN */
+
+// SharpYUV API version following the convention from semver.org
+#define SHARPYUV_VERSION_MAJOR 0
+#define SHARPYUV_VERSION_MINOR 2
+#define SHARPYUV_VERSION_PATCH 1
+// Version as a uint32_t. The major number is the high 8 bits.
+// The minor number is the middle 8 bits. The patch number is the low 16 bits.
+#define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \
+  (((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))
+#define SHARPYUV_VERSION                                                \
+  SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
+                        SHARPYUV_VERSION_PATCH)
+
+// Returns the library's version number, packed in hexadecimal. See
+// SHARPYUV_VERSION.
+SHARPYUV_EXTERN int SharpYuvGetVersion(void);
+
+// RGB to YUV conversion matrix, in 16 bit fixed point.
+// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
+// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
+// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]
+// Then y, u and v values are divided by 1<<16 and rounded.
+typedef struct {
+  int rgb_to_y[4];
+  int rgb_to_u[4];
+  int rgb_to_v[4];
+} SharpYuvConversionMatrix;
+
+// Converts RGB to YUV420 using a downsampling algorithm that minimizes
+// artefacts caused by chroma subsampling.
+// This is slower than standard downsampling (averaging of 4 UV values).
+// Assumes that the image will be upsampled using a bilinear filter. If nearest
+// neighbor is used instead, the upsampled image might look worse than with
+// standard downsampling.
+// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point
+//     to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.
+// rgb_step: distance in bytes between two horizontally adjacent pixels on the
+//     r, g and b channels. If rgb_bit_depth is > 8, it should be a
+//     multiple of 2.
+// rgb_stride: distance in bytes between two vertically adjacent pixels on the
+//     r, g, and b channels. If rgb_bit_depth is > 8, it should be a
+//     multiple of 2.
+// rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.
+//     Note: 16 bit input is truncated to 14 bits before conversion to yuv.
+// yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.
+// y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels.  Should
+//     point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers
+//     otherwise.
+// y_stride, u_stride, v_stride: distance in bytes between two vertically
+//     adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
+//     should be multiples of 2.
+// width, height: width and height of the image in pixels
+SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+                                    const void* b_ptr, int rgb_step,
+                                    int rgb_stride, int rgb_bit_depth,
+                                    void* y_ptr, int y_stride, void* u_ptr,
+                                    int u_stride, void* v_ptr, int v_stride,
+                                    int yuv_bit_depth, int width, int height,
+                                    const SharpYuvConversionMatrix* yuv_matrix);
+
+// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
+// support (it's rarely used in practice, especially for images).
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_H_
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_cpu.c b/third_party/libwebp/sharpyuv/sharpyuv_cpu.c
new file mode 100644
index 0000000..29425a0
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_cpu.c
@@ -0,0 +1,14 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#include "sharpyuv/sharpyuv_cpu.h"
+
+// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
+// function pointer is renamed in sharpyuv_cpu.h.
+#include "src/dsp/cpu.c"
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_cpu.h b/third_party/libwebp/sharpyuv/sharpyuv_cpu.h
new file mode 100644
index 0000000..176ca3e
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_cpu.h
@@ -0,0 +1,22 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
+#define WEBP_SHARPYUV_SHARPYUV_CPU_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
+// SharpYuvInit() replaces the use of the function pointer.
+#undef WEBP_EXTERN
+#define WEBP_EXTERN extern
+#define VP8GetCPUInfo SharpYuvGetCPUInfo
+#include "src/dsp/cpu.h"
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_CPU_H_
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_csp.c b/third_party/libwebp/sharpyuv/sharpyuv_csp.c
new file mode 100644
index 0000000..0ad22be
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_csp.c
@@ -0,0 +1,110 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Colorspace utilities.
+
+#include "sharpyuv/sharpyuv_csp.h"
+
+#include <assert.h>
+#include <math.h>
+#include <stddef.h>
+
+static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
+
+void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
+                                     SharpYuvConversionMatrix* matrix) {
+  const float kr = yuv_color_space->kr;
+  const float kb = yuv_color_space->kb;
+  const float kg = 1.0f - kr - kb;
+  const float cr = 0.5f / (1.0f - kb);
+  const float cb = 0.5f / (1.0f - kr);
+
+  const int shift = yuv_color_space->bit_depth - 8;
+
+  const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
+  float scale_y = 1.0f;
+  float add_y = 0.0f;
+  float scale_u = cr;
+  float scale_v = cb;
+  float add_uv = (float)(128 << shift);
+  assert(yuv_color_space->bit_depth >= 8);
+
+  if (yuv_color_space->range == kSharpYuvRangeLimited) {
+    scale_y *= (219 << shift) / denom;
+    scale_u *= (224 << shift) / denom;
+    scale_v *= (224 << shift) / denom;
+    add_y = (float)(16 << shift);
+  }
+
+  matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
+  matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
+  matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
+  matrix->rgb_to_y[3] = ToFixed16(add_y);
+
+  matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
+  matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
+  matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
+  matrix->rgb_to_u[3] = ToFixed16(add_uv);
+
+  matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
+  matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
+  matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
+  matrix->rgb_to_v[3] = ToFixed16(add_uv);
+}
+
+// Matrices are in YUV_FIX fixed point precision.
+// WebP's matrix, similar but not identical to kRec601LimitedMatrix.
+static const SharpYuvConversionMatrix kWebpMatrix = {
+  {16839, 33059, 6420, 16 << 16},
+  {-9719, -19081, 28800, 128 << 16},
+  {28800, -24116, -4684, 128 << 16},
+};
+// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited
+static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
+  {16829, 33039, 6416, 16 << 16},
+  {-9714, -19071, 28784, 128 << 16},
+  {28784, -24103, -4681, 128 << 16},
+};
+// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull
+static const SharpYuvConversionMatrix kRec601FullMatrix = {
+  {19595, 38470, 7471, 0},
+  {-11058, -21710, 32768, 128 << 16},
+  {32768, -27439, -5329, 128 << 16},
+};
+// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited
+static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
+  {11966, 40254, 4064, 16 << 16},
+  {-6596, -22189, 28784, 128 << 16},
+  {28784, -26145, -2639, 128 << 16},
+};
+// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull
+static const SharpYuvConversionMatrix kRec709FullMatrix = {
+  {13933, 46871, 4732, 0},
+  {-7509, -25259, 32768, 128 << 16},
+  {32768, -29763, -3005, 128 << 16},
+};
+
+const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+    SharpYuvMatrixType matrix_type) {
+  switch (matrix_type) {
+    case kSharpYuvMatrixWebp:
+      return &kWebpMatrix;
+    case kSharpYuvMatrixRec601Limited:
+      return &kRec601LimitedMatrix;
+    case kSharpYuvMatrixRec601Full:
+      return &kRec601FullMatrix;
+    case kSharpYuvMatrixRec709Limited:
+      return &kRec709LimitedMatrix;
+    case kSharpYuvMatrixRec709Full:
+      return &kRec709FullMatrix;
+    case kSharpYuvMatrixNum:
+      return NULL;
+  }
+  return NULL;
+}
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_csp.h b/third_party/libwebp/sharpyuv/sharpyuv_csp.h
new file mode 100644
index 0000000..3214e3a
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_csp.h
@@ -0,0 +1,60 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Colorspace utilities.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_CSP_H_
+#define WEBP_SHARPYUV_SHARPYUV_CSP_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Range of YUV values.
+typedef enum {
+  kSharpYuvRangeFull,     // YUV values between [0;255] (for 8 bit)
+  kSharpYuvRangeLimited   // Y in [16;235], YUV in [16;240] (for 8 bit)
+} SharpYuvRange;
+
+// Constants that define a YUV color space.
+typedef struct {
+  // Kr and Kb are defined such that:
+  // Y = Kr * r + Kg * g + Kb * b where Kg = 1 - Kr - Kb.
+  float kr;
+  float kb;
+  int bit_depth;  // 8, 10 or 12
+  SharpYuvRange range;
+} SharpYuvColorSpace;
+
+// Fills in 'matrix' for the given YUVColorSpace.
+SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix(
+    const SharpYuvColorSpace* yuv_color_space,
+    SharpYuvConversionMatrix* matrix);
+
+// Enums for precomputed conversion matrices.
+typedef enum {
+  kSharpYuvMatrixWebp = 0,
+  kSharpYuvMatrixRec601Limited,
+  kSharpYuvMatrixRec601Full,
+  kSharpYuvMatrixRec709Limited,
+  kSharpYuvMatrixRec709Full,
+  kSharpYuvMatrixNum
+} SharpYuvMatrixType;
+
+// Returns a pointer to a matrix for one of the predefined colorspaces.
+SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+    SharpYuvMatrixType matrix_type);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_CSP_H_
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_dsp.c b/third_party/libwebp/sharpyuv/sharpyuv_dsp.c
new file mode 100644
index 0000000..0da3efc
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_dsp.c
@@ -0,0 +1,104 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "sharpyuv/sharpyuv_cpu.h"
+
+//-----------------------------------------------------------------------------
+
+#if !WEBP_NEON_OMIT_C_CODE
+static uint16_t clip(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_C(const uint16_t* ref, const uint16_t* src,
+                                  uint16_t* dst, int len, int bit_depth) {
+  uint64_t diff = 0;
+  int i;
+  const int max_y = (1 << bit_depth) - 1;
+  for (i = 0; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)dst[i] + diff_y;
+    dst[i] = clip(new_y, max_y);
+    diff += (uint64_t)abs(diff_y);
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_C(const int16_t* ref, const int16_t* src,
+                                int16_t* dst, int len) {
+  int i;
+  for (i = 0; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow_C(const int16_t* A, const int16_t* B, int len,
+                                const uint16_t* best_y, uint16_t* out,
+                                int bit_depth) {
+  int i;
+  const int max_y = (1 << bit_depth) - 1;
+  for (i = 0; i < len; ++i, ++A, ++B) {
+    const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4;
+    const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4;
+    out[2 * i + 0] = clip(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+#endif  // !WEBP_NEON_OMIT_C_CODE
+
+//-----------------------------------------------------------------------------
+
+uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
+                            uint16_t* dst, int len, int bit_depth);
+void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref, int16_t* dst,
+                          int len);
+void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
+                          const uint16_t* best_y, uint16_t* out,
+                          int bit_depth);
+
+extern VP8CPUInfo SharpYuvGetCPUInfo;
+extern void InitSharpYuvSSE2(void);
+extern void InitSharpYuvNEON(void);
+
+void SharpYuvInitDsp(void) {
+#if !WEBP_NEON_OMIT_C_CODE
+  SharpYuvUpdateY = SharpYuvUpdateY_C;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_C;
+  SharpYuvFilterRow = SharpYuvFilterRow_C;
+#endif
+
+  if (SharpYuvGetCPUInfo != NULL) {
+#if defined(WEBP_HAVE_SSE2)
+    if (SharpYuvGetCPUInfo(kSSE2)) {
+      InitSharpYuvSSE2();
+    }
+#endif  // WEBP_HAVE_SSE2
+  }
+
+#if defined(WEBP_HAVE_NEON)
+  if (WEBP_NEON_OMIT_C_CODE ||
+      (SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) {
+    InitSharpYuvNEON();
+  }
+#endif  // WEBP_HAVE_NEON
+
+  assert(SharpYuvUpdateY != NULL);
+  assert(SharpYuvUpdateRGB != NULL);
+  assert(SharpYuvFilterRow != NULL);
+}
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_dsp.h b/third_party/libwebp/sharpyuv/sharpyuv_dsp.h
new file mode 100644
index 0000000..805fbad
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_dsp.h
@@ -0,0 +1,28 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
+#define WEBP_SHARPYUV_SHARPYUV_DSP_H_
+
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "src/webp/types.h"
+
+extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
+                                   uint16_t* dst, int len, int bit_depth);
+extern void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref,
+                                 int16_t* dst, int len);
+extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
+                                 const uint16_t* best_y, uint16_t* out,
+                                 int bit_depth);
+
+void SharpYuvInitDsp(void);
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_DSP_H_
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_gamma.c b/third_party/libwebp/sharpyuv/sharpyuv_gamma.c
new file mode 100644
index 0000000..20ab2da
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_gamma.c
@@ -0,0 +1,113 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Gamma correction utilities.
+
+#include "sharpyuv/sharpyuv_gamma.h"
+
+#include <assert.h>
+#include <math.h>
+
+#include "src/webp/types.h"
+
+// Gamma correction compensates loss of resolution during chroma subsampling.
+// Size of pre-computed table for converting from gamma to linear.
+#define GAMMA_TO_LINEAR_TAB_BITS 10
+#define GAMMA_TO_LINEAR_TAB_SIZE (1 << GAMMA_TO_LINEAR_TAB_BITS)
+static uint32_t kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 2];
+#define LINEAR_TO_GAMMA_TAB_BITS 9
+#define LINEAR_TO_GAMMA_TAB_SIZE (1 << LINEAR_TO_GAMMA_TAB_BITS)
+static uint32_t kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 2];
+
+static const double kGammaF = 1. / 0.45;
+#define GAMMA_TO_LINEAR_BITS 16
+
+static volatile int kGammaTablesSOk = 0;
+void SharpYuvInitGammaTables(void) {
+  assert(GAMMA_TO_LINEAR_BITS <= 16);
+  if (!kGammaTablesSOk) {
+    int v;
+    const double a = 0.09929682680944;
+    const double thresh = 0.018053968510807;
+    const double final_scale = 1 << GAMMA_TO_LINEAR_BITS;
+    // Precompute gamma to linear table.
+    {
+      const double norm = 1. / GAMMA_TO_LINEAR_TAB_SIZE;
+      const double a_rec = 1. / (1. + a);
+      for (v = 0; v <= GAMMA_TO_LINEAR_TAB_SIZE; ++v) {
+        const double g = norm * v;
+        double value;
+        if (g <= thresh * 4.5) {
+          value = g / 4.5;
+        } else {
+          value = pow(a_rec * (g + a), kGammaF);
+        }
+        kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5);
+      }
+      // to prevent small rounding errors to cause read-overflow:
+      kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 1] =
+          kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE];
+    }
+    // Precompute linear to gamma table.
+    {
+      const double scale = 1. / LINEAR_TO_GAMMA_TAB_SIZE;
+      for (v = 0; v <= LINEAR_TO_GAMMA_TAB_SIZE; ++v) {
+        const double g = scale * v;
+        double value;
+        if (g <= thresh) {
+          value = 4.5 * g;
+        } else {
+          value = (1. + a) * pow(g, 1. / kGammaF) - a;
+        }
+        kLinearToGammaTabS[v] =
+            (uint32_t)(final_scale * value + 0.5);
+      }
+      // to prevent small rounding errors to cause read-overflow:
+      kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 1] =
+          kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE];
+    }
+    kGammaTablesSOk = 1;
+  }
+}
+
+static WEBP_INLINE int Shift(int v, int shift) {
+  return (shift >= 0) ? (v << shift) : (v >> -shift);
+}
+
+static WEBP_INLINE uint32_t FixedPointInterpolation(int v, uint32_t* tab,
+                                                    int tab_pos_shift_right,
+                                                    int tab_value_shift) {
+  const uint32_t tab_pos = Shift(v, -tab_pos_shift_right);
+  // fractional part, in 'tab_pos_shift' fixed-point precision
+  const uint32_t x = v - (tab_pos << tab_pos_shift_right);  // fractional part
+  // v0 / v1 are in kGammaToLinearBits fixed-point precision (range [0..1])
+  const uint32_t v0 = Shift(tab[tab_pos + 0], tab_value_shift);
+  const uint32_t v1 = Shift(tab[tab_pos + 1], tab_value_shift);
+  // Final interpolation.
+  const uint32_t v2 = (v1 - v0) * x;  // note: v1 >= v0.
+  const int half =
+      (tab_pos_shift_right > 0) ? 1 << (tab_pos_shift_right - 1) : 0;
+  const uint32_t result = v0 + ((v2 + half) >> tab_pos_shift_right);
+  return result;
+}
+
+uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth) {
+  const int shift = GAMMA_TO_LINEAR_TAB_BITS - bit_depth;
+  if (shift > 0) {
+    return kGammaToLinearTabS[v << shift];
+  }
+  return FixedPointInterpolation(v, kGammaToLinearTabS, -shift, 0);
+}
+
+uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth) {
+  return FixedPointInterpolation(
+      value, kLinearToGammaTabS,
+      (GAMMA_TO_LINEAR_BITS - LINEAR_TO_GAMMA_TAB_BITS),
+      bit_depth - GAMMA_TO_LINEAR_BITS);
+}
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_gamma.h b/third_party/libwebp/sharpyuv/sharpyuv_gamma.h
new file mode 100644
index 0000000..d13aff5
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_gamma.h
@@ -0,0 +1,35 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Gamma correction utilities.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
+#define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
+
+#include "src/webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initializes precomputed tables. Must be called once before calling
+// SharpYuvGammaToLinear or SharpYuvLinearToGamma.
+void SharpYuvInitGammaTables(void);
+
+// Converts a gamma color value on 'bit_depth' bits to a 16 bit linear value.
+uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth);
+
+// Converts a 16 bit linear color value to a gamma value on 'bit_depth' bits.
+uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_neon.c b/third_party/libwebp/sharpyuv/sharpyuv_neon.c
new file mode 100644
index 0000000..5840914
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_neon.c
@@ -0,0 +1,181 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#if defined(WEBP_USE_NEON)
+#include <assert.h>
+#include <stdlib.h>
+#include <arm_neon.h>
+
+static uint16_t clip_NEON(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_NEON(const uint16_t* ref, const uint16_t* src,
+                                     uint16_t* dst, int len, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const int16x8_t zero = vdupq_n_s16(0);
+  const int16x8_t max = vdupq_n_s16(max_y);
+  uint64x2_t sum = vdupq_n_u64(0);
+  uint64_t diff;
+
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t A = vreinterpretq_s16_u16(vld1q_u16(ref + i));
+    const int16x8_t B = vreinterpretq_s16_u16(vld1q_u16(src + i));
+    const int16x8_t C = vreinterpretq_s16_u16(vld1q_u16(dst + i));
+    const int16x8_t D = vsubq_s16(A, B);       // diff_y
+    const int16x8_t F = vaddq_s16(C, D);       // new_y
+    const uint16x8_t H =
+        vreinterpretq_u16_s16(vmaxq_s16(vminq_s16(F, max), zero));
+    const int16x8_t I = vabsq_s16(D);          // abs(diff_y)
+    vst1q_u16(dst + i, H);
+    sum = vpadalq_u32(sum, vpaddlq_u16(vreinterpretq_u16_s16(I)));
+  }
+  diff = vgetq_lane_u64(sum, 0) + vgetq_lane_u64(sum, 1);
+  for (; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)(dst[i]) + diff_y;
+    dst[i] = clip_NEON(new_y, max_y);
+    diff += (uint64_t)(abs(diff_y));
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_NEON(const int16_t* ref, const int16_t* src,
+                                   int16_t* dst, int len) {
+  int i;
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t A = vld1q_s16(ref + i);
+    const int16x8_t B = vld1q_s16(src + i);
+    const int16x8_t C = vld1q_s16(dst + i);
+    const int16x8_t D = vsubq_s16(A, B);   // diff_uv
+    const int16x8_t E = vaddq_s16(C, D);   // new_uv
+    vst1q_s16(dst + i, E);
+  }
+  for (; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow16_NEON(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const int16x8_t max = vdupq_n_s16(max_y);
+  const int16x8_t zero = vdupq_n_s16(0);
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t a0 = vld1q_s16(A + i + 0);
+    const int16x8_t a1 = vld1q_s16(A + i + 1);
+    const int16x8_t b0 = vld1q_s16(B + i + 0);
+    const int16x8_t b1 = vld1q_s16(B + i + 1);
+    const int16x8_t a0b1 = vaddq_s16(a0, b1);
+    const int16x8_t a1b0 = vaddq_s16(a1, b0);
+    const int16x8_t a0a1b0b1 = vaddq_s16(a0b1, a1b0);  // A0+A1+B0+B1
+    const int16x8_t a0b1_2 = vaddq_s16(a0b1, a0b1);    // 2*(A0+B1)
+    const int16x8_t a1b0_2 = vaddq_s16(a1b0, a1b0);    // 2*(A1+B0)
+    const int16x8_t c0 = vshrq_n_s16(vaddq_s16(a0b1_2, a0a1b0b1), 3);
+    const int16x8_t c1 = vshrq_n_s16(vaddq_s16(a1b0_2, a0a1b0b1), 3);
+    const int16x8_t e0 = vrhaddq_s16(c1, a0);
+    const int16x8_t e1 = vrhaddq_s16(c0, a1);
+    const int16x8x2_t f = vzipq_s16(e0, e1);
+    const int16x8_t g0 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 0));
+    const int16x8_t g1 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 8));
+    const int16x8_t h0 = vaddq_s16(g0, f.val[0]);
+    const int16x8_t h1 = vaddq_s16(g1, f.val[1]);
+    const int16x8_t i0 = vmaxq_s16(vminq_s16(h0, max), zero);
+    const int16x8_t i1 = vmaxq_s16(vminq_s16(h1, max), zero);
+    vst1q_u16(out + 2 * i + 0, vreinterpretq_u16_s16(i0));
+    vst1q_u16(out + 2 * i + 8, vreinterpretq_u16_s16(i1));
+  }
+  for (; i < len; ++i) {
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow32_NEON(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const uint16x8_t max = vdupq_n_u16(max_y);
+  for (i = 0; i + 4 <= len; i += 4) {
+    const int16x4_t a0 = vld1_s16(A + i + 0);
+    const int16x4_t a1 = vld1_s16(A + i + 1);
+    const int16x4_t b0 = vld1_s16(B + i + 0);
+    const int16x4_t b1 = vld1_s16(B + i + 1);
+    const int32x4_t a0b1 = vaddl_s16(a0, b1);
+    const int32x4_t a1b0 = vaddl_s16(a1, b0);
+    const int32x4_t a0a1b0b1 = vaddq_s32(a0b1, a1b0);  // A0+A1+B0+B1
+    const int32x4_t a0b1_2 = vaddq_s32(a0b1, a0b1);    // 2*(A0+B1)
+    const int32x4_t a1b0_2 = vaddq_s32(a1b0, a1b0);    // 2*(A1+B0)
+    const int32x4_t c0 = vshrq_n_s32(vaddq_s32(a0b1_2, a0a1b0b1), 3);
+    const int32x4_t c1 = vshrq_n_s32(vaddq_s32(a1b0_2, a0a1b0b1), 3);
+    const int32x4_t e0 = vrhaddq_s32(c1, vmovl_s16(a0));
+    const int32x4_t e1 = vrhaddq_s32(c0, vmovl_s16(a1));
+    const int32x4x2_t f = vzipq_s32(e0, e1);
+
+    const int16x8_t g = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i));
+    const int32x4_t h0 = vaddw_s16(f.val[0], vget_low_s16(g));
+    const int32x4_t h1 = vaddw_s16(f.val[1], vget_high_s16(g));
+    const uint16x8_t i_16 = vcombine_u16(vqmovun_s32(h0), vqmovun_s32(h1));
+    const uint16x8_t i_clamped = vminq_u16(i_16, max);
+    vst1q_u16(out + 2 * i + 0, i_clamped);
+  }
+  for (; i < len; ++i) {
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
+                                   const uint16_t* best_y, uint16_t* out,
+                                   int bit_depth) {
+  if (bit_depth <= 10) {
+    SharpYuvFilterRow16_NEON(A, B, len, best_y, out, bit_depth);
+  } else {
+    SharpYuvFilterRow32_NEON(A, B, len, best_y, out, bit_depth);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+extern void InitSharpYuvNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
+  SharpYuvUpdateY = SharpYuvUpdateY_NEON;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON;
+  SharpYuvFilterRow = SharpYuvFilterRow_NEON;
+}
+
+#else  // !WEBP_USE_NEON
+
+extern void InitSharpYuvNEON(void);
+
+void InitSharpYuvNEON(void) {}
+
+#endif  // WEBP_USE_NEON
diff --git a/third_party/libwebp/sharpyuv/sharpyuv_sse2.c b/third_party/libwebp/sharpyuv/sharpyuv_sse2.c
new file mode 100644
index 0000000..9744d1b
--- /dev/null
+++ b/third_party/libwebp/sharpyuv/sharpyuv_sse2.c
@@ -0,0 +1,201 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <stdlib.h>
+#include <emmintrin.h>
+
+static uint16_t clip_SSE2(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
+                                     uint16_t* dst, int len, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  uint64_t diff = 0;
+  uint32_t tmp[4];
+  int i;
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i one = _mm_set1_epi16(1);
+  __m128i sum = zero;
+
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+    const __m128i D = _mm_sub_epi16(A, B);       // diff_y
+    const __m128i E = _mm_cmpgt_epi16(zero, D);  // sign (-1 or 0)
+    const __m128i F = _mm_add_epi16(C, D);       // new_y
+    const __m128i G = _mm_or_si128(E, one);      // -1 or 1
+    const __m128i H = _mm_max_epi16(_mm_min_epi16(F, max), zero);
+    const __m128i I = _mm_madd_epi16(D, G);      // sum(abs(...))
+    _mm_storeu_si128((__m128i*)(dst + i), H);
+    sum = _mm_add_epi32(sum, I);
+  }
+  _mm_storeu_si128((__m128i*)tmp, sum);
+  diff = tmp[3] + tmp[2] + tmp[1] + tmp[0];
+  for (; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)dst[i] + diff_y;
+    dst[i] = clip_SSE2(new_y, max_y);
+    diff += (uint64_t)abs(diff_y);
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
+                                   int16_t* dst, int len) {
+  int i = 0;
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+    const __m128i D = _mm_sub_epi16(A, B);   // diff_uv
+    const __m128i E = _mm_add_epi16(C, D);   // new_uv
+    _mm_storeu_si128((__m128i*)(dst + i), E);
+  }
+  for (; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow16_SSE2(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const __m128i kCst8 = _mm_set1_epi16(8);
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i zero = _mm_setzero_si128();
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)(A + i + 0));
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)(A + i + 1));
+    const __m128i b0 = _mm_loadu_si128((const __m128i*)(B + i + 0));
+    const __m128i b1 = _mm_loadu_si128((const __m128i*)(B + i + 1));
+    const __m128i a0b1 = _mm_add_epi16(a0, b1);
+    const __m128i a1b0 = _mm_add_epi16(a1, b0);
+    const __m128i a0a1b0b1 = _mm_add_epi16(a0b1, a1b0);  // A0+A1+B0+B1
+    const __m128i a0a1b0b1_8 = _mm_add_epi16(a0a1b0b1, kCst8);
+    const __m128i a0b1_2 = _mm_add_epi16(a0b1, a0b1);    // 2*(A0+B1)
+    const __m128i a1b0_2 = _mm_add_epi16(a1b0, a1b0);    // 2*(A1+B0)
+    const __m128i c0 = _mm_srai_epi16(_mm_add_epi16(a0b1_2, a0a1b0b1_8), 3);
+    const __m128i c1 = _mm_srai_epi16(_mm_add_epi16(a1b0_2, a0a1b0b1_8), 3);
+    const __m128i d0 = _mm_add_epi16(c1, a0);
+    const __m128i d1 = _mm_add_epi16(c0, a1);
+    const __m128i e0 = _mm_srai_epi16(d0, 1);
+    const __m128i e1 = _mm_srai_epi16(d1, 1);
+    const __m128i f0 = _mm_unpacklo_epi16(e0, e1);
+    const __m128i f1 = _mm_unpackhi_epi16(e0, e1);
+    const __m128i g0 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
+    const __m128i g1 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 8));
+    const __m128i h0 = _mm_add_epi16(g0, f0);
+    const __m128i h1 = _mm_add_epi16(g1, f1);
+    const __m128i i0 = _mm_max_epi16(_mm_min_epi16(h0, max), zero);
+    const __m128i i1 = _mm_max_epi16(_mm_min_epi16(h1, max), zero);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 0), i0);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 8), i1);
+  }
+  for (; i < len; ++i) {
+    //   (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
+    // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
+    // We reuse the common sub-expressions.
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static WEBP_INLINE __m128i s16_to_s32(__m128i in) {
+  return _mm_srai_epi32(_mm_unpacklo_epi16(in, in), 16);
+}
+
+static void SharpYuvFilterRow32_SSE2(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const __m128i kCst8 = _mm_set1_epi32(8);
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i zero = _mm_setzero_si128();
+  for (i = 0; i + 4 <= len; i += 4) {
+    const __m128i a0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 0)));
+    const __m128i a1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 1)));
+    const __m128i b0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 0)));
+    const __m128i b1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 1)));
+    const __m128i a0b1 = _mm_add_epi32(a0, b1);
+    const __m128i a1b0 = _mm_add_epi32(a1, b0);
+    const __m128i a0a1b0b1 = _mm_add_epi32(a0b1, a1b0);  // A0+A1+B0+B1
+    const __m128i a0a1b0b1_8 = _mm_add_epi32(a0a1b0b1, kCst8);
+    const __m128i a0b1_2 = _mm_add_epi32(a0b1, a0b1);  // 2*(A0+B1)
+    const __m128i a1b0_2 = _mm_add_epi32(a1b0, a1b0);  // 2*(A1+B0)
+    const __m128i c0 = _mm_srai_epi32(_mm_add_epi32(a0b1_2, a0a1b0b1_8), 3);
+    const __m128i c1 = _mm_srai_epi32(_mm_add_epi32(a1b0_2, a0a1b0b1_8), 3);
+    const __m128i d0 = _mm_add_epi32(c1, a0);
+    const __m128i d1 = _mm_add_epi32(c0, a1);
+    const __m128i e0 = _mm_srai_epi32(d0, 1);
+    const __m128i e1 = _mm_srai_epi32(d1, 1);
+    const __m128i f0 = _mm_unpacklo_epi32(e0, e1);
+    const __m128i f1 = _mm_unpackhi_epi32(e0, e1);
+    const __m128i g = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
+    const __m128i h_16 = _mm_add_epi16(g, _mm_packs_epi32(f0, f1));
+    const __m128i final = _mm_max_epi16(_mm_min_epi16(h_16, max), zero);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 0), final);
+  }
+  for (; i < len; ++i) {
+    //   (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
+    // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
+    // We reuse the common sub-expressions.
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
+                                   const uint16_t* best_y, uint16_t* out,
+                                   int bit_depth) {
+  if (bit_depth <= 10) {
+    SharpYuvFilterRow16_SSE2(A, B, len, best_y, out, bit_depth);
+  } else {
+    SharpYuvFilterRow32_SSE2(A, B, len, best_y, out, bit_depth);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+extern void InitSharpYuvSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) {
+  SharpYuvUpdateY = SharpYuvUpdateY_SSE2;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_SSE2;
+  SharpYuvFilterRow = SharpYuvFilterRow_SSE2;
+}
+#else  // !WEBP_USE_SSE2
+
+extern void InitSharpYuvSSE2(void);
+
+void InitSharpYuvSSE2(void) {}
+
+#endif  // WEBP_USE_SSE2
diff --git a/third_party/libwebp/src/Makefile.am b/third_party/libwebp/src/Makefile.am
index 32cfa38..23da9fb 100644
--- a/third_party/libwebp/src/Makefile.am
+++ b/third_party/libwebp/src/Makefile.am
@@ -1,10 +1,10 @@
 # The mux and demux libraries depend on libwebp, thus the '.' to force
 # the build order so it's available to them.
 SUBDIRS = dec enc dsp utils .
-if WANT_MUX
+if BUILD_MUX
   SUBDIRS += mux
 endif
-if WANT_DEMUX
+if BUILD_DEMUX
   SUBDIRS += demux
 endif
 
@@ -36,7 +36,7 @@
 # other than the ones listed on the command line, i.e., after linking, it will
 # not have unresolved symbols. Some platforms (Windows among them) require all
 # symbols in shared libraries to be resolved at library creation.
-libwebp_la_LDFLAGS = -no-undefined -version-info 7:2:0
+libwebp_la_LDFLAGS = -no-undefined -version-info 8:7:1
 libwebpincludedir = $(includedir)/webp
 pkgconfig_DATA = libwebp.pc
 
@@ -48,7 +48,7 @@
   libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
   libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
 
-  libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:2:0
+  libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:7:1
   pkgconfig_DATA += libwebpdecoder.pc
 endif
 
diff --git a/third_party/libwebp/src/dec/alpha_dec.c b/third_party/libwebp/src/dec/alpha_dec.c
index c2bef1d..94d71ac 100644
--- a/third_party/libwebp/src/dec/alpha_dec.c
+++ b/third_party/libwebp/src/dec/alpha_dec.c
@@ -189,7 +189,7 @@
   assert(dec != NULL && io != NULL);
 
   if (row < 0 || num_rows <= 0 || row + num_rows > height) {
-    return NULL;    // sanity check.
+    return NULL;
   }
 
   if (!dec->is_alpha_decoded_) {
diff --git a/third_party/libwebp/src/dec/alphai_dec.h b/third_party/libwebp/src/dec/alphai_dec.h
index e0fa281..a64104a 100644
--- a/third_party/libwebp/src/dec/alphai_dec.h
+++ b/third_party/libwebp/src/dec/alphai_dec.h
@@ -51,4 +51,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DEC_ALPHAI_DEC_H_ */
+#endif  // WEBP_DEC_ALPHAI_DEC_H_
diff --git a/third_party/libwebp/src/dec/buffer_dec.c b/third_party/libwebp/src/dec/buffer_dec.c
index d6d99b9..8ca5e23 100644
--- a/third_party/libwebp/src/dec/buffer_dec.c
+++ b/third_party/libwebp/src/dec/buffer_dec.c
@@ -79,7 +79,8 @@
   } else {    // RGB checks
     const WebPRGBABuffer* const buf = &buffer->u.RGBA;
     const int stride = abs(buf->stride);
-    const uint64_t size = MIN_BUFFER_SIZE(width, height, stride);
+    const uint64_t size =
+        MIN_BUFFER_SIZE(width * kModeBpp[mode], height, stride);
     ok &= (size <= buf->size);
     ok &= (stride >= width * kModeBpp[mode]);
     ok &= (buf->rgba != NULL);
@@ -106,7 +107,7 @@
     int stride;
     uint64_t size;
 
-    if ((uint64_t)w * kModeBpp[mode] >= (1ull << 32)) {
+    if ((uint64_t)w * kModeBpp[mode] >= (1ull << 31)) {
       return VP8_STATUS_INVALID_PARAM;
     }
     stride = w * kModeBpp[mode];
@@ -121,7 +122,6 @@
     }
     total_size = size + 2 * uv_size + a_size;
 
-    // Security/sanity checks
     output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
     if (output == NULL) {
       return VP8_STATUS_OUT_OF_MEMORY;
@@ -160,11 +160,11 @@
   }
   if (WebPIsRGBMode(buffer->colorspace)) {
     WebPRGBABuffer* const buf = &buffer->u.RGBA;
-    buf->rgba += (buffer->height - 1) * buf->stride;
+    buf->rgba += (int64_t)(buffer->height - 1) * buf->stride;
     buf->stride = -buf->stride;
   } else {
     WebPYUVABuffer* const buf = &buffer->u.YUVA;
-    const int H = buffer->height;
+    const int64_t H = buffer->height;
     buf->y += (H - 1) * buf->y_stride;
     buf->y_stride = -buf->y_stride;
     buf->u += ((H - 1) >> 1) * buf->u_stride;
@@ -192,8 +192,7 @@
       const int ch = options->crop_height;
       const int x = options->crop_left & ~1;
       const int y = options->crop_top & ~1;
-      if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
-          x + cw > width || y + ch > height) {
+      if (!WebPCheckCropDimensions(width, height, x, y, cw, ch)) {
         return VP8_STATUS_INVALID_PARAM;   // out of frame boundary.
       }
       width = cw;
diff --git a/third_party/libwebp/src/dec/common_dec.h b/third_party/libwebp/src/dec/common_dec.h
index 9995f1a..b158550 100644
--- a/third_party/libwebp/src/dec/common_dec.h
+++ b/third_party/libwebp/src/dec/common_dec.h
@@ -51,4 +51,4 @@
        NUM_PROBAS = 11
      };
 
-#endif    // WEBP_DEC_COMMON_DEC_H_
+#endif  // WEBP_DEC_COMMON_DEC_H_
diff --git a/third_party/libwebp/src/dec/frame_dec.c b/third_party/libwebp/src/dec/frame_dec.c
index 0d44798..98fba09 100644
--- a/third_party/libwebp/src/dec/frame_dec.c
+++ b/third_party/libwebp/src/dec/frame_dec.c
@@ -344,7 +344,6 @@
       for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
         VP8QuantMatrix* const dqm = &dec->dqm_[s];
         if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) {
-          // TODO(skal): should we specially dither more for uv_quant_ < 0?
           const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_;
           dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3;
         }
@@ -675,15 +674,9 @@
   (void)height;
   assert(headers == NULL || !headers->is_lossless);
 #if defined(WEBP_USE_THREAD)
-  if (width < MIN_WIDTH_FOR_THREADS) return 0;
-  // TODO(skal): tune the heuristic further
-#if 0
-  if (height < 2 * width) return 2;
+  if (width >= MIN_WIDTH_FOR_THREADS) return 2;
 #endif
-  return 2;
-#else   // !WEBP_USE_THREAD
   return 0;
-#endif
 }
 
 #undef MT_CACHE_LINES
@@ -718,7 +711,7 @@
                         + cache_size + alpha_size + WEBP_ALIGN_CST;
   uint8_t* mem;
 
-  if (needed != (size_t)needed) return 0;  // check for overflow
+  if (!CheckSizeOverflow(needed)) return 0;  // check for overflow
   if (needed > dec->mem_size_) {
     WebPSafeFree(dec->mem_);
     dec->mem_size_ = 0;
@@ -745,7 +738,7 @@
   mem += f_info_size;
   dec->thread_ctx_.id_ = 0;
   dec->thread_ctx_.f_info_ = dec->f_info_;
-  if (dec->mt_method_ > 0) {
+  if (dec->filter_type_ > 0 && dec->mt_method_ > 0) {
     // secondary cache line. The deblocking process need to make use of the
     // filtering strength from previous macroblock row, while the new ones
     // are being decoded in parallel. We'll just swap the pointers.
diff --git a/third_party/libwebp/src/dec/idec_dec.c b/third_party/libwebp/src/dec/idec_dec.c
index d7d0226..cf3c967 100644
--- a/third_party/libwebp/src/dec/idec_dec.c
+++ b/third_party/libwebp/src/dec/idec_dec.c
@@ -146,10 +146,9 @@
       if (NeedCompressedAlpha(idec)) {
         ALPHDecoder* const alph_dec = dec->alph_dec_;
         dec->alpha_data_ += offset;
-        if (alph_dec != NULL) {
+        if (alph_dec != NULL && alph_dec->vp8l_dec_ != NULL) {
           if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
             VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
-            assert(alph_vp8l_dec != NULL);
             assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
             VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
                                    dec->alpha_data_ + ALPHA_HEADER_LEN,
@@ -173,9 +172,11 @@
   VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
   MemBuffer* const mem = &idec->mem_;
   const int need_compressed_alpha = NeedCompressedAlpha(idec);
-  const uint8_t* const old_start = mem->buf_ + mem->start_;
+  const uint8_t* const old_start =
+      (mem->buf_ == NULL) ? NULL : mem->buf_ + mem->start_;
   const uint8_t* const old_base =
       need_compressed_alpha ? dec->alpha_data_ : old_start;
+  assert(mem->buf_ != NULL || mem->start_ == 0);
   assert(mem->mode_ == MEM_MODE_APPEND);
   if (data_size > MAX_CHUNK_PAYLOAD) {
     // security safeguard: trying to allocate more than what the format
@@ -191,7 +192,7 @@
     uint8_t* const new_buf =
         (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
     if (new_buf == NULL) return 0;
-    memcpy(new_buf, old_base, current_size);
+    if (old_base != NULL) memcpy(new_buf, old_base, current_size);
     WebPSafeFree(mem->buf_);
     mem->buf_ = new_buf;
     mem->buf_size_ = (size_t)extra_size;
@@ -199,6 +200,7 @@
     mem->end_ = current_size;
   }
 
+  assert(mem->buf_ != NULL);
   memcpy(mem->buf_ + mem->end_, data, data_size);
   mem->end_ += data_size;
   assert(mem->end_ <= mem->buf_size_);
@@ -211,7 +213,9 @@
                           const uint8_t* const data, size_t data_size) {
   MemBuffer* const mem = &idec->mem_;
   const uint8_t* const old_buf = mem->buf_;
-  const uint8_t* const old_start = old_buf + mem->start_;
+  const uint8_t* const old_start =
+      (old_buf == NULL) ? NULL : old_buf + mem->start_;
+  assert(old_buf != NULL || mem->start_ == 0);
   assert(mem->mode_ == MEM_MODE_MAP);
 
   if (data_size < mem->buf_size_) return 0;  // can't remap to a shorter buffer!
@@ -289,10 +293,8 @@
 
 static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
   if (idec->state_ == STATE_VP8_DATA) {
-    VP8Io* const io = &idec->io_;
-    if (io->teardown != NULL) {
-      io->teardown(io);
-    }
+    // Synchronize the thread, clean-up and check for errors.
+    VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
   }
   idec->state_ = STATE_ERROR;
   return error;
@@ -457,7 +459,10 @@
   VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
   VP8Io* const io = &idec->io_;
 
-  assert(dec->ready_);
+  // Make sure partition #0 has been read before, to set dec to ready_.
+  if (!dec->ready_) {
+    return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+  }
   for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
     if (idec->last_mb_y_ != dec->mb_y_) {
       if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
@@ -479,6 +484,12 @@
             MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
           return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
         }
+        // Synchronize the threads.
+        if (dec->mt_method_ > 0) {
+          if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) {
+            return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+          }
+        }
         RestoreContext(&context, dec, token_br);
         return VP8_STATUS_SUSPENDED;
       }
@@ -497,6 +508,7 @@
   }
   // Synchronize the thread and check for errors.
   if (!VP8ExitCritical(dec, io)) {
+    idec->state_ = STATE_ERROR;  // prevent re-entry in IDecError
     return IDecError(idec, VP8_STATUS_USER_ABORT);
   }
   dec->ready_ = 0;
@@ -577,6 +589,10 @@
     status = DecodePartition0(idec);
   }
   if (idec->state_ == STATE_VP8_DATA) {
+    const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+    if (dec == NULL) {
+      return VP8_STATUS_SUSPENDED;  // can't continue if we have no decoder.
+    }
     status = DecodeRemaining(idec);
   }
   if (idec->state_ == STATE_VP8L_HEADER) {
diff --git a/third_party/libwebp/src/dec/io_dec.c b/third_party/libwebp/src/dec/io_dec.c
index 1924435..a67af25 100644
--- a/third_party/libwebp/src/dec/io_dec.c
+++ b/third_party/libwebp/src/dec/io_dec.c
@@ -32,21 +32,16 @@
 static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
   WebPDecBuffer* output = p->output;
   const WebPYUVABuffer* const buf = &output->u.YUVA;
-  uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
-  uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
-  uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
+  uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
+  uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
+  uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
   const int mb_w = io->mb_w;
   const int mb_h = io->mb_h;
   const int uv_w = (mb_w + 1) / 2;
   const int uv_h = (mb_h + 1) / 2;
-  int j;
-  for (j = 0; j < mb_h; ++j) {
-    memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
-  }
-  for (j = 0; j < uv_h; ++j) {
-    memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
-    memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
-  }
+  WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
+  WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
+  WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
   return io->mb_h;
 }
 
@@ -54,7 +49,7 @@
 static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
   WebPDecBuffer* const output = p->output;
   WebPRGBABuffer* const buf = &output->u.RGBA;
-  uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
+  uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
   WebPSamplerProcessPlane(io->y, io->y_stride,
                           io->u, io->v, io->uv_stride,
                           dst, buf->stride, io->mb_w, io->mb_h,
@@ -69,7 +64,7 @@
 static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
   int num_lines_out = io->mb_h;   // a priori guess
   const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
+  uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
   WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
   const uint8_t* cur_y = io->y;
   const uint8_t* cur_u = io->u;
@@ -140,7 +135,7 @@
   const WebPYUVABuffer* const buf = &p->output->u.YUVA;
   const int mb_w = io->mb_w;
   const int mb_h = io->mb_h;
-  uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
+  uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
   int j;
   (void)expected_num_lines_out;
   assert(expected_num_lines_out == mb_h);
@@ -193,7 +188,7 @@
         (colorspace == MODE_ARGB || colorspace == MODE_Argb);
     const WebPRGBABuffer* const buf = &p->output->u.RGBA;
     int num_rows;
-    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+    const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
     uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
     uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
     const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
@@ -217,7 +212,7 @@
     const WEBP_CSP_MODE colorspace = p->output->colorspace;
     const WebPRGBABuffer* const buf = &p->output->u.RGBA;
     int num_rows;
-    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+    const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
     uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
 #if (WEBP_SWAP_16BIT_CSP == 1)
     uint8_t* alpha_dst = base_rgba;
@@ -283,9 +278,9 @@
 static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
                                 int expected_num_lines_out) {
   const WebPYUVABuffer* const buf = &p->output->u.YUVA;
-  uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
+  uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
   if (io->a != NULL) {
-    uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
+    uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
     const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
     assert(expected_num_lines_out == num_lines_out);
     if (num_lines_out > 0) {   // unmultiply the Y
@@ -310,46 +305,57 @@
   const int uv_out_height = (out_height + 1) >> 1;
   const int uv_in_width  = (io->mb_w + 1) >> 1;
   const int uv_in_height = (io->mb_h + 1) >> 1;
-  const size_t work_size = 2 * out_width;   // scratch memory for luma rescaler
+  // scratch memory for luma rescaler
+  const size_t work_size = 2 * (size_t)out_width;
   const size_t uv_work_size = 2 * uv_out_width;  // and for each u/v ones
-  size_t tmp_size, rescaler_size;
+  uint64_t total_size;
+  size_t rescaler_size;
   rescaler_t* work;
   WebPRescaler* scalers;
   const int num_rescalers = has_alpha ? 4 : 3;
 
-  tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
+  total_size = ((uint64_t)work_size + 2 * uv_work_size) * sizeof(*work);
   if (has_alpha) {
-    tmp_size += work_size * sizeof(*work);
+    total_size += (uint64_t)work_size * sizeof(*work);
   }
   rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
+  total_size += rescaler_size;
+  if (!CheckSizeOverflow(total_size)) {
+    return 0;
+  }
 
-  p->memory = WebPSafeMalloc(1ULL, tmp_size + rescaler_size);
+  p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
   if (p->memory == NULL) {
     return 0;   // memory error
   }
   work = (rescaler_t*)p->memory;
 
-  scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + tmp_size);
+  scalers = (WebPRescaler*)WEBP_ALIGN(
+      (const uint8_t*)work + total_size - rescaler_size);
   p->scaler_y = &scalers[0];
   p->scaler_u = &scalers[1];
   p->scaler_v = &scalers[2];
   p->scaler_a = has_alpha ? &scalers[3] : NULL;
 
-  WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
-                   buf->y, out_width, out_height, buf->y_stride, 1,
-                   work);
-  WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
-                   buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
-                   work + work_size);
-  WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
-                   buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
-                   work + work_size + uv_work_size);
+  if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
+                        buf->y, out_width, out_height, buf->y_stride, 1,
+                        work) ||
+      !WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
+                        buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
+                        work + work_size) ||
+      !WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
+                        buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
+                        work + work_size + uv_work_size)) {
+    return 0;
+  }
   p->emit = EmitRescaledYUV;
 
   if (has_alpha) {
-    WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
-                     buf->a, out_width, out_height, buf->a_stride, 1,
-                     work + work_size + 2 * uv_work_size);
+    if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
+                          buf->a, out_width, out_height, buf->a_stride, 1,
+                          work + work_size + 2 * uv_work_size)) {
+      return 0;
+    }
     p->emit_alpha = EmitRescaledAlphaYUV;
     WebPInitAlphaProcessing();
   }
@@ -363,7 +369,7 @@
   const WebPYUV444Converter convert =
       WebPYUV444Converters[p->output->colorspace];
   const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* dst = buf->rgba + y_pos * buf->stride;
+  uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
   int num_lines_out = 0;
   // For RGB rescaling, because of the YUV420, current scan position
   // U/V can be +1/-1 line from the Y one.  Hence the double test.
@@ -390,15 +396,15 @@
   while (j < mb_h) {
     const int y_lines_in =
         WebPRescalerImport(p->scaler_y, mb_h - j,
-                           io->y + j * io->y_stride, io->y_stride);
+                           io->y + (size_t)j * io->y_stride, io->y_stride);
     j += y_lines_in;
     if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
-      const int u_lines_in =
-          WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
-                             io->u + uv_j * io->uv_stride, io->uv_stride);
-      const int v_lines_in =
-          WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
-                             io->v + uv_j * io->uv_stride, io->uv_stride);
+      const int u_lines_in = WebPRescalerImport(
+          p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
+          io->uv_stride);
+      const int v_lines_in = WebPRescalerImport(
+          p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
+          io->uv_stride);
       (void)v_lines_in;   // remove a gcc warning
       assert(u_lines_in == v_lines_in);
       uv_j += u_lines_in;
@@ -410,7 +416,7 @@
 
 static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
   const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
+  uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
   const WEBP_CSP_MODE colorspace = p->output->colorspace;
   const int alpha_first =
       (colorspace == MODE_ARGB || colorspace == MODE_Argb);
@@ -438,7 +444,7 @@
 static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
                                int max_lines_out) {
   const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
+  uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
 #if (WEBP_SWAP_16BIT_CSP == 1)
   uint8_t* alpha_dst = base_rgba;
 #else
@@ -477,7 +483,7 @@
     int lines_left = expected_num_out_lines;
     const int y_end = p->last_y + lines_left;
     while (lines_left > 0) {
-      const int row_offset = scaler->src_y - io->mb_y;
+      const int64_t row_offset = (int64_t)scaler->src_y - io->mb_y;
       WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
                          io->a + row_offset * io->width, io->width);
       lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
@@ -492,51 +498,58 @@
   const int out_height = io->scaled_height;
   const int uv_in_width  = (io->mb_w + 1) >> 1;
   const int uv_in_height = (io->mb_h + 1) >> 1;
-  const size_t work_size = 2 * out_width;   // scratch memory for one rescaler
+  // scratch memory for one rescaler
+  const size_t work_size = 2 * (size_t)out_width;
   rescaler_t* work;  // rescalers work area
   uint8_t* tmp;   // tmp storage for scaled YUV444 samples before RGB conversion
-  size_t tmp_size1, tmp_size2, total_size, rescaler_size;
+  uint64_t tmp_size1, tmp_size2, total_size;
+  size_t rescaler_size;
   WebPRescaler* scalers;
   const int num_rescalers = has_alpha ? 4 : 3;
 
-  tmp_size1 = 3 * work_size;
-  tmp_size2 = 3 * out_width;
-  if (has_alpha) {
-    tmp_size1 += work_size;
-    tmp_size2 += out_width;
-  }
+  tmp_size1 = (uint64_t)num_rescalers * work_size;
+  tmp_size2 = (uint64_t)num_rescalers * out_width;
   total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
   rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
+  total_size += rescaler_size;
+  if (!CheckSizeOverflow(total_size)) {
+    return 0;
+  }
 
-  p->memory = WebPSafeMalloc(1ULL, total_size + rescaler_size);
+  p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
   if (p->memory == NULL) {
     return 0;   // memory error
   }
   work = (rescaler_t*)p->memory;
   tmp = (uint8_t*)(work + tmp_size1);
 
-  scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + total_size);
+  scalers = (WebPRescaler*)WEBP_ALIGN(
+      (const uint8_t*)work + total_size - rescaler_size);
   p->scaler_y = &scalers[0];
   p->scaler_u = &scalers[1];
   p->scaler_v = &scalers[2];
   p->scaler_a = has_alpha ? &scalers[3] : NULL;
 
-  WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
-                   tmp + 0 * out_width, out_width, out_height, 0, 1,
-                   work + 0 * work_size);
-  WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
-                   tmp + 1 * out_width, out_width, out_height, 0, 1,
-                   work + 1 * work_size);
-  WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
-                   tmp + 2 * out_width, out_width, out_height, 0, 1,
-                   work + 2 * work_size);
+  if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
+                        tmp + 0 * out_width, out_width, out_height, 0, 1,
+                        work + 0 * work_size) ||
+      !WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
+                        tmp + 1 * out_width, out_width, out_height, 0, 1,
+                        work + 1 * work_size) ||
+      !WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
+                        tmp + 2 * out_width, out_width, out_height, 0, 1,
+                        work + 2 * work_size)) {
+    return 0;
+  }
   p->emit = EmitRescaledRGB;
   WebPInitYUV444Converters();
 
   if (has_alpha) {
-    WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
-                     tmp + 3 * out_width, out_width, out_height, 0, 1,
-                     work + 3 * work_size);
+    if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
+                          tmp + 3 * out_width, out_width, out_height, 0, 1,
+                          work + 3 * work_size)) {
+      return 0;
+    }
     p->emit_alpha = EmitRescaledAlphaRGB;
     if (p->output->colorspace == MODE_RGBA_4444 ||
         p->output->colorspace == MODE_rgbA_4444) {
diff --git a/third_party/libwebp/src/dec/quant_dec.c b/third_party/libwebp/src/dec/quant_dec.c
index f07212a..a0ac018 100644
--- a/third_party/libwebp/src/dec/quant_dec.c
+++ b/third_party/libwebp/src/dec/quant_dec.c
@@ -61,12 +61,17 @@
 
 void VP8ParseQuant(VP8Decoder* const dec) {
   VP8BitReader* const br = &dec->br_;
-  const int base_q0 = VP8GetValue(br, 7);
-  const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+  const int base_q0 = VP8GetValue(br, 7, "global-header");
+  const int dqy1_dc = VP8Get(br, "global-header") ?
+       VP8GetSignedValue(br, 4, "global-header") : 0;
+  const int dqy2_dc = VP8Get(br, "global-header") ?
+       VP8GetSignedValue(br, 4, "global-header") : 0;
+  const int dqy2_ac = VP8Get(br, "global-header") ?
+       VP8GetSignedValue(br, 4, "global-header") : 0;
+  const int dquv_dc = VP8Get(br, "global-header") ?
+       VP8GetSignedValue(br, 4, "global-header") : 0;
+  const int dquv_ac = VP8Get(br, "global-header") ?
+       VP8GetSignedValue(br, 4, "global-header") : 0;
 
   const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
   int i;
diff --git a/third_party/libwebp/src/dec/tree_dec.c b/third_party/libwebp/src/dec/tree_dec.c
index 1bd4dfc..5b24c70 100644
--- a/third_party/libwebp/src/dec/tree_dec.c
+++ b/third_party/libwebp/src/dec/tree_dec.c
@@ -16,10 +16,11 @@
 #endif
 
 #include "src/dec/vp8i_dec.h"
+#include "src/dsp/cpu.h"
 #include "src/utils/bit_reader_inl_utils.h"
 
 #if !defined(USE_GENERIC_TREE)
-#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
+#if !defined(__arm__) && !defined(_M_ARM) && !WEBP_AARCH64
 // using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
 #define USE_GENERIC_TREE 1   // ALTERNATE_CODE
 #else
@@ -300,20 +301,21 @@
   // to decode more than 1 keyframe.
   if (dec->segment_hdr_.update_map_) {
     // Hardcoded tree parsing
-    block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0])
-                    ? VP8GetBit(br, dec->proba_.segments_[1])
-                    : 2 + VP8GetBit(br, dec->proba_.segments_[2]);
+    block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0], "segments")
+                    ?  VP8GetBit(br, dec->proba_.segments_[1], "segments")
+                    :  VP8GetBit(br, dec->proba_.segments_[2], "segments") + 2;
   } else {
     block->segment_ = 0;  // default for intra
   }
-  if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_);
+  if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_, "skip");
 
-  block->is_i4x4_ = !VP8GetBit(br, 145);   // decide for B_PRED first
+  block->is_i4x4_ = !VP8GetBit(br, 145, "block-size");
   if (!block->is_i4x4_) {
     // Hardcoded 16x16 intra-mode decision tree.
     const int ymode =
-        VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
-                           : (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
+        VP8GetBit(br, 156, "pred-modes") ?
+            (VP8GetBit(br, 128, "pred-modes") ? TM_PRED : H_PRED) :
+            (VP8GetBit(br, 163, "pred-modes") ? V_PRED : DC_PRED);
     block->imodes_[0] = ymode;
     memset(top, ymode, 4 * sizeof(*top));
     memset(left, ymode, 4 * sizeof(*left));
@@ -327,22 +329,25 @@
         const uint8_t* const prob = kBModesProba[top[x]][ymode];
 #if (USE_GENERIC_TREE == 1)
         // Generic tree-parsing
-        int i = kYModesIntra4[VP8GetBit(br, prob[0])];
+        int i = kYModesIntra4[VP8GetBit(br, prob[0], "pred-modes")];
         while (i > 0) {
-          i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
+          i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i], "pred-modes")];
         }
         ymode = -i;
 #else
         // Hardcoded tree parsing
-        ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
-                  !VP8GetBit(br, prob[1]) ? B_TM_PRED :
-                    !VP8GetBit(br, prob[2]) ? B_VE_PRED :
-                      !VP8GetBit(br, prob[3]) ?
-                        (!VP8GetBit(br, prob[4]) ? B_HE_PRED :
-                          (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
-                        (!VP8GetBit(br, prob[6]) ? B_LD_PRED :
-                          (!VP8GetBit(br, prob[7]) ? B_VL_PRED :
-                            (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
+        ymode = !VP8GetBit(br, prob[0], "pred-modes") ? B_DC_PRED :
+                  !VP8GetBit(br, prob[1], "pred-modes") ? B_TM_PRED :
+                    !VP8GetBit(br, prob[2], "pred-modes") ? B_VE_PRED :
+                      !VP8GetBit(br, prob[3], "pred-modes") ?
+                        (!VP8GetBit(br, prob[4], "pred-modes") ? B_HE_PRED :
+                          (!VP8GetBit(br, prob[5], "pred-modes") ? B_RD_PRED
+                                                                 : B_VR_PRED)) :
+                        (!VP8GetBit(br, prob[6], "pred-modes") ? B_LD_PRED :
+                          (!VP8GetBit(br, prob[7], "pred-modes") ? B_VL_PRED :
+                            (!VP8GetBit(br, prob[8], "pred-modes") ? B_HD_PRED
+                                                                   : B_HU_PRED))
+                        );
 #endif  // USE_GENERIC_TREE
         top[x] = ymode;
       }
@@ -352,9 +357,9 @@
     }
   }
   // Hardcoded UVMode decision tree
-  block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
-                 : !VP8GetBit(br, 114) ? V_PRED
-                 : VP8GetBit(br, 183) ? TM_PRED : H_PRED;
+  block->uvmode_ = !VP8GetBit(br, 142, "pred-modes-uv") ? DC_PRED
+                 : !VP8GetBit(br, 114, "pred-modes-uv") ? V_PRED
+                 : VP8GetBit(br, 183, "pred-modes-uv") ? TM_PRED : H_PRED;
 }
 
 int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
@@ -518,8 +523,10 @@
     for (b = 0; b < NUM_BANDS; ++b) {
       for (c = 0; c < NUM_CTX; ++c) {
         for (p = 0; p < NUM_PROBAS; ++p) {
-          const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ?
-                        VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p];
+          const int v =
+              VP8GetBit(br, CoeffsUpdateProba[t][b][c][p], "global-header") ?
+                        VP8GetValue(br, 8, "global-header") :
+                        CoeffsProba0[t][b][c][p];
           proba->bands_[t][b].probas_[c][p] = v;
         }
       }
@@ -528,9 +535,8 @@
       proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
     }
   }
-  dec->use_skip_proba_ = VP8Get(br);
+  dec->use_skip_proba_ = VP8Get(br, "global-header");
   if (dec->use_skip_proba_) {
-    dec->skip_p_ = VP8GetValue(br, 8);
+    dec->skip_p_ = VP8GetValue(br, 8, "global-header");
   }
 }
-
diff --git a/third_party/libwebp/src/dec/vp8_dec.c b/third_party/libwebp/src/dec/vp8_dec.c
index ea29a20..3f161da 100644
--- a/third_party/libwebp/src/dec/vp8_dec.c
+++ b/third_party/libwebp/src/dec/vp8_dec.c
@@ -166,23 +166,26 @@
                               VP8SegmentHeader* hdr, VP8Proba* proba) {
   assert(br != NULL);
   assert(hdr != NULL);
-  hdr->use_segment_ = VP8Get(br);
+  hdr->use_segment_ = VP8Get(br, "global-header");
   if (hdr->use_segment_) {
-    hdr->update_map_ = VP8Get(br);
-    if (VP8Get(br)) {   // update data
+    hdr->update_map_ = VP8Get(br, "global-header");
+    if (VP8Get(br, "global-header")) {   // update data
       int s;
-      hdr->absolute_delta_ = VP8Get(br);
+      hdr->absolute_delta_ = VP8Get(br, "global-header");
       for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
+        hdr->quantizer_[s] = VP8Get(br, "global-header") ?
+            VP8GetSignedValue(br, 7, "global-header") : 0;
       }
       for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
+        hdr->filter_strength_[s] = VP8Get(br, "global-header") ?
+            VP8GetSignedValue(br, 6, "global-header") : 0;
       }
     }
     if (hdr->update_map_) {
       int s;
       for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
-        proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
+        proba->segments_[s] = VP8Get(br, "global-header") ?
+            VP8GetValue(br, 8, "global-header") : 255u;
       }
     }
   } else {
@@ -210,7 +213,7 @@
   size_t last_part;
   size_t p;
 
-  dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1;
+  dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2, "global-header")) - 1;
   last_part = dec->num_parts_minus_one_;
   if (size < 3 * last_part) {
     // we can't even read the sizes with sz[]! That's a failure.
@@ -234,21 +237,21 @@
 // Paragraph 9.4
 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
   VP8FilterHeader* const hdr = &dec->filter_hdr_;
-  hdr->simple_    = VP8Get(br);
-  hdr->level_     = VP8GetValue(br, 6);
-  hdr->sharpness_ = VP8GetValue(br, 3);
-  hdr->use_lf_delta_ = VP8Get(br);
+  hdr->simple_    = VP8Get(br, "global-header");
+  hdr->level_     = VP8GetValue(br, 6, "global-header");
+  hdr->sharpness_ = VP8GetValue(br, 3, "global-header");
+  hdr->use_lf_delta_ = VP8Get(br, "global-header");
   if (hdr->use_lf_delta_) {
-    if (VP8Get(br)) {   // update lf-delta?
+    if (VP8Get(br, "global-header")) {   // update lf-delta?
       int i;
       for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
-        if (VP8Get(br)) {
-          hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
+        if (VP8Get(br, "global-header")) {
+          hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
         }
       }
       for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
-        if (VP8Get(br)) {
-          hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
+        if (VP8Get(br, "global-header")) {
+          hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
         }
       }
     }
@@ -337,7 +340,7 @@
     io->scaled_width = io->width;
     io->scaled_height = io->height;
 
-    io->mb_w = io->width;   // sanity check
+    io->mb_w = io->width;   // for soundness
     io->mb_h = io->height;  // ditto
 
     VP8ResetProba(&dec->proba_);
@@ -357,8 +360,8 @@
   buf_size -= frm_hdr->partition_length_;
 
   if (frm_hdr->key_frame_) {
-    pic_hdr->colorspace_ = VP8Get(br);
-    pic_hdr->clamp_type_ = VP8Get(br);
+    pic_hdr->colorspace_ = VP8Get(br, "global-header");
+    pic_hdr->clamp_type_ = VP8Get(br, "global-header");
   }
   if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
     return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
@@ -383,7 +386,7 @@
                        "Not a key frame.");
   }
 
-  VP8Get(br);   // ignore the value of update_proba_
+  VP8Get(br, "global-header");   // ignore the value of update_proba_
 
   VP8ParseProba(br, dec);
 
@@ -405,31 +408,31 @@
   0, 1, 4, 8,  5, 2, 3, 6,  9, 12, 13, 10,  7, 11, 14, 15
 };
 
-// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
+// See section 13-2: https://datatracker.ietf.org/doc/html/rfc6386#section-13.2
 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
   int v;
-  if (!VP8GetBit(br, p[3])) {
-    if (!VP8GetBit(br, p[4])) {
+  if (!VP8GetBit(br, p[3], "coeffs")) {
+    if (!VP8GetBit(br, p[4], "coeffs")) {
       v = 2;
     } else {
-      v = 3 + VP8GetBit(br, p[5]);
+      v = 3 + VP8GetBit(br, p[5], "coeffs");
     }
   } else {
-    if (!VP8GetBit(br, p[6])) {
-      if (!VP8GetBit(br, p[7])) {
-        v = 5 + VP8GetBit(br, 159);
+    if (!VP8GetBit(br, p[6], "coeffs")) {
+      if (!VP8GetBit(br, p[7], "coeffs")) {
+        v = 5 + VP8GetBit(br, 159, "coeffs");
       } else {
-        v = 7 + 2 * VP8GetBit(br, 165);
-        v += VP8GetBit(br, 145);
+        v = 7 + 2 * VP8GetBit(br, 165, "coeffs");
+        v += VP8GetBit(br, 145, "coeffs");
       }
     } else {
       const uint8_t* tab;
-      const int bit1 = VP8GetBit(br, p[8]);
-      const int bit0 = VP8GetBit(br, p[9 + bit1]);
+      const int bit1 = VP8GetBit(br, p[8], "coeffs");
+      const int bit0 = VP8GetBit(br, p[9 + bit1], "coeffs");
       const int cat = 2 * bit1 + bit0;
       v = 0;
       for (tab = kCat3456[cat]; *tab; ++tab) {
-        v += v + VP8GetBit(br, *tab);
+        v += v + VP8GetBit(br, *tab, "coeffs");
       }
       v += 3 + (8 << cat);
     }
@@ -443,24 +446,24 @@
                          int ctx, const quant_t dq, int n, int16_t* out) {
   const uint8_t* p = prob[n]->probas_[ctx];
   for (; n < 16; ++n) {
-    if (!VP8GetBit(br, p[0])) {
+    if (!VP8GetBit(br, p[0], "coeffs")) {
       return n;  // previous coeff was last non-zero coeff
     }
-    while (!VP8GetBit(br, p[1])) {       // sequence of zero coeffs
+    while (!VP8GetBit(br, p[1], "coeffs")) {       // sequence of zero coeffs
       p = prob[++n]->probas_[0];
       if (n == 16) return 16;
     }
     {        // non zero coeff
       const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
       int v;
-      if (!VP8GetBit(br, p[2])) {
+      if (!VP8GetBit(br, p[2], "coeffs")) {
         v = 1;
         p = p_ctx[1];
       } else {
         v = GetLargeValue(br, p);
         p = p_ctx[2];
       }
-      out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
+      out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
     }
   }
   return 16;
@@ -473,36 +476,36 @@
                         int ctx, const quant_t dq, int n, int16_t* out) {
   const uint8_t* p = prob[n]->probas_[ctx];
   for (; n < 16; ++n) {
-    if (!VP8GetBitAlt(br, p[0])) {
+    if (!VP8GetBitAlt(br, p[0], "coeffs")) {
       return n;  // previous coeff was last non-zero coeff
     }
-    while (!VP8GetBitAlt(br, p[1])) {       // sequence of zero coeffs
+    while (!VP8GetBitAlt(br, p[1], "coeffs")) {       // sequence of zero coeffs
       p = prob[++n]->probas_[0];
       if (n == 16) return 16;
     }
     {        // non zero coeff
       const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
       int v;
-      if (!VP8GetBitAlt(br, p[2])) {
+      if (!VP8GetBitAlt(br, p[2], "coeffs")) {
         v = 1;
         p = p_ctx[1];
       } else {
         v = GetLargeValue(br, p);
         p = p_ctx[2];
       }
-      out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
+      out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
     }
   }
   return 16;
 }
 
-static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
-  if (GetCoeffs == NULL) {
-    if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
-      GetCoeffs = GetCoeffsAlt;
-    } else {
-      GetCoeffs = GetCoeffsFast;
-    }
+extern VP8CPUInfo VP8GetCPUInfo;
+
+WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
+  if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
+    GetCoeffs = GetCoeffsAlt;
+  } else {
+    GetCoeffs = GetCoeffsFast;
   }
 }
 
diff --git a/third_party/libwebp/src/dec/vp8_dec.h b/third_party/libwebp/src/dec/vp8_dec.h
index ca85b34..a05405d 100644
--- a/third_party/libwebp/src/dec/vp8_dec.h
+++ b/third_party/libwebp/src/dec/vp8_dec.h
@@ -182,4 +182,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DEC_VP8_DEC_H_ */
+#endif  // WEBP_DEC_VP8_DEC_H_
diff --git a/third_party/libwebp/src/dec/vp8i_dec.h b/third_party/libwebp/src/dec/vp8i_dec.h
index 33b0dbd..279483b 100644
--- a/third_party/libwebp/src/dec/vp8i_dec.h
+++ b/third_party/libwebp/src/dec/vp8i_dec.h
@@ -34,8 +34,8 @@
 
 // version numbers
 #define DEC_MAJ_VERSION 1
-#define DEC_MIN_VERSION 0
-#define DEC_REV_VERSION 0
+#define DEC_MIN_VERSION 3
+#define DEC_REV_VERSION 1
 
 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
 // Constraints are: We need to store one 16x16 block of luma samples (y),
@@ -319,4 +319,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DEC_VP8I_DEC_H_ */
+#endif  // WEBP_DEC_VP8I_DEC_H_
diff --git a/third_party/libwebp/src/dec/vp8l_dec.c b/third_party/libwebp/src/dec/vp8l_dec.c
index fba6649..f1e7a11 100644
--- a/third_party/libwebp/src/dec/vp8l_dec.c
+++ b/third_party/libwebp/src/dec/vp8l_dec.c
@@ -88,7 +88,7 @@
 // to 256 (green component values) + 24 (length prefix values)
 // + color_cache_size (between 0 and 2048).
 // All values computed for 8-bit first level lookup with Mark Adler's tool:
-// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
+// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
 #define FIXED_TABLE_SIZE (630 * 3 + 410)
 static const uint16_t kTableSize[12] = {
   FIXED_TABLE_SIZE + 654,
@@ -182,7 +182,7 @@
 
 //------------------------------------------------------------------------------
 // Decodes the next Huffman code from bit-stream.
-// FillBitWindow(br) needs to be called at minimum every second call
+// VP8LFillBitWindow(br) needs to be called at minimum every second call
 // to ReadSymbol, in order to pre-fetch enough bits.
 static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
                                   VP8LBitReader* const br) {
@@ -325,7 +325,7 @@
     // The first code is either 1 bit or 8 bit code.
     int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
     code_lengths[symbol] = 1;
-    // The second code (if present), is always 8 bit long.
+    // The second code (if present), is always 8 bits long.
     if (num_symbols == 2) {
       symbol = VP8LReadBits(br, 8);
       code_lengths[symbol] = 1;
@@ -367,11 +367,14 @@
   uint32_t* huffman_image = NULL;
   HTreeGroup* htree_groups = NULL;
   HuffmanCode* huffman_tables = NULL;
-  HuffmanCode* next = NULL;
+  HuffmanCode* huffman_table = NULL;
   int num_htree_groups = 1;
+  int num_htree_groups_max = 1;
   int max_alphabet_size = 0;
   int* code_lengths = NULL;
   const int table_size = kTableSize[color_cache_bits];
+  int* mapping = NULL;
+  int ok = 0;
 
   if (allow_recursion && VP8LReadBits(br, 1)) {
     // use meta Huffman codes.
@@ -388,10 +391,36 @@
       // The huffman data is stored in red and green bytes.
       const int group = (huffman_image[i] >> 8) & 0xffff;
       huffman_image[i] = group;
-      if (group >= num_htree_groups) {
-        num_htree_groups = group + 1;
+      if (group >= num_htree_groups_max) {
+        num_htree_groups_max = group + 1;
       }
     }
+    // Check the validity of num_htree_groups_max. If it seems too big, use a
+    // smaller value for later. This will prevent big memory allocations to end
+    // up with a bad bitstream anyway.
+    // The value of 1000 is totally arbitrary. We know that num_htree_groups_max
+    // is smaller than (1 << 16) and should be smaller than the number of pixels
+    // (though the format allows it to be bigger).
+    if (num_htree_groups_max > 1000 || num_htree_groups_max > xsize * ysize) {
+      // Create a mapping from the used indices to the minimal set of used
+      // values [0, num_htree_groups)
+      mapping = (int*)WebPSafeMalloc(num_htree_groups_max, sizeof(*mapping));
+      if (mapping == NULL) {
+        dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+        goto Error;
+      }
+      // -1 means a value is unmapped, and therefore unused in the Huffman
+      // image.
+      memset(mapping, 0xff, num_htree_groups_max * sizeof(*mapping));
+      for (num_htree_groups = 0, i = 0; i < huffman_pixs; ++i) {
+        // Get the current mapping for the group and remap the Huffman image.
+        int* const mapped_group = &mapping[huffman_image[i]];
+        if (*mapped_group == -1) *mapped_group = num_htree_groups++;
+        huffman_image[i] = *mapped_group;
+      }
+    } else {
+      num_htree_groups = num_htree_groups_max;
+    }
   }
 
   if (br->eos_) goto Error;
@@ -407,83 +436,100 @@
     }
   }
 
+  code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
+                                      sizeof(*code_lengths));
   huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
                                                 sizeof(*huffman_tables));
   htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
-  code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
-                                      sizeof(*code_lengths));
 
   if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
     goto Error;
   }
 
-  next = huffman_tables;
-  for (i = 0; i < num_htree_groups; ++i) {
-    HTreeGroup* const htree_group = &htree_groups[i];
-    HuffmanCode** const htrees = htree_group->htrees;
-    int size;
-    int total_size = 0;
-    int is_trivial_literal = 1;
-    int max_bits = 0;
-    for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
-      int alphabet_size = kAlphabetSize[j];
-      htrees[j] = next;
-      if (j == 0 && color_cache_bits > 0) {
-        alphabet_size += 1 << color_cache_bits;
-      }
-      size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next);
-      if (size == 0) {
-        goto Error;
-      }
-      if (is_trivial_literal && kLiteralMap[j] == 1) {
-        is_trivial_literal = (next->bits == 0);
-      }
-      total_size += next->bits;
-      next += size;
-      if (j <= ALPHA) {
-        int local_max_bits = code_lengths[0];
-        int k;
-        for (k = 1; k < alphabet_size; ++k) {
-          if (code_lengths[k] > local_max_bits) {
-            local_max_bits = code_lengths[k];
-          }
+  huffman_table = huffman_tables;
+  for (i = 0; i < num_htree_groups_max; ++i) {
+    // If the index "i" is unused in the Huffman image, just make sure the
+    // coefficients are valid but do not store them.
+    if (mapping != NULL && mapping[i] == -1) {
+      for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+        int alphabet_size = kAlphabetSize[j];
+        if (j == 0 && color_cache_bits > 0) {
+          alphabet_size += (1 << color_cache_bits);
         }
-        max_bits += local_max_bits;
+        // Passing in NULL so that nothing gets filled.
+        if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) {
+          goto Error;
+        }
       }
-    }
-    htree_group->is_trivial_literal = is_trivial_literal;
-    htree_group->is_trivial_code = 0;
-    if (is_trivial_literal) {
-      const int red = htrees[RED][0].value;
-      const int blue = htrees[BLUE][0].value;
-      const int alpha = htrees[ALPHA][0].value;
-      htree_group->literal_arb =
-          ((uint32_t)alpha << 24) | (red << 16) | blue;
-      if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
-        htree_group->is_trivial_code = 1;
-        htree_group->literal_arb |= htrees[GREEN][0].value << 8;
+    } else {
+      HTreeGroup* const htree_group =
+          &htree_groups[(mapping == NULL) ? i : mapping[i]];
+      HuffmanCode** const htrees = htree_group->htrees;
+      int size;
+      int total_size = 0;
+      int is_trivial_literal = 1;
+      int max_bits = 0;
+      for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+        int alphabet_size = kAlphabetSize[j];
+        htrees[j] = huffman_table;
+        if (j == 0 && color_cache_bits > 0) {
+          alphabet_size += (1 << color_cache_bits);
+        }
+        size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
+        if (size == 0) {
+          goto Error;
+        }
+        if (is_trivial_literal && kLiteralMap[j] == 1) {
+          is_trivial_literal = (huffman_table->bits == 0);
+        }
+        total_size += huffman_table->bits;
+        huffman_table += size;
+        if (j <= ALPHA) {
+          int local_max_bits = code_lengths[0];
+          int k;
+          for (k = 1; k < alphabet_size; ++k) {
+            if (code_lengths[k] > local_max_bits) {
+              local_max_bits = code_lengths[k];
+            }
+          }
+          max_bits += local_max_bits;
+        }
       }
+      htree_group->is_trivial_literal = is_trivial_literal;
+      htree_group->is_trivial_code = 0;
+      if (is_trivial_literal) {
+        const int red = htrees[RED][0].value;
+        const int blue = htrees[BLUE][0].value;
+        const int alpha = htrees[ALPHA][0].value;
+        htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
+        if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
+          htree_group->is_trivial_code = 1;
+          htree_group->literal_arb |= htrees[GREEN][0].value << 8;
+        }
+      }
+      htree_group->use_packed_table =
+          !htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
+      if (htree_group->use_packed_table) BuildPackedTable(htree_group);
     }
-    htree_group->use_packed_table = !htree_group->is_trivial_code &&
-                                    (max_bits < HUFFMAN_PACKED_BITS);
-    if (htree_group->use_packed_table) BuildPackedTable(htree_group);
   }
-  WebPSafeFree(code_lengths);
+  ok = 1;
 
-  // All OK. Finalize pointers and return.
+  // All OK. Finalize pointers.
   hdr->huffman_image_ = huffman_image;
   hdr->num_htree_groups_ = num_htree_groups;
   hdr->htree_groups_ = htree_groups;
   hdr->huffman_tables_ = huffman_tables;
-  return 1;
 
  Error:
   WebPSafeFree(code_lengths);
-  WebPSafeFree(huffman_image);
-  WebPSafeFree(huffman_tables);
-  VP8LHtreeGroupsFree(htree_groups);
-  return 0;
+  WebPSafeFree(mapping);
+  if (!ok) {
+    WebPSafeFree(huffman_image);
+    WebPSafeFree(huffman_tables);
+    VP8LHtreeGroupsFree(htree_groups);
+  }
+  return ok;
 }
 
 //------------------------------------------------------------------------------
@@ -517,8 +563,11 @@
   memory += work_size * sizeof(*work);
   scaled_data = (uint32_t*)memory;
 
-  WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
-                   out_width, out_height, 0, num_channels, work);
+  if (!WebPRescalerInit(dec->rescaler, in_width, in_height,
+                        (uint8_t*)scaled_data, out_width, out_height,
+                        0, num_channels, work)) {
+    return 0;
+  }
   return 1;
 }
 #endif   // WEBP_REDUCE_SIZE
@@ -532,13 +581,14 @@
 static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
                   int rgba_stride, uint8_t* const rgba) {
   uint32_t* const src = (uint32_t*)rescaler->dst;
+  uint8_t* dst = rgba;
   const int dst_width = rescaler->dst_width;
   int num_lines_out = 0;
   while (WebPRescalerHasPendingOutput(rescaler)) {
-    uint8_t* const dst = rgba + num_lines_out * rgba_stride;
     WebPRescalerExportRow(rescaler);
     WebPMultARGBRow(src, dst_width, 1);
     VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
+    dst += rgba_stride;
     ++num_lines_out;
   }
   return num_lines_out;
@@ -552,8 +602,8 @@
   int num_lines_in = 0;
   int num_lines_out = 0;
   while (num_lines_in < mb_h) {
-    uint8_t* const row_in = in + num_lines_in * in_stride;
-    uint8_t* const row_out = out + num_lines_out * out_stride;
+    uint8_t* const row_in = in + (uint64_t)num_lines_in * in_stride;
+    uint8_t* const row_out = out + (uint64_t)num_lines_out * out_stride;
     const int lines_left = mb_h - num_lines_in;
     const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
     int lines_imported;
@@ -712,11 +762,11 @@
 
 typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
 
-static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
+static void ApplyInverseTransforms(VP8LDecoder* const dec,
+                                   int start_row, int num_rows,
                                    const uint32_t* const rows) {
   int n = dec->next_transform_;
   const int cache_pixs = dec->width_ * num_rows;
-  const int start_row = dec->last_row_;
   const int end_row = start_row + num_rows;
   const uint32_t* rows_in = rows;
   uint32_t* const rows_out = dec->argb_cache_;
@@ -747,15 +797,15 @@
     VP8Io* const io = dec->io_;
     uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
     const int in_stride = io->width * sizeof(uint32_t);  // in unit of RGBA
-
-    ApplyInverseTransforms(dec, num_rows, rows);
+    ApplyInverseTransforms(dec, dec->last_row_, num_rows, rows);
     if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) {
       // Nothing to output (this time).
     } else {
       const WebPDecBuffer* const output = dec->output_;
       if (WebPIsRGBMode(output->colorspace)) {  // convert to RGBA
         const WebPRGBABuffer* const buf = &output->u.RGBA;
-        uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
+        uint8_t* const rgba =
+            buf->rgba + (int64_t)dec->last_out_row_ * buf->stride;
         const int num_rows_out =
 #if !defined(WEBP_REDUCE_SIZE)
          io->use_scaling ?
@@ -888,7 +938,11 @@
 #endif
         break;
       case 2:
+#if !defined(WORDS_BIGENDIAN)
         memcpy(&pattern, src, sizeof(uint16_t));
+#else
+        pattern = ((uint32_t)src[0] << 8) | src[1];
+#endif
 #if defined(__arm__) || defined(_M_ARM)
         pattern |= pattern << 16;
 #elif defined(WEBP_USE_MIPS_DSP_R2)
@@ -902,7 +956,6 @@
         break;
       default:
         goto Copy;
-        break;
     }
     CopySmallPattern8b(src, dst, length, pattern);
     return;
@@ -1147,6 +1200,7 @@
       VP8LFillBitWindow(br);
       dist_code = GetCopyDistance(dist_symbol, br);
       dist = PlaneCodeToDistance(width, dist_code);
+
       if (VP8LIsEndOfStream(br)) break;
       if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
         goto Error;
@@ -1231,7 +1285,7 @@
     uint8_t* const new_data = (uint8_t*)new_color_map;
     new_color_map[0] = transform->data_[0];
     for (i = 4; i < 4 * num_colors; ++i) {
-      // Equivalent to AddPixelEq(), on a byte-basis.
+      // Equivalent to VP8LAddPixels(), on a byte-basis.
       new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
     }
     for (; i < 4 * final_num_colors; ++i) {
@@ -1286,7 +1340,7 @@
        ok = ok && ExpandColorMap(num_colors, transform);
       break;
     }
-    case SUBTRACT_GREEN:
+    case SUBTRACT_GREEN_TRANSFORM:
       break;
     default:
       assert(0);    // can't happen
@@ -1469,7 +1523,7 @@
   assert(dec->width_ <= final_width);
   dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
   if (dec->pixels_ == NULL) {
-    dec->argb_cache_ = NULL;    // for sanity check
+    dec->argb_cache_ = NULL;    // for soundness
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
     return 0;
   }
@@ -1479,7 +1533,7 @@
 
 static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
   const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
-  dec->argb_cache_ = NULL;    // for sanity check
+  dec->argb_cache_ = NULL;    // for soundness
   dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
   if (dec->pixels_ == NULL) {
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
@@ -1507,7 +1561,7 @@
     const int cache_pixs = width * num_rows_to_process;
     uint8_t* const dst = output + width * cur_row;
     const uint32_t* const src = dec->argb_cache_;
-    ApplyInverseTransforms(dec, num_rows_to_process, in);
+    ApplyInverseTransforms(dec, cur_row, num_rows_to_process, in);
     WebPExtractGreen(src, dst, cache_pixs);
     AlphaApplyFilter(alph_dec,
                      cur_row, cur_row + num_rows_to_process, dst, width);
@@ -1527,7 +1581,6 @@
   if (dec == NULL) return 0;
 
   assert(alph_dec != NULL);
-  alph_dec->vp8l_dec_ = dec;
 
   dec->width_ = alph_dec->width_;
   dec->height_ = alph_dec->height_;
@@ -1559,11 +1612,12 @@
 
   if (!ok) goto Err;
 
+  // Only set here, once we are sure it is valid (to avoid thread races).
+  alph_dec->vp8l_dec_ = dec;
   return 1;
 
  Err:
-  VP8LDelete(alph_dec->vp8l_dec_);
-  alph_dec->vp8l_dec_ = NULL;
+  VP8LDelete(dec);
   return 0;
 }
 
@@ -1621,7 +1675,6 @@
   VP8Io* io = NULL;
   WebPDecParams* params = NULL;
 
-  // Sanity checks.
   if (dec == NULL) return 0;
 
   assert(dec->hdr_.huffman_tables_ != NULL);
diff --git a/third_party/libwebp/src/dec/vp8li_dec.h b/third_party/libwebp/src/dec/vp8li_dec.h
index cea22f7..6eb4d4b 100644
--- a/third_party/libwebp/src/dec/vp8li_dec.h
+++ b/third_party/libwebp/src/dec/vp8li_dec.h
@@ -39,7 +39,7 @@
   int                    bits_;   // subsampling bits defining transform window.
   int                    xsize_;  // transform window X index.
   int                    ysize_;  // transform window Y index.
-  uint32_t              *data_;   // transform data.
+  uint32_t*              data_;   // transform data.
 };
 
 typedef struct {
@@ -50,23 +50,23 @@
   int             huffman_mask_;
   int             huffman_subsample_bits_;
   int             huffman_xsize_;
-  uint32_t       *huffman_image_;
+  uint32_t*       huffman_image_;
   int             num_htree_groups_;
-  HTreeGroup     *htree_groups_;
-  HuffmanCode    *huffman_tables_;
+  HTreeGroup*     htree_groups_;
+  HuffmanCode*    huffman_tables_;
 } VP8LMetadata;
 
 typedef struct VP8LDecoder VP8LDecoder;
 struct VP8LDecoder {
   VP8StatusCode    status_;
   VP8LDecodeState  state_;
-  VP8Io           *io_;
+  VP8Io*           io_;
 
-  const WebPDecBuffer *output_;    // shortcut to io->opaque->output
+  const WebPDecBuffer* output_;    // shortcut to io->opaque->output
 
-  uint32_t        *pixels_;        // Internal data: either uint8_t* for alpha
+  uint32_t*        pixels_;        // Internal data: either uint8_t* for alpha
                                    // or uint32_t* for BGRA.
-  uint32_t        *argb_cache_;    // Scratch buffer for temporary BGRA storage.
+  uint32_t*        argb_cache_;    // Scratch buffer for temporary BGRA storage.
 
   VP8LBitReader    br_;
   int              incremental_;   // if true, incremental decoding is expected
@@ -88,8 +88,8 @@
   // or'd bitset storing the transforms types.
   uint32_t         transforms_seen_;
 
-  uint8_t         *rescaler_memory;  // Working memory for rescaling work.
-  WebPRescaler    *rescaler;         // Common rescaler for all channels.
+  uint8_t*         rescaler_memory;  // Working memory for rescaling work.
+  WebPRescaler*    rescaler;         // Common rescaler for all channels.
 };
 
 //------------------------------------------------------------------------------
@@ -134,4 +134,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DEC_VP8LI_DEC_H_ */
+#endif  // WEBP_DEC_VP8LI_DEC_H_
diff --git a/third_party/libwebp/src/dec/webp_dec.c b/third_party/libwebp/src/dec/webp_dec.c
index 81a13ac..3fc87de 100644
--- a/third_party/libwebp/src/dec/webp_dec.c
+++ b/third_party/libwebp/src/dec/webp_dec.c
@@ -184,7 +184,7 @@
       return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
     }
     // For odd-sized chunk-payload, there's one byte padding at the end.
-    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u;
     total_size += disk_chunk_size;
 
     // Check that total bytes skipped so far does not exceed riff_size.
@@ -663,19 +663,26 @@
 uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
                        int* width, int* height, uint8_t** u, uint8_t** v,
                        int* stride, int* uv_stride) {
-  WebPDecBuffer output;   // only to preserve the side-infos
-  uint8_t* const out = Decode(MODE_YUV, data, data_size,
-                              width, height, &output);
-
-  if (out != NULL) {
-    const WebPYUVABuffer* const buf = &output.u.YUVA;
-    *u = buf->u;
-    *v = buf->v;
-    *stride = buf->y_stride;
-    *uv_stride = buf->u_stride;
-    assert(buf->u_stride == buf->v_stride);
+  // data, width and height are checked by Decode().
+  if (u == NULL || v == NULL || stride == NULL || uv_stride == NULL) {
+    return NULL;
   }
-  return out;
+
+  {
+    WebPDecBuffer output;   // only to preserve the side-infos
+    uint8_t* const out = Decode(MODE_YUV, data, data_size,
+                                width, height, &output);
+
+    if (out != NULL) {
+      const WebPYUVABuffer* const buf = &output.u.YUVA;
+      *u = buf->u;
+      *v = buf->v;
+      *stride = buf->y_stride;
+      *uv_stride = buf->u_stride;
+      assert(buf->u_stride == buf->v_stride);
+    }
+    return out;
+  }
 }
 
 static void DefaultFeatures(WebPBitstreamFeatures* const features) {
@@ -790,6 +797,13 @@
 //------------------------------------------------------------------------------
 // Cropping and rescaling.
 
+int WebPCheckCropDimensions(int image_width, int image_height,
+                            int x, int y, int w, int h) {
+  return !(x < 0 || y < 0 || w <= 0 || h <= 0 ||
+           x >= image_width || w > image_width || w > image_width - x ||
+           y >= image_height || h > image_height || h > image_height - y);
+}
+
 int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
                           VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
   const int W = io->width;
@@ -797,7 +811,7 @@
   int x = 0, y = 0, w = W, h = H;
 
   // Cropping
-  io->use_cropping = (options != NULL) && (options->use_cropping > 0);
+  io->use_cropping = (options != NULL) && options->use_cropping;
   if (io->use_cropping) {
     w = options->crop_width;
     h = options->crop_height;
@@ -807,7 +821,7 @@
       x &= ~1;
       y &= ~1;
     }
-    if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
+    if (!WebPCheckCropDimensions(W, H, x, y, w, h)) {
       return 0;  // out of frame boundary error
     }
   }
@@ -819,7 +833,7 @@
   io->mb_h = h;
 
   // Scaling
-  io->use_scaling = (options != NULL) && (options->use_scaling > 0);
+  io->use_scaling = (options != NULL) && options->use_scaling;
   if (io->use_scaling) {
     int scaled_width = options->scaled_width;
     int scaled_height = options->scaled_height;
@@ -840,8 +854,8 @@
 
   if (io->use_scaling) {
     // disable filter (only for large downscaling ratio).
-    io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
-                           (io->scaled_height < H * 3 / 4);
+    io->bypass_filtering |= (io->scaled_width < W * 3 / 4) &&
+                            (io->scaled_height < H * 3 / 4);
     io->fancy_upsampling = 0;
   }
   return 1;
diff --git a/third_party/libwebp/src/dec/webpi_dec.h b/third_party/libwebp/src/dec/webpi_dec.h
index c378ba6..3b97388 100644
--- a/third_party/libwebp/src/dec/webpi_dec.h
+++ b/third_party/libwebp/src/dec/webpi_dec.h
@@ -77,6 +77,10 @@
 //------------------------------------------------------------------------------
 // Misc utils
 
+// Returns true if crop dimensions are within image bounds.
+int WebPCheckCropDimensions(int image_width, int image_height,
+                            int x, int y, int w, int h);
+
 // Initializes VP8Io with custom setup, io and teardown functions. The default
 // hooks will use the supplied 'params' as io->opaque handle.
 void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
@@ -130,4 +134,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DEC_WEBPI_DEC_H_ */
+#endif  // WEBP_DEC_WEBPI_DEC_H_
diff --git a/third_party/libwebp/src/demux/Makefile.am b/third_party/libwebp/src/demux/Makefile.am
index 7e80bdc..42de71d 100644
--- a/third_party/libwebp/src/demux/Makefile.am
+++ b/third_party/libwebp/src/demux/Makefile.am
@@ -13,6 +13,6 @@
 noinst_HEADERS += ../webp/format_constants.h
 
 libwebpdemux_la_LIBADD = ../libwebp.la
-libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:4:0
+libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:13:0
 libwebpdemuxincludedir = $(includedir)/webp
 pkgconfig_DATA = libwebpdemux.pc
diff --git a/third_party/libwebp/src/demux/anim_decode.c b/third_party/libwebp/src/demux/anim_decode.c
index 6de3121..fdf4a63 100644
--- a/third_party/libwebp/src/demux/anim_decode.c
+++ b/third_party/libwebp/src/demux/anim_decode.c
@@ -28,6 +28,14 @@
 
 #define NUM_CHANNELS 4
 
+// Channel extraction from a uint32_t representation of a uint8_t RGBA/BGRA
+// buffer.
+#ifdef WORDS_BIGENDIAN
+#define CHANNEL_SHIFT(i) (24 - (i) * 8)
+#else
+#define CHANNEL_SHIFT(i) ((i) * 8)
+#endif
+
 typedef void (*BlendRowFunc)(uint32_t* const, const uint32_t* const, int);
 static void BlendPixelRowNonPremult(uint32_t* const src,
                                     const uint32_t* const dst, int num_pixels);
@@ -92,11 +100,19 @@
     int abi_version) {
   WebPAnimDecoderOptions options;
   WebPAnimDecoder* dec = NULL;
+  WebPBitstreamFeatures features;
   if (webp_data == NULL ||
       WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_DEMUX_ABI_VERSION)) {
     return NULL;
   }
 
+  // Validate the bitstream before doing expensive allocations. The demuxer may
+  // be more tolerant than the decoder.
+  if (WebPGetFeatures(webp_data->bytes, webp_data->size, &features) !=
+      VP8_STATUS_OK) {
+    return NULL;
+  }
+
   // Note: calloc() so that the pointer members are initialized to NULL.
   dec = (WebPAnimDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
   if (dec == NULL) goto Error;
@@ -150,7 +166,7 @@
                           uint32_t canvas_height) {
   const uint64_t size =
       (uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
-  if (size != (size_t)size) return 0;
+  if (!CheckSizeOverflow(size)) return 0;
   memset(buf, 0, (size_t)size);
   return 1;
 }
@@ -171,7 +187,7 @@
 static int CopyCanvas(const uint8_t* src, uint8_t* dst,
                       uint32_t width, uint32_t height) {
   const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
-  if (size != (size_t)size) return 0;
+  if (!CheckSizeOverflow(size)) return 0;
   assert(src != NULL && dst != NULL);
   memcpy(dst, src, (size_t)size);
   return 1;
@@ -206,35 +222,35 @@
   const uint8_t dst_channel = (dst >> shift) & 0xff;
   const uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
   assert(blend_unscaled < (1ULL << 32) / scale);
-  return (blend_unscaled * scale) >> 24;
+  return (blend_unscaled * scale) >> CHANNEL_SHIFT(3);
 }
 
 // Blend 'src' over 'dst' assuming they are NOT pre-multiplied by alpha.
 static uint32_t BlendPixelNonPremult(uint32_t src, uint32_t dst) {
-  const uint8_t src_a = (src >> 24) & 0xff;
+  const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
 
   if (src_a == 0) {
     return dst;
   } else {
-    const uint8_t dst_a = (dst >> 24) & 0xff;
+    const uint8_t dst_a = (dst >> CHANNEL_SHIFT(3)) & 0xff;
     // This is the approximate integer arithmetic for the actual formula:
     // dst_factor_a = (dst_a * (255 - src_a)) / 255.
     const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
     const uint8_t blend_a = src_a + dst_factor_a;
     const uint32_t scale = (1UL << 24) / blend_a;
 
-    const uint8_t blend_r =
-        BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 0);
-    const uint8_t blend_g =
-        BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 8);
-    const uint8_t blend_b =
-        BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 16);
+    const uint8_t blend_r = BlendChannelNonPremult(
+        src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(0));
+    const uint8_t blend_g = BlendChannelNonPremult(
+        src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(1));
+    const uint8_t blend_b = BlendChannelNonPremult(
+        src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(2));
     assert(src_a + dst_factor_a < 256);
 
-    return (blend_r << 0) |
-           (blend_g << 8) |
-           (blend_b << 16) |
-           ((uint32_t)blend_a << 24);
+    return ((uint32_t)blend_r << CHANNEL_SHIFT(0)) |
+           ((uint32_t)blend_g << CHANNEL_SHIFT(1)) |
+           ((uint32_t)blend_b << CHANNEL_SHIFT(2)) |
+           ((uint32_t)blend_a << CHANNEL_SHIFT(3));
   }
 }
 
@@ -244,7 +260,7 @@
                                     const uint32_t* const dst, int num_pixels) {
   int i;
   for (i = 0; i < num_pixels; ++i) {
-    const uint8_t src_alpha = (src[i] >> 24) & 0xff;
+    const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
     if (src_alpha != 0xff) {
       src[i] = BlendPixelNonPremult(src[i], dst[i]);
     }
@@ -261,7 +277,7 @@
 
 // Blend 'src' over 'dst' assuming they are pre-multiplied by alpha.
 static uint32_t BlendPixelPremult(uint32_t src, uint32_t dst) {
-  const uint8_t src_a = (src >> 24) & 0xff;
+  const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
   return src + ChannelwiseMultiply(dst, 256 - src_a);
 }
 
@@ -271,7 +287,7 @@
                                  int num_pixels) {
   int i;
   for (i = 0; i < num_pixels; ++i) {
-    const uint8_t src_alpha = (src[i] >> 24) & 0xff;
+    const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
     if (src_alpha != 0xff) {
       src[i] = BlendPixelPremult(src[i], dst[i]);
     }
@@ -351,12 +367,15 @@
   {
     const uint8_t* in = iter.fragment.bytes;
     const size_t in_size = iter.fragment.size;
-    const size_t out_offset =
-        (iter.y_offset * width + iter.x_offset) * NUM_CHANNELS;
+    const uint32_t stride = width * NUM_CHANNELS;  // at most 25 + 2 bits
+    const uint64_t out_offset = (uint64_t)iter.y_offset * stride +
+                                (uint64_t)iter.x_offset * NUM_CHANNELS;  // 53b
+    const uint64_t size = (uint64_t)iter.height * stride;  // at most 25 + 27b
     WebPDecoderConfig* const config = &dec->config_;
     WebPRGBABuffer* const buf = &config->output.u.RGBA;
-    buf->stride = NUM_CHANNELS * width;
-    buf->size = buf->stride * iter.height;
+    if ((size_t)size != size) goto Error;
+    buf->stride = (int)stride;
+    buf->size = (size_t)size;
     buf->rgba = dec->curr_frame_ + out_offset;
 
     if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {
diff --git a/third_party/libwebp/src/demux/demux.c b/third_party/libwebp/src/demux/demux.c
index 684215e..fd45a25 100644
--- a/third_party/libwebp/src/demux/demux.c
+++ b/third_party/libwebp/src/demux/demux.c
@@ -24,8 +24,8 @@
 #include "src/webp/format_constants.h"
 
 #define DMUX_MAJ_VERSION 1
-#define DMUX_MIN_VERSION 0
-#define DMUX_REV_VERSION 0
+#define DMUX_MIN_VERSION 3
+#define DMUX_REV_VERSION 1
 
 typedef struct {
   size_t start_;        // start location of the data
@@ -221,12 +221,16 @@
     const size_t chunk_start_offset = mem->start_;
     const uint32_t fourcc = ReadLE32(mem);
     const uint32_t payload_size = ReadLE32(mem);
-    const uint32_t payload_size_padded = payload_size + (payload_size & 1);
-    const size_t payload_available = (payload_size_padded > MemDataSize(mem))
-                                   ? MemDataSize(mem) : payload_size_padded;
-    const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
+    uint32_t payload_size_padded;
+    size_t payload_available;
+    size_t chunk_size;
 
     if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+
+    payload_size_padded = payload_size + (payload_size & 1);
+    payload_available = (payload_size_padded > MemDataSize(mem))
+                      ? MemDataSize(mem) : payload_size_padded;
+    chunk_size = CHUNK_HEADER_SIZE + payload_available;
     if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
     if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
 
@@ -312,6 +316,7 @@
   int bits;
   MemBuffer* const mem = &dmux->mem_;
   Frame* frame;
+  size_t start_offset;
   ParseStatus status =
       NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
   if (status != PARSE_OK) return status;
@@ -332,7 +337,11 @@
 
   // Store a frame only if the animation flag is set there is some data for
   // this frame is available.
+  start_offset = mem->start_;
   status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
+  if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) {
+    status = PARSE_ERROR;
+  }
   if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
     added_frame = AddFrame(dmux, frame);
     if (added_frame) {
@@ -446,9 +455,11 @@
     const size_t chunk_start_offset = mem->start_;
     const uint32_t fourcc = ReadLE32(mem);
     const uint32_t chunk_size = ReadLE32(mem);
-    const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
+    uint32_t chunk_size_padded;
 
     if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+
+    chunk_size_padded = chunk_size + (chunk_size & 1);
     if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
 
     switch (fourcc) {
@@ -603,7 +614,6 @@
 
   while (f != NULL) {
     const int cur_frame_set = f->frame_num_;
-    int frame_count = 0;
 
     // Check frame properties.
     for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
@@ -638,8 +648,6 @@
                             dmux->canvas_width_, dmux->canvas_height_)) {
         return 0;
       }
-
-      ++frame_count;
     }
   }
   return 1;
diff --git a/third_party/libwebp/src/demux/libwebpdemux.pc.in b/third_party/libwebp/src/demux/libwebpdemux.pc.in
index 6dfbbbd..4da2e40 100644
--- a/third_party/libwebp/src/demux/libwebpdemux.pc.in
+++ b/third_party/libwebp/src/demux/libwebpdemux.pc.in
@@ -6,6 +6,6 @@
 Name: libwebpdemux
 Description: Library for parsing the WebP graphics format container
 Version: @PACKAGE_VERSION@
-Requires: libwebp >= 0.2.0
+Requires.private: libwebp >= 0.2.0
 Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpdemux
+Libs: -L${libdir} -l@webp_libname_prefix@webpdemux
diff --git a/third_party/libwebp/src/demux/libwebpdemux.rc b/third_party/libwebp/src/demux/libwebpdemux.rc
index 544a8b2..49a4547 100644
--- a/third_party/libwebp/src/demux/libwebpdemux.rc
+++ b/third_party/libwebp/src/demux/libwebpdemux.rc
@@ -6,8 +6,8 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,0
- PRODUCTVERSION 1,0,0,0
+ FILEVERSION 1,0,3,1
+ PRODUCTVERSION 1,0,3,1
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -24,12 +24,12 @@
         BEGIN
             VALUE "CompanyName", "Google, Inc."
             VALUE "FileDescription", "libwebpdemux DLL"
-            VALUE "FileVersion", "1.0.0"
+            VALUE "FileVersion", "1.3.1"
             VALUE "InternalName", "libwebpdemux.dll"
-            VALUE "LegalCopyright", "Copyright (C) 2018"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
             VALUE "OriginalFilename", "libwebpdemux.dll"
             VALUE "ProductName", "WebP Image Demuxer"
-            VALUE "ProductVersion", "1.0.0"
+            VALUE "ProductVersion", "1.3.1"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/third_party/libwebp/src/dsp/Makefile.am b/third_party/libwebp/src/dsp/Makefile.am
index 0836d8f..7db4ef0 100644
--- a/third_party/libwebp/src/dsp/Makefile.am
+++ b/third_party/libwebp/src/dsp/Makefile.am
@@ -1,7 +1,6 @@
 AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
 noinst_LTLIBRARIES =
 noinst_LTLIBRARIES += libwebpdsp.la
-noinst_LTLIBRARIES += libwebpdsp_avx2.la
 noinst_LTLIBRARIES += libwebpdsp_sse2.la
 noinst_LTLIBRARIES += libwebpdspdecode_sse2.la
 noinst_LTLIBRARIES += libwebpdsp_sse41.la
@@ -10,6 +9,10 @@
 noinst_LTLIBRARIES += libwebpdspdecode_neon.la
 noinst_LTLIBRARIES += libwebpdsp_msa.la
 noinst_LTLIBRARIES += libwebpdspdecode_msa.la
+noinst_LTLIBRARIES += libwebpdsp_mips32.la
+noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
+noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
+noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
 
 if BUILD_LIBWEBPDECODER
   noinst_LTLIBRARIES += libwebpdspdecode.la
@@ -20,51 +23,31 @@
 
 COMMON_SOURCES =
 COMMON_SOURCES += alpha_processing.c
-COMMON_SOURCES += alpha_processing_mips_dsp_r2.c
-COMMON_SOURCES += common_sse2.h
 COMMON_SOURCES += cpu.c
+COMMON_SOURCES += cpu.h
 COMMON_SOURCES += dec.c
 COMMON_SOURCES += dec_clip_tables.c
-COMMON_SOURCES += dec_mips32.c
-COMMON_SOURCES += dec_mips_dsp_r2.c
 COMMON_SOURCES += dsp.h
 COMMON_SOURCES += filters.c
-COMMON_SOURCES += filters_mips_dsp_r2.c
 COMMON_SOURCES += lossless.c
 COMMON_SOURCES += lossless.h
 COMMON_SOURCES += lossless_common.h
-COMMON_SOURCES += lossless_mips_dsp_r2.c
-COMMON_SOURCES += mips_macro.h
 COMMON_SOURCES += rescaler.c
-COMMON_SOURCES += rescaler_mips32.c
-COMMON_SOURCES += rescaler_mips_dsp_r2.c
 COMMON_SOURCES += upsampling.c
-COMMON_SOURCES += upsampling_mips_dsp_r2.c
 COMMON_SOURCES += yuv.c
 COMMON_SOURCES += yuv.h
-COMMON_SOURCES += yuv_mips32.c
-COMMON_SOURCES += yuv_mips_dsp_r2.c
 
 ENC_SOURCES =
 ENC_SOURCES += cost.c
-ENC_SOURCES += cost_mips32.c
-ENC_SOURCES += cost_mips_dsp_r2.c
 ENC_SOURCES += enc.c
-ENC_SOURCES += enc_mips32.c
-ENC_SOURCES += enc_mips_dsp_r2.c
 ENC_SOURCES += lossless_enc.c
-ENC_SOURCES += lossless_enc_mips32.c
-ENC_SOURCES += lossless_enc_mips_dsp_r2.c
+ENC_SOURCES += quant.h
 ENC_SOURCES += ssim.c
 
-libwebpdsp_avx2_la_SOURCES =
-libwebpdsp_avx2_la_SOURCES += enc_avx2.c
-libwebpdsp_avx2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
-libwebpdsp_avx2_la_CFLAGS = $(AM_CFLAGS) $(AVX2_FLAGS)
-
 libwebpdspdecode_sse41_la_SOURCES =
 libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
 libwebpdspdecode_sse41_la_SOURCES += dec_sse41.c
+libwebpdspdecode_sse41_la_SOURCES += lossless_sse41.c
 libwebpdspdecode_sse41_la_SOURCES += upsampling_sse41.c
 libwebpdspdecode_sse41_la_SOURCES += yuv_sse41.c
 libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
@@ -72,6 +55,7 @@
 
 libwebpdspdecode_sse2_la_SOURCES =
 libwebpdspdecode_sse2_la_SOURCES += alpha_processing_sse2.c
+libwebpdspdecode_sse2_la_SOURCES += common_sse2.h
 libwebpdspdecode_sse2_la_SOURCES += dec_sse2.c
 libwebpdspdecode_sse2_la_SOURCES += filters_sse2.c
 libwebpdspdecode_sse2_la_SOURCES += lossless_sse2.c
@@ -103,6 +87,26 @@
 libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS)
 libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS)
 
+libwebpdspdecode_mips32_la_SOURCES =
+libwebpdspdecode_mips32_la_SOURCES += dec_mips32.c
+libwebpdspdecode_mips32_la_SOURCES += mips_macro.h
+libwebpdspdecode_mips32_la_SOURCES += rescaler_mips32.c
+libwebpdspdecode_mips32_la_SOURCES += yuv_mips32.c
+libwebpdspdecode_mips32_la_CPPFLAGS = $(libwebpdsp_mips32_la_CPPFLAGS)
+libwebpdspdecode_mips32_la_CFLAGS = $(libwebpdsp_mips32_la_CFLAGS)
+
+libwebpdspdecode_mips_dsp_r2_la_SOURCES =
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += alpha_processing_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += dec_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += filters_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += lossless_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += mips_macro.h
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += rescaler_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += upsampling_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_SOURCES += yuv_mips_dsp_r2.c
+libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
+libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
+
 libwebpdsp_sse2_la_SOURCES =
 libwebpdsp_sse2_la_SOURCES += cost_sse2.c
 libwebpdsp_sse2_la_SOURCES += enc_sse2.c
@@ -120,6 +124,7 @@
 libwebpdsp_sse41_la_LIBADD = libwebpdspdecode_sse41.la
 
 libwebpdsp_neon_la_SOURCES =
+libwebpdsp_neon_la_SOURCES += cost_neon.c
 libwebpdsp_neon_la_SOURCES += enc_neon.c
 libwebpdsp_neon_la_SOURCES += lossless_enc_neon.c
 libwebpdsp_neon_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
@@ -133,6 +138,22 @@
 libwebpdsp_msa_la_CFLAGS = $(AM_CFLAGS)
 libwebpdsp_msa_la_LIBADD = libwebpdspdecode_msa.la
 
+libwebpdsp_mips32_la_SOURCES =
+libwebpdsp_mips32_la_SOURCES += cost_mips32.c
+libwebpdsp_mips32_la_SOURCES += enc_mips32.c
+libwebpdsp_mips32_la_SOURCES += lossless_enc_mips32.c
+libwebpdsp_mips32_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
+libwebpdsp_mips32_la_CFLAGS = $(AM_CFLAGS)
+libwebpdsp_mips32_la_LIBADD = libwebpdspdecode_mips32.la
+
+libwebpdsp_mips_dsp_r2_la_SOURCES =
+libwebpdsp_mips_dsp_r2_la_SOURCES += cost_mips_dsp_r2.c
+libwebpdsp_mips_dsp_r2_la_SOURCES += enc_mips_dsp_r2.c
+libwebpdsp_mips_dsp_r2_la_SOURCES += lossless_enc_mips_dsp_r2.c
+libwebpdsp_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
+libwebpdsp_mips_dsp_r2_la_CFLAGS = $(AM_CFLAGS)
+libwebpdsp_mips_dsp_r2_la_LIBADD = libwebpdspdecode_mips_dsp_r2.la
+
 libwebpdsp_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES)
 
 noinst_HEADERS =
@@ -144,11 +165,12 @@
 libwebpdsp_la_CPPFLAGS += $(USE_SWAP_16BIT_CSP)
 libwebpdsp_la_LDFLAGS = -lm
 libwebpdsp_la_LIBADD =
-libwebpdsp_la_LIBADD += libwebpdsp_avx2.la
 libwebpdsp_la_LIBADD += libwebpdsp_sse2.la
 libwebpdsp_la_LIBADD += libwebpdsp_sse41.la
 libwebpdsp_la_LIBADD += libwebpdsp_neon.la
 libwebpdsp_la_LIBADD += libwebpdsp_msa.la
+libwebpdsp_la_LIBADD += libwebpdsp_mips32.la
+libwebpdsp_la_LIBADD += libwebpdsp_mips_dsp_r2.la
 
 if BUILD_LIBWEBPDECODER
   libwebpdspdecode_la_SOURCES = $(COMMON_SOURCES)
@@ -160,4 +182,6 @@
   libwebpdspdecode_la_LIBADD += libwebpdspdecode_sse41.la
   libwebpdspdecode_la_LIBADD += libwebpdspdecode_neon.la
   libwebpdspdecode_la_LIBADD += libwebpdspdecode_msa.la
+  libwebpdspdecode_la_LIBADD += libwebpdspdecode_mips32.la
+  libwebpdspdecode_la_LIBADD += libwebpdspdecode_mips_dsp_r2.la
 endif
diff --git a/third_party/libwebp/src/dsp/alpha_processing.c b/third_party/libwebp/src/dsp/alpha_processing.c
index 819d139..1d152f2 100644
--- a/third_party/libwebp/src/dsp/alpha_processing.c
+++ b/third_party/libwebp/src/dsp/alpha_processing.c
@@ -157,7 +157,8 @@
   }
 }
 
-void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
+void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
+                   const uint8_t* WEBP_RESTRICT const alpha,
                    int width, int inverse) {
   int x;
   for (x = 0; x < width; ++x) {
@@ -178,7 +179,8 @@
 #undef MFIX
 
 void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
-void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
+                    const uint8_t* WEBP_RESTRICT const alpha,
                     int width, int inverse);
 
 //------------------------------------------------------------------------------
@@ -193,8 +195,8 @@
   }
 }
 
-void WebPMultRows(uint8_t* ptr, int stride,
-                  const uint8_t* alpha, int alpha_stride,
+void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
+                  const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
                   int width, int num_rows, int inverse) {
   int n;
   for (n = 0; n < num_rows; ++n) {
@@ -290,9 +292,9 @@
 }
 
 #if !WEBP_NEON_OMIT_C_CODE
-static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
+static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
                            int width, int height,
-                           uint8_t* dst, int dst_stride) {
+                           uint8_t* WEBP_RESTRICT dst, int dst_stride) {
   uint32_t alpha_mask = 0xff;
   int i, j;
 
@@ -309,9 +311,10 @@
   return (alpha_mask != 0xff);
 }
 
-static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
-                                   int width, int height,
-                                   uint32_t* dst, int dst_stride) {
+static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
+                                   int alpha_stride, int width, int height,
+                                   uint32_t* WEBP_RESTRICT dst,
+                                   int dst_stride) {
   int i, j;
   for (j = 0; j < height; ++j) {
     for (i = 0; i < width; ++i) {
@@ -322,9 +325,9 @@
   }
 }
 
-static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
+static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
                           int width, int height,
-                          uint8_t* alpha, int alpha_stride) {
+                          uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
   uint8_t alpha_mask = 0xff;
   int i, j;
 
@@ -340,7 +343,8 @@
   return (alpha_mask == 0xff);
 }
 
-static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
+static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
+                           uint8_t* WEBP_RESTRICT alpha, int size) {
   int i;
   for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
 }
@@ -359,6 +363,11 @@
   return 0;
 }
 
+static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
+  int x;
+  for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
+}
+
 //------------------------------------------------------------------------------
 // Simple channel manipulations.
 
@@ -367,8 +376,11 @@
 }
 
 #ifdef WORDS_BIGENDIAN
-static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
-                       const uint8_t* b, int len, uint32_t* out) {
+static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
+                       const uint8_t* WEBP_RESTRICT r,
+                       const uint8_t* WEBP_RESTRICT g,
+                       const uint8_t* WEBP_RESTRICT b,
+                       int len, uint32_t* WEBP_RESTRICT out) {
   int i;
   for (i = 0; i < len; ++i) {
     out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
@@ -376,8 +388,10 @@
 }
 #endif
 
-static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
-                      int len, int step, uint32_t* out) {
+static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
+                      const uint8_t* WEBP_RESTRICT g,
+                      const uint8_t* WEBP_RESTRICT b,
+                      int len, int step, uint32_t* WEBP_RESTRICT out) {
   int i, offset = 0;
   for (i = 0; i < len; ++i) {
     out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
@@ -387,23 +401,31 @@
 
 void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
 void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
-int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
-void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
-int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
-void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
+int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
+                         uint8_t* WEBP_RESTRICT, int);
+void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int,
+                                 uint32_t* WEBP_RESTRICT, int);
+int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
+                        uint8_t* WEBP_RESTRICT, int);
+void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
+                         uint8_t* WEBP_RESTRICT alpha, int size);
 #ifdef WORDS_BIGENDIAN
 void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
                      const uint8_t* b, int, uint32_t*);
 #endif
-void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
-                    int len, int step, uint32_t* out);
+void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
+                    const uint8_t* WEBP_RESTRICT g,
+                    const uint8_t* WEBP_RESTRICT b,
+                    int len, int step, uint32_t* WEBP_RESTRICT out);
 
 int (*WebPHasAlpha8b)(const uint8_t* src, int length);
 int (*WebPHasAlpha32b)(const uint8_t* src, int length);
+void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
 
 //------------------------------------------------------------------------------
 // Init function
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void WebPInitAlphaProcessingMIPSdspR2(void);
 extern void WebPInitAlphaProcessingSSE2(void);
 extern void WebPInitAlphaProcessingSSE41(void);
@@ -428,13 +450,14 @@
 
   WebPHasAlpha8b = HasAlpha8b_C;
   WebPHasAlpha32b = HasAlpha32b_C;
+  WebPAlphaReplace = AlphaReplace_C;
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPInitAlphaProcessingSSE2();
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
       if (VP8GetCPUInfo(kSSE4_1)) {
         WebPInitAlphaProcessingSSE41();
       }
@@ -448,7 +471,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     WebPInitAlphaProcessingNEON();
@@ -469,4 +492,5 @@
   assert(WebPPackRGB != NULL);
   assert(WebPHasAlpha8b != NULL);
   assert(WebPHasAlpha32b != NULL);
+  assert(WebPAlphaReplace != NULL);
 }
diff --git a/third_party/libwebp/src/dsp/alpha_processing_neon.c b/third_party/libwebp/src/dsp/alpha_processing_neon.c
index 9d55421..6716fb7 100644
--- a/third_party/libwebp/src/dsp/alpha_processing_neon.c
+++ b/third_party/libwebp/src/dsp/alpha_processing_neon.c
@@ -80,10 +80,10 @@
 
 //------------------------------------------------------------------------------
 
-static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
-                              int width, int height,
-                              uint8_t* dst, int dst_stride) {
-  uint32_t alpha_mask = 0xffffffffu;
+static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
+                              int alpha_stride, int width, int height,
+                              uint8_t* WEBP_RESTRICT dst, int dst_stride) {
+  uint32_t alpha_mask = 0xffu;
   uint8x8_t mask8 = vdup_n_u8(0xff);
   uint32_t tmp[2];
   int i, j;
@@ -107,14 +107,16 @@
     dst += dst_stride;
   }
   vst1_u8((uint8_t*)tmp, mask8);
+  alpha_mask *= 0x01010101;
   alpha_mask &= tmp[0];
   alpha_mask &= tmp[1];
   return (alpha_mask != 0xffffffffu);
 }
 
-static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
-                                      int width, int height,
-                                      uint32_t* dst, int dst_stride) {
+static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
+                                      int alpha_stride, int width, int height,
+                                      uint32_t* WEBP_RESTRICT dst,
+                                      int dst_stride) {
   int i, j;
   uint8x8x4_t greens;   // leave A/R/B channels zero'd.
   greens.val[0] = vdup_n_u8(0);
@@ -131,10 +133,10 @@
   }
 }
 
-static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
+static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
                              int width, int height,
-                             uint8_t* alpha, int alpha_stride) {
-  uint32_t alpha_mask = 0xffffffffu;
+                             uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
+  uint32_t alpha_mask = 0xffu;
   uint8x8_t mask8 = vdup_n_u8(0xff);
   uint32_t tmp[2];
   int i, j;
@@ -156,13 +158,14 @@
     alpha += alpha_stride;
   }
   vst1_u8((uint8_t*)tmp, mask8);
+  alpha_mask *= 0x01010101;
   alpha_mask &= tmp[0];
   alpha_mask &= tmp[1];
   return (alpha_mask == 0xffffffffu);
 }
 
-static void ExtractGreen_NEON(const uint32_t* argb,
-                              uint8_t* alpha, int size) {
+static void ExtractGreen_NEON(const uint32_t* WEBP_RESTRICT argb,
+                              uint8_t* WEBP_RESTRICT alpha, int size) {
   int i;
   for (i = 0; i + 16 <= size; i += 16) {
     const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i));
diff --git a/third_party/libwebp/src/dsp/alpha_processing_sse2.c b/third_party/libwebp/src/dsp/alpha_processing_sse2.c
index 7658700..f0843d0 100644
--- a/third_party/libwebp/src/dsp/alpha_processing_sse2.c
+++ b/third_party/libwebp/src/dsp/alpha_processing_sse2.c
@@ -18,16 +18,16 @@
 
 //------------------------------------------------------------------------------
 
-static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
-                              int width, int height,
-                              uint8_t* dst, int dst_stride) {
+static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
+                              int alpha_stride, int width, int height,
+                              uint8_t* WEBP_RESTRICT dst, int dst_stride) {
   // alpha_and stores an 'and' operation of all the alpha[] values. The final
   // value is not 0xff if any of the alpha[] is not equal to 0xff.
   uint32_t alpha_and = 0xff;
   int i, j;
   const __m128i zero = _mm_setzero_si128();
-  const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u);  // to preserve RGB
-  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00);  // to preserve RGB
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte
@@ -72,9 +72,10 @@
   return (alpha_and != 0xff);
 }
 
-static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
-                                      int width, int height,
-                                      uint32_t* dst, int dst_stride) {
+static void DispatchAlphaToGreen_SSE2(const uint8_t* WEBP_RESTRICT alpha,
+                                      int alpha_stride, int width, int height,
+                                      uint32_t* WEBP_RESTRICT dst,
+                                      int dst_stride) {
   int i, j;
   const __m128i zero = _mm_setzero_si128();
   const int limit = width & ~15;
@@ -98,15 +99,15 @@
   }
 }
 
-static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
+static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
                              int width, int height,
-                             uint8_t* alpha, int alpha_stride) {
+                             uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
   // alpha_and stores an 'and' operation of all the alpha[] values. The final
   // value is not 0xff if any of the alpha[] is not equal to 0xff.
   uint32_t alpha_and = 0xff;
   int i, j;
-  const __m128i a_mask = _mm_set1_epi32(0xffu);  // to preserve alpha
-  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  const __m128i a_mask = _mm_set1_epi32(0xff);  // to preserve alpha
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte
@@ -177,7 +178,7 @@
 static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
                                     int w, int h, int stride) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i kMult = _mm_set1_epi16(0x8081u);
+  const __m128i kMult = _mm_set1_epi16((short)0x8081);
   const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
   const int kSpan = 4;
   while (h-- > 0) {
@@ -214,7 +215,7 @@
 // Alpha detection
 
 static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
-  const __m128i all_0xff = _mm_set1_epi8(0xff);
+  const __m128i all_0xff = _mm_set1_epi8((char)0xff);
   int i = 0;
   for (; i + 16 <= length; i += 16) {
     const __m128i v = _mm_loadu_si128((const __m128i*)(src + i));
@@ -228,7 +229,7 @@
 
 static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
   const __m128i alpha_mask = _mm_set1_epi32(0xff);
-  const __m128i all_0xff = _mm_set1_epi8(0xff);
+  const __m128i all_0xff = _mm_set1_epi8((char)0xff);
   int i = 0;
   // We don't know if we can access the last 3 bytes after the last alpha
   // value 'src[4 * length - 4]' (because we don't know if alpha is the first
@@ -265,6 +266,27 @@
   return 0;
 }
 
+static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
+  const __m128i m_color = _mm_set1_epi32((int)color);
+  const __m128i zero = _mm_setzero_si128();
+  int i = 0;
+  for (; i + 8 <= length; i += 8) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 4));
+    const __m128i b0 = _mm_srai_epi32(a0, 24);
+    const __m128i b1 = _mm_srai_epi32(a1, 24);
+    const __m128i c0 = _mm_cmpeq_epi32(b0, zero);
+    const __m128i c1 = _mm_cmpeq_epi32(b1, zero);
+    const __m128i d0 = _mm_and_si128(c0, m_color);
+    const __m128i d1 = _mm_and_si128(c1, m_color);
+    const __m128i e0 = _mm_andnot_si128(c0, a0);
+    const __m128i e1 = _mm_andnot_si128(c1, a1);
+    _mm_storeu_si128((__m128i*)(src + i + 0), _mm_or_si128(d0, e0));
+    _mm_storeu_si128((__m128i*)(src + i + 4), _mm_or_si128(d1, e1));
+  }
+  for (; i < length; ++i) if ((src[i] >> 24) == 0) src[i] = color;
+}
+
 // -----------------------------------------------------------------------------
 // Apply alpha value to rows
 
@@ -296,7 +318,8 @@
   if (width > 0) WebPMultARGBRow_C(ptr + x, width, inverse);
 }
 
-static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
+static void MultRow_SSE2(uint8_t* WEBP_RESTRICT const ptr,
+                         const uint8_t* WEBP_RESTRICT const alpha,
                          int width, int inverse) {
   int x = 0;
   if (!inverse) {
@@ -334,6 +357,7 @@
 
   WebPHasAlpha8b = HasAlpha8b_SSE2;
   WebPHasAlpha32b = HasAlpha32b_SSE2;
+  WebPAlphaReplace = AlphaReplace_SSE2;
 }
 
 #else  // !WEBP_USE_SSE2
diff --git a/third_party/libwebp/src/dsp/alpha_processing_sse41.c b/third_party/libwebp/src/dsp/alpha_processing_sse41.c
index 56040f9..1156ac3 100644
--- a/third_party/libwebp/src/dsp/alpha_processing_sse41.c
+++ b/third_party/libwebp/src/dsp/alpha_processing_sse41.c
@@ -19,14 +19,14 @@
 
 //------------------------------------------------------------------------------
 
-static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
-                              int width, int height,
-                              uint8_t* alpha, int alpha_stride) {
+static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
+                              int argb_stride, int width, int height,
+                              uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
   // alpha_and stores an 'and' operation of all the alpha[] values. The final
   // value is not 0xff if any of the alpha[] is not equal to 0xff.
   uint32_t alpha_and = 0xff;
   int i, j;
-  const __m128i all_0xff = _mm_set1_epi32(~0u);
+  const __m128i all_0xff = _mm_set1_epi32(~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte
diff --git a/third_party/libwebp/src/dsp/cost.c b/third_party/libwebp/src/dsp/cost.c
index 0dba57b..eae0cb7 100644
--- a/third_party/libwebp/src/dsp/cost.c
+++ b/third_party/libwebp/src/dsp/cost.c
@@ -380,9 +380,11 @@
 VP8GetResidualCostFunc VP8GetResidualCost;
 VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8EncDspCostInitMIPS32(void);
 extern void VP8EncDspCostInitMIPSdspR2(void);
 extern void VP8EncDspCostInitSSE2(void);
+extern void VP8EncDspCostInitNEON(void);
 
 WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
   VP8GetResidualCost = GetResidualCost_C;
@@ -400,11 +402,16 @@
       VP8EncDspCostInitMIPSdspR2();
     }
 #endif
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8EncDspCostInitSSE2();
     }
 #endif
+#if defined(WEBP_HAVE_NEON)
+    if (VP8GetCPUInfo(kNEON)) {
+      VP8EncDspCostInitNEON();
+    }
+#endif
   }
 }
 
diff --git a/third_party/libwebp/src/dsp/cost_neon.c b/third_party/libwebp/src/dsp/cost_neon.c
new file mode 100644
index 0000000..5e28930
--- /dev/null
+++ b/third_party/libwebp/src/dsp/cost_neon.c
@@ -0,0 +1,126 @@
+// Copyright 2018 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// ARM NEON version of cost functions
+
+#include "src/dsp/dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#if defined(STARBOARD)
+#include "starboard/client_porting/poem/assert_poem.h"
+#endif
+
+#include "src/dsp/neon.h"
+#include "src/enc/cost_enc.h"
+
+static const uint8_t position[16] = { 1, 2,  3,  4,  5,  6,  7,  8,
+                                      9, 10, 11, 12, 13, 14, 15, 16 };
+
+static void SetResidualCoeffs_NEON(const int16_t* const coeffs,
+                                   VP8Residual* const res) {
+  const int16x8_t minus_one = vdupq_n_s16(-1);
+  const int16x8_t coeffs_0 = vld1q_s16(coeffs);
+  const int16x8_t coeffs_1 = vld1q_s16(coeffs + 8);
+  const uint16x8_t eob_0 = vtstq_s16(coeffs_0, minus_one);
+  const uint16x8_t eob_1 = vtstq_s16(coeffs_1, minus_one);
+  const uint8x16_t eob = vcombine_u8(vqmovn_u16(eob_0), vqmovn_u16(eob_1));
+  const uint8x16_t masked = vandq_u8(eob, vld1q_u8(position));
+
+#if WEBP_AARCH64
+  res->last = vmaxvq_u8(masked) - 1;
+#else
+  const uint8x8_t eob_8x8 = vmax_u8(vget_low_u8(masked), vget_high_u8(masked));
+  const uint16x8_t eob_16x8 = vmovl_u8(eob_8x8);
+  const uint16x4_t eob_16x4 =
+      vmax_u16(vget_low_u16(eob_16x8), vget_high_u16(eob_16x8));
+  const uint32x4_t eob_32x4 = vmovl_u16(eob_16x4);
+  uint32x2_t eob_32x2 =
+      vmax_u32(vget_low_u32(eob_32x4), vget_high_u32(eob_32x4));
+  eob_32x2 = vpmax_u32(eob_32x2, eob_32x2);
+
+  vst1_lane_s32(&res->last, vreinterpret_s32_u32(eob_32x2), 0);
+  --res->last;
+#endif  // WEBP_AARCH64
+
+  res->coeffs = coeffs;
+}
+
+static int GetResidualCost_NEON(int ctx0, const VP8Residual* const res) {
+  uint8_t levels[16], ctxs[16];
+  uint16_t abs_levels[16];
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  const int p0 = res->prob[n][ctx0][0];
+  CostArrayPtr const costs = res->costs;
+  const uint16_t* t = costs[n][ctx0];
+  // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0
+  // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll
+  // be missing during the loop.
+  int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0;
+
+  if (res->last < 0) {
+    return VP8BitCost(0, p0);
+  }
+
+  {   // precompute clamped levels and contexts, packed to 8b.
+    const uint8x16_t kCst2 = vdupq_n_u8(2);
+    const uint8x16_t kCst67 = vdupq_n_u8(MAX_VARIABLE_LEVEL);
+    const int16x8_t c0 = vld1q_s16(res->coeffs);
+    const int16x8_t c1 = vld1q_s16(res->coeffs + 8);
+    const uint16x8_t E0 = vreinterpretq_u16_s16(vabsq_s16(c0));
+    const uint16x8_t E1 = vreinterpretq_u16_s16(vabsq_s16(c1));
+    const uint8x16_t F = vcombine_u8(vqmovn_u16(E0), vqmovn_u16(E1));
+    const uint8x16_t G = vminq_u8(F, kCst2);   // context = 0,1,2
+    const uint8x16_t H = vminq_u8(F, kCst67);  // clamp_level in [0..67]
+
+    vst1q_u8(ctxs, G);
+    vst1q_u8(levels, H);
+
+    vst1q_u16(abs_levels, E0);
+    vst1q_u16(abs_levels + 8, E1);
+  }
+  for (; n < res->last; ++n) {
+    const int ctx = ctxs[n];
+    const int level = levels[n];
+    const int flevel = abs_levels[n];   // full level
+    cost += VP8LevelFixedCosts[flevel] + t[level];  // simplified VP8LevelCost()
+    t = costs[n + 1][ctx];
+  }
+  // Last coefficient is always non-zero
+  {
+    const int level = levels[n];
+    const int flevel = abs_levels[n];
+    assert(flevel != 0);
+    cost += VP8LevelFixedCosts[flevel] + t[level];
+    if (n < 15) {
+      const int b = VP8EncBands[n + 1];
+      const int ctx = ctxs[n];
+      const int last_p0 = res->prob[b][ctx][0];
+      cost += VP8BitCost(0, last_p0);
+    }
+  }
+  return cost;
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspCostInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitNEON(void) {
+  VP8SetResidualCoeffs = SetResidualCoeffs_NEON;
+  VP8GetResidualCost = GetResidualCost_NEON;
+}
+
+#else  // !WEBP_USE_NEON
+
+WEBP_DSP_INIT_STUB(VP8EncDspCostInitNEON)
+
+#endif  // WEBP_USE_NEON
diff --git a/third_party/libwebp/src/dsp/cpu.c b/third_party/libwebp/src/dsp/cpu.c
index cba9455..71b20f6 100644
--- a/third_party/libwebp/src/dsp/cpu.c
+++ b/third_party/libwebp/src/dsp/cpu.c
@@ -11,7 +11,7 @@
 //
 // Author: Christian Duvivier (cduvivier@google.com)
 
-#include "src/dsp/dsp.h"
+#include "src/dsp/cpu.h"
 
 #if defined(STARBOARD)
 
@@ -19,7 +19,7 @@
 #include "starboard/log.h"
 #include "starboard/system.h"
 
-bool warn_if_not_enabled(const char* name, bool value) {
+static bool warn_if_not_enabled(const char* name, bool value) {
   if (!value) {
     SbLogFormatF("LibWebP optimization not enabled: %s\n", name);
     SbLogFlush();
@@ -100,12 +100,18 @@
     : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
     : "a"(info_type), "c"(0));
 }
-#elif (defined(_M_X64) || defined(_M_IX86)) && \
-      defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729  // >= VS2008 SP1
+#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
+
+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729  // >= VS2008 SP1
 #include <intrin.h>
 #define GetCPUInfo(info, type) __cpuidex(info, type, 0)  // set ecx=0
-#elif defined(WEBP_MSC_SSE2)
+#define WEBP_HAVE_MSC_CPUID
+#elif _MSC_VER > 1310
+#include <intrin.h>
 #define GetCPUInfo __cpuid
+#define WEBP_HAVE_MSC_CPUID
+#endif
+
 #endif
 
 // NaCl has no support for xgetbv or the raw opcode.
@@ -139,7 +145,7 @@
 #define xgetbv() 0U  // no AVX for older x64 or unrecognized toolchains.
 #endif
 
-#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
+#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
 
 // helper function for run-time detection of slow SSSE3 platforms
 static int CheckSlowModel(int info) {
@@ -212,21 +218,49 @@
   }
   return 0;
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
 #elif defined(WEBP_ANDROID_NEON)  // NB: needs to be before generic NEON test.
 static int AndroidCPUInfo(CPUFeature feature) {
   const AndroidCpuFamily cpu_family = android_getCpuFamily();
   const uint64_t cpu_features = android_getCpuFeatures();
   if (feature == kNEON) {
-    return (cpu_family == ANDROID_CPU_FAMILY_ARM &&
-            0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON));
+    return cpu_family == ANDROID_CPU_FAMILY_ARM &&
+           (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
   }
   return 0;
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
-#elif defined(WEBP_USE_NEON)
-// define a dummy function to enable turning off NEON at runtime by setting
-// VP8DecGetCPUInfo = NULL
+#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
+// Use compile flags as an indicator of SIMD support instead of a runtime check.
+static int wasmCPUInfo(CPUFeature feature) {
+  switch (feature) {
+#ifdef WEBP_HAVE_SSE2
+    case kSSE2:
+      return 1;
+#endif
+#ifdef WEBP_HAVE_SSE41
+    case kSSE3:
+    case kSlowSSSE3:
+    case kSSE4_1:
+      return 1;
+#endif
+#ifdef WEBP_HAVE_NEON
+    case kNEON:
+      return 1;
+#endif
+    default:
+      break;
+  }
+  return 0;
+}
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
+VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
+#elif defined(WEBP_HAVE_NEON)
+// In most cases this function doesn't check for NEON support (it's assumed by
+// the configuration), but enables turning off NEON at runtime, for testing
+// purposes, by setting VP8GetCPUInfo = NULL.
 static int armCPUInfo(CPUFeature feature) {
   if (feature != kNEON) return 0;
 #if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
@@ -250,6 +284,7 @@
   return 1;
 #endif
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
 #elif defined(WEBP_USE_MIPS32) || defined(WEBP_USE_MIPS_DSP_R2) || \
       defined(WEBP_USE_MSA)
@@ -261,8 +296,10 @@
   }
 
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
 #else
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = NULL;
 #endif
 
diff --git a/third_party/libwebp/src/dsp/cpu.h b/third_party/libwebp/src/dsp/cpu.h
new file mode 100644
index 0000000..c86540f
--- /dev/null
+++ b/third_party/libwebp/src/dsp/cpu.h
@@ -0,0 +1,266 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   CPU detection functions and macros.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_DSP_CPU_H_
+#define WEBP_DSP_CPU_H_
+
+#include <stddef.h>
+
+#ifdef HAVE_CONFIG_H
+#include "src/webp/config.h"
+#endif
+
+#include "src/webp/types.h"
+
+#if defined(__GNUC__)
+#define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
+#define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
+#else
+#define LOCAL_GCC_VERSION 0
+#define LOCAL_GCC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__)
+#define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
+#define LOCAL_CLANG_PREREQ(maj, min) \
+  (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
+#else
+#define LOCAL_CLANG_VERSION 0
+#define LOCAL_CLANG_PREREQ(maj, min) 0
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+//------------------------------------------------------------------------------
+// x86 defines.
+
+#if !defined(HAVE_CONFIG_H)
+#if defined(_MSC_VER) && _MSC_VER > 1310 && \
+    (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
+    (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE41  // Visual C++ SSE4.1 targets
+#endif
+#endif
+
+// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
+// files without intrinsics, allowing the corresponding Init() to be called.
+// Files containing intrinsics will need to be built targeting the instruction
+// set so should succeed on one of the earlier tests.
+#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
+    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
+#define WEBP_USE_SSE2
+#endif
+
+#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
+#define WEBP_HAVE_SSE2
+#endif
+
+#if (defined(__SSE4_1__) || defined(WEBP_MSC_SSE41)) && \
+    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE41))
+#define WEBP_USE_SSE41
+#endif
+
+#if defined(WEBP_USE_SSE41) && !defined(WEBP_HAVE_SSE41)
+#define WEBP_HAVE_SSE41
+#endif
+
+#undef WEBP_MSC_SSE41
+#undef WEBP_MSC_SSE2
+
+//------------------------------------------------------------------------------
+// Arm defines.
+
+// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
+// inline assembly would need to be modified for use with Native Client.
+#if ((defined(__ARM_NEON__) || defined(__aarch64__)) &&       \
+     (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
+    !defined(__native_client__)
+#define WEBP_USE_NEON
+#endif
+
+#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
+    defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
+#define WEBP_ANDROID_NEON  // Android targets that may have NEON
+#define WEBP_USE_NEON
+#endif
+
+// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
+// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
+// arm_neon.h. Compile errors were seen with Visual Studio 2019 16.4 with
+// vtbl4_u8(); a fix was made in 16.6.
+#if defined(_MSC_VER) && \
+    ((_MSC_VER >= 1700 && defined(_M_ARM)) || \
+     (_MSC_VER >= 1926 && (defined(_M_ARM64) || defined(_M_ARM64EC))))
+#define WEBP_USE_NEON
+#define WEBP_USE_INTRINSICS
+#endif
+
+#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
+#define WEBP_AARCH64 1
+#else
+#define WEBP_AARCH64 0
+#endif
+
+#if defined(WEBP_USE_NEON) && !defined(WEBP_HAVE_NEON)
+#define WEBP_HAVE_NEON
+#endif
+
+//------------------------------------------------------------------------------
+// MIPS defines.
+
+#if defined(__mips__) && !defined(__mips64) && defined(__mips_isa_rev) && \
+    (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
+#define WEBP_USE_MIPS32
+#if (__mips_isa_rev >= 2)
+#define WEBP_USE_MIPS32_R2
+#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
+#define WEBP_USE_MIPS_DSP_R2
+#endif
+#endif
+#endif
+
+#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
+#define WEBP_USE_MSA
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef WEBP_DSP_OMIT_C_CODE
+#define WEBP_DSP_OMIT_C_CODE 1
+#endif
+
+#if defined(WEBP_USE_NEON) && WEBP_DSP_OMIT_C_CODE
+#define WEBP_NEON_OMIT_C_CODE 1
+#else
+#define WEBP_NEON_OMIT_C_CODE 0
+#endif
+
+#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
+#define WEBP_NEON_WORK_AROUND_GCC 1
+#else
+#define WEBP_NEON_WORK_AROUND_GCC 0
+#endif
+
+//------------------------------------------------------------------------------
+
+// This macro prevents thread_sanitizer from reporting known concurrent writes.
+#define WEBP_TSAN_IGNORE_FUNCTION
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#undef WEBP_TSAN_IGNORE_FUNCTION
+#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
+#endif
+#endif
+
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#define WEBP_MSAN
+#endif
+#endif
+
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h>  // NOLINT
+
+#define WEBP_DSP_INIT(func)                                         \
+  do {                                                              \
+    static volatile VP8CPUInfo func##_last_cpuinfo_used =           \
+        (VP8CPUInfo)&func##_last_cpuinfo_used;                      \
+    static pthread_mutex_t func##_lock = PTHREAD_MUTEX_INITIALIZER; \
+    if (pthread_mutex_lock(&func##_lock)) break;                    \
+    if (func##_last_cpuinfo_used != VP8GetCPUInfo) func();          \
+    func##_last_cpuinfo_used = VP8GetCPUInfo;                       \
+    (void)pthread_mutex_unlock(&func##_lock);                       \
+  } while (0)
+#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define WEBP_DSP_INIT(func)                               \
+  do {                                                    \
+    static volatile VP8CPUInfo func##_last_cpuinfo_used = \
+        (VP8CPUInfo)&func##_last_cpuinfo_used;            \
+    if (func##_last_cpuinfo_used == VP8GetCPUInfo) break; \
+    func();                                               \
+    func##_last_cpuinfo_used = VP8GetCPUInfo;             \
+  } while (0)
+#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
+// Defines an Init + helper function that control multiple initialization of
+// function pointers / tables.
+/* Usage:
+   WEBP_DSP_INIT_FUNC(InitFunc) {
+     ...function body
+   }
+*/
+#define WEBP_DSP_INIT_FUNC(name)                                            \
+  static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void);                  \
+  WEBP_TSAN_IGNORE_FUNCTION void name(void) { WEBP_DSP_INIT(name##_body); } \
+  static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void)
+
+#define WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#if defined(__clang__) && defined(__has_attribute)
+#if __has_attribute(no_sanitize)
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures. This is only meant to silence unaligned loads on platforms that
+// are known to support them.
+#undef WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNDEF __attribute__((no_sanitize("undefined")))
+
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures related to unsigned integer overflows. This is only meant to
+// silence cases where this well defined behavior is expected.
+#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
+  __attribute__((no_sanitize("unsigned-integer-overflow")))
+#endif
+#endif
+
+// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
+// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
+#if !defined(WEBP_OFFSET_PTR)
+#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
+#endif
+
+// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
+#if !defined(WEBP_SWAP_16BIT_CSP)
+#define WEBP_SWAP_16BIT_CSP 0
+#endif
+
+// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
+#if !defined(WORDS_BIGENDIAN) &&                   \
+    (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
+     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
+#define WORDS_BIGENDIAN
+#endif
+
+typedef enum {
+  kSSE2,
+  kSSE3,
+  kSlowSSSE3,  // special feature for slow SSSE3 architectures
+  kSSE4_1,
+  kAVX,
+  kAVX2,
+  kNEON,
+  kMIPS32,
+  kMIPSdspR2,
+  kMSA
+} CPUFeature;
+
+// returns true if the CPU supports the feature.
+typedef int (*VP8CPUInfo)(CPUFeature feature);
+
+#endif  // WEBP_DSP_CPU_H_
diff --git a/third_party/libwebp/src/dsp/dec.c b/third_party/libwebp/src/dsp/dec.c
index aa2079b..791e041 100644
--- a/third_party/libwebp/src/dsp/dec.c
+++ b/third_party/libwebp/src/dsp/dec.c
@@ -738,6 +738,7 @@
 void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst,
                             int dst_stride);
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8DspInitSSE2(void);
 extern void VP8DspInitSSE41(void);
 extern void VP8DspInitNEON(void);
@@ -811,10 +812,10 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8DspInitSSE2();
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
       if (VP8GetCPUInfo(kSSE4_1)) {
         VP8DspInitSSE41();
       }
@@ -838,7 +839,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     VP8DspInitNEON();
diff --git a/third_party/libwebp/src/dsp/dec_neon.c b/third_party/libwebp/src/dsp/dec_neon.c
index ffa697f..22784cf 100644
--- a/third_party/libwebp/src/dsp/dec_neon.c
+++ b/third_party/libwebp/src/dsp/dec_neon.c
@@ -1283,12 +1283,12 @@
   const uint8x8_t A = vld1_u8(dst - BPS);  // top row
   const uint16x4_t p0 = vpaddl_u8(A);  // cascading summation of the top
   const uint16x4_t p1 = vpadd_u16(p0, p0);
-  const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
-  const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
-  const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
-  const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
-  const uint16x8_t s0 = vaddq_u16(L0, L1);
-  const uint16x8_t s1 = vaddq_u16(L2, L3);
+  const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
+  const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
+  const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
+  const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
+  const uint16x8_t s0 = vaddl_u8(L0, L1);
+  const uint16x8_t s1 = vaddl_u8(L2, L3);
   const uint16x8_t s01 = vaddq_u16(s0, s1);
   const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
   const uint8x8_t dc0 = vrshrn_n_u16(sum, 3);  // (sum + 4) >> 3
@@ -1361,7 +1361,8 @@
   const uint32_t J = dst[-1 + 1 * BPS];
   const uint32_t K = dst[-1 + 2 * BPS];
   const uint32_t L = dst[-1 + 3 * BPS];
-  const uint64x1_t LKJI____ = vcreate_u64(L | (K << 8) | (J << 16) | (I << 24));
+  const uint64x1_t LKJI____ =
+      vcreate_u64((uint64_t)L | (K << 8) | (J << 16) | (I << 24));
   const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
   const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
   const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
@@ -1427,25 +1428,30 @@
 
   if (do_top) {
     const uint8x8_t A = vld1_u8(dst - BPS);  // top row
+#if WEBP_AARCH64
+    const uint16_t p2 = vaddlv_u8(A);
+    sum_top = vdupq_n_u16(p2);
+#else
     const uint16x4_t p0 = vpaddl_u8(A);  // cascading summation of the top
     const uint16x4_t p1 = vpadd_u16(p0, p0);
     const uint16x4_t p2 = vpadd_u16(p1, p1);
     sum_top = vcombine_u16(p2, p2);
+#endif
   }
 
   if (do_left) {
-    const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
-    const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
-    const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
-    const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
-    const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + 4 * BPS - 1));
-    const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + 5 * BPS - 1));
-    const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + 6 * BPS - 1));
-    const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + 7 * BPS - 1));
-    const uint16x8_t s0 = vaddq_u16(L0, L1);
-    const uint16x8_t s1 = vaddq_u16(L2, L3);
-    const uint16x8_t s2 = vaddq_u16(L4, L5);
-    const uint16x8_t s3 = vaddq_u16(L6, L7);
+    const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
+    const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
+    const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
+    const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
+    const uint8x8_t L4 = vld1_u8(dst + 4 * BPS - 1);
+    const uint8x8_t L5 = vld1_u8(dst + 5 * BPS - 1);
+    const uint8x8_t L6 = vld1_u8(dst + 6 * BPS - 1);
+    const uint8x8_t L7 = vld1_u8(dst + 7 * BPS - 1);
+    const uint16x8_t s0 = vaddl_u8(L0, L1);
+    const uint16x8_t s1 = vaddl_u8(L2, L3);
+    const uint16x8_t s2 = vaddl_u8(L4, L5);
+    const uint16x8_t s3 = vaddl_u8(L6, L7);
     const uint16x8_t s01 = vaddq_u16(s0, s1);
     const uint16x8_t s23 = vaddq_u16(s2, s3);
     sum_left = vaddq_u16(s01, s23);
@@ -1505,29 +1511,34 @@
 
   if (do_top) {
     const uint8x16_t A = vld1q_u8(dst - BPS);  // top row
+#if WEBP_AARCH64
+    const uint16_t p3 = vaddlvq_u8(A);
+    sum_top = vdupq_n_u16(p3);
+#else
     const uint16x8_t p0 = vpaddlq_u8(A);  // cascading summation of the top
     const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
     const uint16x4_t p2 = vpadd_u16(p1, p1);
     const uint16x4_t p3 = vpadd_u16(p2, p2);
     sum_top = vcombine_u16(p3, p3);
+#endif
   }
 
   if (do_left) {
     int i;
     sum_left = vdupq_n_u16(0);
     for (i = 0; i < 16; i += 8) {
-      const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + (i + 0) * BPS - 1));
-      const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + (i + 1) * BPS - 1));
-      const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + (i + 2) * BPS - 1));
-      const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + (i + 3) * BPS - 1));
-      const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + (i + 4) * BPS - 1));
-      const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + (i + 5) * BPS - 1));
-      const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + (i + 6) * BPS - 1));
-      const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + (i + 7) * BPS - 1));
-      const uint16x8_t s0 = vaddq_u16(L0, L1);
-      const uint16x8_t s1 = vaddq_u16(L2, L3);
-      const uint16x8_t s2 = vaddq_u16(L4, L5);
-      const uint16x8_t s3 = vaddq_u16(L6, L7);
+      const uint8x8_t L0 = vld1_u8(dst + (i + 0) * BPS - 1);
+      const uint8x8_t L1 = vld1_u8(dst + (i + 1) * BPS - 1);
+      const uint8x8_t L2 = vld1_u8(dst + (i + 2) * BPS - 1);
+      const uint8x8_t L3 = vld1_u8(dst + (i + 3) * BPS - 1);
+      const uint8x8_t L4 = vld1_u8(dst + (i + 4) * BPS - 1);
+      const uint8x8_t L5 = vld1_u8(dst + (i + 5) * BPS - 1);
+      const uint8x8_t L6 = vld1_u8(dst + (i + 6) * BPS - 1);
+      const uint8x8_t L7 = vld1_u8(dst + (i + 7) * BPS - 1);
+      const uint16x8_t s0 = vaddl_u8(L0, L1);
+      const uint16x8_t s1 = vaddl_u8(L2, L3);
+      const uint16x8_t s2 = vaddl_u8(L4, L5);
+      const uint16x8_t s3 = vaddl_u8(L6, L7);
       const uint16x8_t s01 = vaddq_u16(s0, s1);
       const uint16x8_t s23 = vaddq_u16(s2, s3);
       const uint16x8_t sum = vaddq_u16(s01, s23);
diff --git a/third_party/libwebp/src/dsp/dec_sse2.c b/third_party/libwebp/src/dsp/dec_sse2.c
index b3840fa..01e6bcb 100644
--- a/third_party/libwebp/src/dsp/dec_sse2.c
+++ b/third_party/libwebp/src/dsp/dec_sse2.c
@@ -158,10 +158,10 @@
       dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
     } else {
       // Load four bytes/pixels per line.
-      dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
-      dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
-      dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
-      dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+      dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+      dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+      dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+      dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
     }
     // Convert to 16b.
     dst0 = _mm_unpacklo_epi8(dst0, zero);
@@ -187,10 +187,10 @@
       _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
     } else {
       // Store four bytes/pixels per line.
-      WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
-      WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
-      WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
-      WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+      WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+      WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+      WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+      WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
     }
   }
 }
@@ -213,10 +213,10 @@
   const __m128i m3 = _mm_subs_epi16(B, d4);
   const __m128i zero = _mm_setzero_si128();
   // Load the source pixels.
-  __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
-  __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
-  __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
-  __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+  __m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+  __m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+  __m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+  __m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
   // Convert to 16b.
   dst0 = _mm_unpacklo_epi8(dst0, zero);
   dst1 = _mm_unpacklo_epi8(dst1, zero);
@@ -233,10 +233,10 @@
   dst2 = _mm_packus_epi16(dst2, dst2);
   dst3 = _mm_packus_epi16(dst3, dst3);
   // Store the results.
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
 }
 #undef MUL
 #endif   // USE_TRANSFORM_AC3
@@ -326,7 +326,7 @@
   const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
   const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
   const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  const __m128i sign_bit = _mm_set1_epi8((char)0x80);
   *pi = _mm_adds_epi8(*pi, delta);
   *qi = _mm_subs_epi8(*qi, delta);
   FLIP_SIGN_BIT2(*pi, *qi);
@@ -338,9 +338,9 @@
                                          const __m128i* const q0,
                                          const __m128i* const q1,
                                          int thresh, __m128i* const mask) {
-  const __m128i m_thresh = _mm_set1_epi8(thresh);
+  const __m128i m_thresh = _mm_set1_epi8((char)thresh);
   const __m128i t1 = MM_ABS(*p1, *q1);        // abs(p1 - q1)
-  const __m128i kFE = _mm_set1_epi8(0xFE);
+  const __m128i kFE = _mm_set1_epi8((char)0xFE);
   const __m128i t2 = _mm_and_si128(t1, kFE);  // set lsb of each byte to zero
   const __m128i t3 = _mm_srli_epi16(t2, 1);   // abs(p1 - q1) / 2
 
@@ -360,7 +360,7 @@
                                        __m128i* const q0, __m128i* const q1,
                                        int thresh) {
   __m128i a, mask;
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  const __m128i sign_bit = _mm_set1_epi8((char)0x80);
   // convert p1/q1 to int8_t (for GetBaseDelta_SSE2)
   const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
   const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
@@ -380,7 +380,7 @@
                                        const __m128i* const mask,
                                        int hev_thresh) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  const __m128i sign_bit = _mm_set1_epi8((char)0x80);
   const __m128i k64 = _mm_set1_epi8(64);
   const __m128i k3 = _mm_set1_epi8(3);
   const __m128i k4 = _mm_set1_epi8(4);
@@ -427,7 +427,7 @@
                                        const __m128i* const mask,
                                        int hev_thresh) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  const __m128i sign_bit = _mm_set1_epi8((char)0x80);
   __m128i a, not_hev;
 
   // compute hev mask
@@ -477,11 +477,11 @@
   // A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
   // A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
   const __m128i A0 = _mm_set_epi32(
-      WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
-      WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
+      WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]),
+      WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride]));
   const __m128i A1 = _mm_set_epi32(
-      WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
-      WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
+      WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]),
+      WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride]));
 
   // B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
   // B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
@@ -540,7 +540,7 @@
                                       uint8_t* dst, int stride) {
   int i;
   for (i = 0; i < 4; ++i, dst += stride) {
-    WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
+    WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x));
     *x = _mm_srli_si128(*x, 4);
   }
 }
@@ -908,10 +908,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
   const __m128i b = _mm_subs_epu8(a, lsb);
   const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
-  const uint32_t vals = _mm_cvtsi128_si32(avg);
+  const int vals = _mm_cvtsi128_si32(avg);
   int i;
   for (i = 0; i < 4; ++i) {
-    WebPUint32ToMem(dst + i * BPS, vals);
+    WebPInt32ToMem(dst + i * BPS, vals);
   }
 }
 
@@ -925,10 +925,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 static void VR4_SSE2(uint8_t* dst) {   // Vertical-Right
@@ -941,15 +941,15 @@
   const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
   const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
   const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
-  const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
+  const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0);
   const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
 
   // these two are hard to implement in SSE2, so we keep the C-version:
   DST(0, 2) = AVG3(J, I, X);
@@ -970,11 +970,12 @@
   const __m128i abbc = _mm_or_si128(ab, bc);
   const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
   const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
-  const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+  const uint32_t extra_out =
+      (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
 
   // these two are hard to get and irregular
   DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -990,7 +991,7 @@
   const uint32_t K = dst[-1 + 2 * BPS];
   const uint32_t L = dst[-1 + 3 * BPS];
   const __m128i LKJI_____ =
-      _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+      _mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24)));
   const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
   const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
   const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
@@ -998,10 +999,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 #undef DST
@@ -1015,13 +1016,13 @@
   const __m128i zero = _mm_setzero_si128();
   int y;
   if (size == 4) {
-    const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+    const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
     const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
     for (y = 0; y < 4; ++y, dst += BPS) {
       const int val = dst[-1] - top[-1];
       const __m128i base = _mm_set1_epi16(val);
       const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
-      WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+      WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
     }
   } else if (size == 8) {
     const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
@@ -1062,7 +1063,7 @@
 static void HE16_SSE2(uint8_t* dst) {     // horizontal
   int j;
   for (j = 16; j > 0; --j) {
-    const __m128i values = _mm_set1_epi8(dst[-1]);
+    const __m128i values = _mm_set1_epi8((char)dst[-1]);
     _mm_storeu_si128((__m128i*)dst, values);
     dst += BPS;
   }
@@ -1070,7 +1071,7 @@
 
 static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 16; ++j) {
     _mm_storeu_si128((__m128i*)(dst + j * BPS), values);
   }
@@ -1130,7 +1131,7 @@
 // helper for chroma-DC predictions
 static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 8; ++j) {
     _mm_storel_epi64((__m128i*)(dst + j * BPS), values);
   }
diff --git a/third_party/libwebp/src/dsp/dec_sse41.c b/third_party/libwebp/src/dsp/dec_sse41.c
index 8f18506..08a3630 100644
--- a/third_party/libwebp/src/dsp/dec_sse41.c
+++ b/third_party/libwebp/src/dsp/dec_sse41.c
@@ -23,7 +23,7 @@
   int j;
   const __m128i kShuffle3 = _mm_set1_epi8(3);
   for (j = 16; j > 0; --j) {
-    const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
+    const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
     const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
     _mm_storeu_si128((__m128i*)dst, values);
     dst += BPS;
diff --git a/third_party/libwebp/src/dsp/dsp.h b/third_party/libwebp/src/dsp/dsp.h
index 7f9bb53..d2000b8 100644
--- a/third_party/libwebp/src/dsp/dsp.h
+++ b/third_party/libwebp/src/dsp/dsp.h
@@ -18,6 +18,7 @@
 #include "src/webp/config.h"
 #endif
 
+#include "src/dsp/cpu.h"
 #include "src/webp/types.h"
 
 #ifdef __cplusplus
@@ -27,214 +28,22 @@
 #define BPS 32   // this is the common stride for enc/dec
 
 //------------------------------------------------------------------------------
-// CPU detection
+// WEBP_RESTRICT
 
+// Declares a pointer with the restrict type qualifier if available.
+// This allows code to hint to the compiler that only this pointer references a
+// particular object or memory region within the scope of the block in which it
+// is declared. This may allow for improved optimizations due to the lack of
+// pointer aliasing. See also:
+// https://en.cppreference.com/w/c/language/restrict
 #if defined(__GNUC__)
-# define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
-# define LOCAL_GCC_PREREQ(maj, min) \
-    (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
+#define WEBP_RESTRICT __restrict__
+#elif defined(_MSC_VER)
+#define WEBP_RESTRICT __restrict
 #else
-# define LOCAL_GCC_VERSION 0
-# define LOCAL_GCC_PREREQ(maj, min) 0
+#define WEBP_RESTRICT
 #endif
 
-#if defined(__clang__)
-# define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
-# define LOCAL_CLANG_PREREQ(maj, min) \
-    (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
-#else
-# define LOCAL_CLANG_VERSION 0
-# define LOCAL_CLANG_PREREQ(maj, min) 0
-#endif
-
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
-// for now, none of the optimizations below are available in emscripten
-#if !defined(EMSCRIPTEN)
-
-#if defined(_MSC_VER) && _MSC_VER > 1310 && \
-    (defined(_M_X64) || defined(_M_IX86))
-#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
-    (defined(_M_X64) || defined(_M_IX86))
-#define WEBP_MSC_SSE41  // Visual C++ SSE4.1 targets
-#endif
-
-// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
-// files without intrinsics, allowing the corresponding Init() to be called.
-// Files containing intrinsics will need to be built targeting the instruction
-// set so should succeed on one of the earlier tests.
-#if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2)
-#define WEBP_USE_SSE2
-#endif
-
-#if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41)
-#define WEBP_USE_SSE41
-#endif
-
-#if defined(__AVX2__) || defined(WEBP_HAVE_AVX2)
-#define WEBP_USE_AVX2
-#endif
-
-// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
-// inline assembly would need to be modified for use with Native Client.
-#if (defined(__ARM_NEON__) || \
-     defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
-    !defined(__native_client__)
-#define WEBP_USE_NEON
-#endif
-
-#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
-    defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
-#define WEBP_ANDROID_NEON  // Android targets that may have NEON
-#define WEBP_USE_NEON
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
-#define WEBP_USE_NEON
-#define WEBP_USE_INTRINSICS
-#endif
-
-#if defined(__mips__) && !defined(__mips64) && \
-    defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
-#define WEBP_USE_MIPS32
-#if (__mips_isa_rev >= 2)
-#define WEBP_USE_MIPS32_R2
-#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
-#define WEBP_USE_MIPS_DSP_R2
-#endif
-#endif
-#endif
-
-#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
-#define WEBP_USE_MSA
-#endif
-
-#endif  /* EMSCRIPTEN */
-
-#ifndef WEBP_DSP_OMIT_C_CODE
-#define WEBP_DSP_OMIT_C_CODE 1
-#endif
-
-#if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE
-#define WEBP_NEON_OMIT_C_CODE 1
-#else
-#define WEBP_NEON_OMIT_C_CODE 0
-#endif
-
-#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
-#define WEBP_NEON_WORK_AROUND_GCC 1
-#else
-#define WEBP_NEON_WORK_AROUND_GCC 0
-#endif
-
-// This macro prevents thread_sanitizer from reporting known concurrent writes.
-#define WEBP_TSAN_IGNORE_FUNCTION
-#if defined(__has_feature)
-#if __has_feature(thread_sanitizer)
-#undef WEBP_TSAN_IGNORE_FUNCTION
-#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
-#endif
-#endif
-
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
-#if !defined(STARBOARD)
-// TODO: If not including this is a problem on a Starboard platform, then
-//       we should implement this functionality with Starboard threading
-//       primitives instead.
-#include <pthread.h>  // NOLINT
-#endif
-
-#define WEBP_DSP_INIT(func) do {                                    \
-  static volatile VP8CPUInfo func ## _last_cpuinfo_used =           \
-      (VP8CPUInfo)&func ## _last_cpuinfo_used;                      \
-  static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \
-  if (pthread_mutex_lock(&func ## _lock)) break;                    \
-  if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func();          \
-  func ## _last_cpuinfo_used = VP8GetCPUInfo;                       \
-  (void)pthread_mutex_unlock(&func ## _lock);                       \
-} while (0)
-#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
-#define WEBP_DSP_INIT(func) do {                                    \
-  static volatile VP8CPUInfo func ## _last_cpuinfo_used =           \
-      (VP8CPUInfo)&func ## _last_cpuinfo_used;                      \
-  if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break;           \
-  func();                                                           \
-  func ## _last_cpuinfo_used = VP8GetCPUInfo;                       \
-} while (0)
-#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
-
-// Defines an Init + helper function that control multiple initialization of
-// function pointers / tables.
-/* Usage:
-   WEBP_DSP_INIT_FUNC(InitFunc) {
-     ...function body
-   }
-*/
-#define WEBP_DSP_INIT_FUNC(name)                             \
-  static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \
-  WEBP_TSAN_IGNORE_FUNCTION void name(void) {                \
-    WEBP_DSP_INIT(name ## _body);                            \
-  }                                                          \
-  static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void)
-
-#define WEBP_UBSAN_IGNORE_UNDEF
-#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
-#if defined(__clang__) && defined(__has_attribute)
-#if __has_attribute(no_sanitize)
-// This macro prevents the undefined behavior sanitizer from reporting
-// failures. This is only meant to silence unaligned loads on platforms that
-// are known to support them.
-#undef WEBP_UBSAN_IGNORE_UNDEF
-#define WEBP_UBSAN_IGNORE_UNDEF \
-  __attribute__((no_sanitize("undefined")))
-
-// This macro prevents the undefined behavior sanitizer from reporting
-// failures related to unsigned integer overflows. This is only meant to
-// silence cases where this well defined behavior is expected.
-#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
-#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
-  __attribute__((no_sanitize("unsigned-integer-overflow")))
-#endif
-#endif
-
-// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
-#if !defined(WEBP_SWAP_16BIT_CSP)
-#define WEBP_SWAP_16BIT_CSP 0
-#endif
-
-// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
-#if defined(STARBOARD)
-#if SB_IS(BIG_ENDIAN)
-#define WORDS_BIGENDIAN
-#endif
-#else
-#if !defined(WORDS_BIGENDIAN) && \
-    (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
-     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
-#define WORDS_BIGENDIAN
-#endif
-#endif  // defined(STARBOARD)
-
-typedef enum {
-  kSSE2,
-  kSSE3,
-  kSlowSSSE3,  // special feature for slow SSSE3 architectures
-  kSSE4_1,
-  kAVX,
-  kAVX2,
-  kNEON,
-  kMIPS32,
-  kMIPSdspR2,
-  kMSA
-} CPUFeature;
-// returns true if the CPU supports the feature.
-typedef int (*VP8CPUInfo)(CPUFeature feature);
-WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 
 //------------------------------------------------------------------------------
 // Init stub generator
@@ -261,9 +70,9 @@
 extern VP8WHT VP8FTransformWHT;
 // Predictions
 // *dst is the destination block. *top and *left can be NULL.
-typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
+typedef void (*VP8IntraPreds)(uint8_t* dst, const uint8_t* left,
                               const uint8_t* top);
-typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
+typedef void (*VP8Intra4Preds)(uint8_t* dst, const uint8_t* top);
 extern VP8Intra4Preds VP8EncPredLuma4;
 extern VP8IntraPreds VP8EncPredLuma16;
 extern VP8IntraPreds VP8EncPredChroma8;
@@ -523,15 +332,6 @@
 extern void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
                                     uint8_t* u, uint8_t* v, int width);
 
-// utilities for accurate RGB->YUV conversion
-extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
-                                       uint16_t* dst, int len);
-extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
-                                     int16_t* dst, int len);
-extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B,
-                                     int len,
-                                     const uint16_t* best_y, uint16_t* out);
-
 // Must be called before using the above.
 void WebPInitConvertARGBToYUV(void);
 
@@ -587,26 +387,29 @@
 
 // Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
 // Returns true if alpha[] plane has non-trivial values different from 0xff.
-extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride,
-                                int width, int height,
-                                uint8_t* dst, int dst_stride);
+extern int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT alpha,
+                                int alpha_stride, int width, int height,
+                                uint8_t* WEBP_RESTRICT dst, int dst_stride);
 
 // Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
 // A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
-extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride,
-                                        int width, int height,
-                                        uint32_t* dst, int dst_stride);
+extern void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT alpha,
+                                        int alpha_stride, int width, int height,
+                                        uint32_t* WEBP_RESTRICT dst,
+                                        int dst_stride);
 
 // Extract the alpha values from 32b values in argb[] and pack them into alpha[]
 // (this is the opposite of WebPDispatchAlpha).
 // Returns true if there's only trivial 0xff alpha values.
-extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride,
-                               int width, int height,
-                               uint8_t* alpha, int alpha_stride);
+extern int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT argb,
+                               int argb_stride, int width, int height,
+                               uint8_t* WEBP_RESTRICT alpha,
+                               int alpha_stride);
 
 // Extract the green values from 32b values in argb[] and pack them into alpha[]
 // (this is the opposite of WebPDispatchAlphaToGreen).
-extern void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
+extern void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
+                                uint8_t* WEBP_RESTRICT alpha, int size);
 
 // Pre-Multiply operation transforms x into x * A / 255  (where x=Y,R,G or B).
 // Un-Multiply operation transforms x into x * 255 / A.
@@ -619,34 +422,42 @@
                       int inverse);
 
 // Same for a row of single values, with side alpha values.
-extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+extern void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
+                           const uint8_t* WEBP_RESTRICT const alpha,
                            int width, int inverse);
 
 // Same a WebPMultRow(), but for several 'num_rows' rows.
-void WebPMultRows(uint8_t* ptr, int stride,
-                  const uint8_t* alpha, int alpha_stride,
+void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
+                  const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
                   int width, int num_rows, int inverse);
 
 // Plain-C versions, used as fallback by some implementations.
-void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
+void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
+                   const uint8_t* WEBP_RESTRICT const alpha,
                    int width, int inverse);
 void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
 
 #ifdef WORDS_BIGENDIAN
 // ARGB packing function: a/r/g/b input is rgba or bgra order.
-extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r,
-                            const uint8_t* g, const uint8_t* b, int len,
-                            uint32_t* out);
+extern void (*WebPPackARGB)(const uint8_t* WEBP_RESTRICT a,
+                            const uint8_t* WEBP_RESTRICT r,
+                            const uint8_t* WEBP_RESTRICT g,
+                            const uint8_t* WEBP_RESTRICT b,
+                            int len, uint32_t* WEBP_RESTRICT out);
 #endif
 
 // RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
-extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
-                           int len, int step, uint32_t* out);
+extern void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
+                           const uint8_t* WEBP_RESTRICT g,
+                           const uint8_t* WEBP_RESTRICT b,
+                           int len, int step, uint32_t* WEBP_RESTRICT out);
 
 // This function returns true if src[i] contains a value different from 0xff.
 extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
 // This function returns true if src[4*i] contains a value different from 0xff.
 extern int (*WebPHasAlpha32b)(const uint8_t* src, int length);
+// replaces transparent values in src[] by 'color'.
+extern void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
 
 // To be called first before using the above.
 void WebPInitAlphaProcessing(void);
@@ -690,4 +501,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DSP_DSP_H_ */
+#endif  // WEBP_DSP_DSP_H_
diff --git a/third_party/libwebp/src/dsp/enc.c b/third_party/libwebp/src/dsp/enc.c
index 4775258..b492454 100644
--- a/third_party/libwebp/src/dsp/enc.c
+++ b/third_party/libwebp/src/dsp/enc.c
@@ -738,9 +738,9 @@
 VP8BlockCopy VP8Copy4x4;
 VP8BlockCopy VP8Copy16x8;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8EncDspInitSSE2(void);
 extern void VP8EncDspInitSSE41(void);
-extern void VP8EncDspInitAVX2(void);
 extern void VP8EncDspInitNEON(void);
 extern void VP8EncDspInitMIPS32(void);
 extern void VP8EncDspInitMIPSdspR2(void);
@@ -780,21 +780,16 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8EncDspInitSSE2();
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
       if (VP8GetCPUInfo(kSSE4_1)) {
         VP8EncDspInitSSE41();
       }
 #endif
     }
 #endif
-#if defined(WEBP_USE_AVX2)
-    if (VP8GetCPUInfo(kAVX2)) {
-      VP8EncDspInitAVX2();
-    }
-#endif
 #if defined(WEBP_USE_MIPS32)
     if (VP8GetCPUInfo(kMIPS32)) {
       VP8EncDspInitMIPS32();
@@ -812,7 +807,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     VP8EncDspInitNEON();
diff --git a/third_party/libwebp/src/dsp/enc_avx2.c b/third_party/libwebp/src/dsp/enc_avx2.c
deleted file mode 100644
index 8bc5798..0000000
--- a/third_party/libwebp/src/dsp/enc_avx2.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the COPYING file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS. All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-// -----------------------------------------------------------------------------
-//
-// AVX2 version of speed-critical encoding functions.
-
-#include "src/dsp/dsp.h"
-
-#if defined(WEBP_USE_AVX2)
-
-#endif  // WEBP_USE_AVX2
-
-//------------------------------------------------------------------------------
-// Entry point
-
-WEBP_DSP_INIT_STUB(VP8EncDspInitAVX2)
diff --git a/third_party/libwebp/src/dsp/enc_neon.c b/third_party/libwebp/src/dsp/enc_neon.c
index 43bf124..7148003 100644
--- a/third_party/libwebp/src/dsp/enc_neon.c
+++ b/third_party/libwebp/src/dsp/enc_neon.c
@@ -9,7 +9,7 @@
 //
 // ARM NEON version of speed-critical encoding functions.
 //
-// adapted from libvpx (http://www.webmproject.org/code/)
+// adapted from libvpx (https://www.webmproject.org/code/)
 
 #include "src/dsp/dsp.h"
 
@@ -764,9 +764,14 @@
 
 // Horizontal sum of all four uint32_t values in 'sum'.
 static int SumToInt_NEON(uint32x4_t sum) {
+#if WEBP_AARCH64
+  return (int)vaddvq_u32(sum);
+#else
   const uint64x2_t sum2 = vpaddlq_u32(sum);
-  const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1);
-  return (int)sum3;
+  const uint32x2_t sum3 = vadd_u32(vreinterpret_u32_u64(vget_low_u64(sum2)),
+                                   vreinterpret_u32_u64(vget_high_u64(sum2)));
+  return (int)vget_lane_u32(sum3, 0);
+#endif
 }
 
 static int SSE16x16_NEON(const uint8_t* a, const uint8_t* b) {
@@ -860,7 +865,7 @@
   uint8x8x4_t shuffles;
   // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
   // non-standard versions there.
-#if defined(__APPLE__) && defined(__aarch64__) && \
+#if defined(__APPLE__) && WEBP_AARCH64 && \
     defined(__apple_build_version__) && (__apple_build_version__< 6020037)
   uint8x16x2_t all_out;
   INIT_VECTOR2(all_out, vreinterpretq_u8_s16(out0), vreinterpretq_u8_s16(out1));
diff --git a/third_party/libwebp/src/dsp/enc_sse2.c b/third_party/libwebp/src/dsp/enc_sse2.c
index eead98e..463609a 100644
--- a/third_party/libwebp/src/dsp/enc_sse2.c
+++ b/third_party/libwebp/src/dsp/enc_sse2.c
@@ -31,9 +31,160 @@
 //------------------------------------------------------------------------------
 // Transforms (Paragraph 14.4)
 
-// Does one or two inverse transforms.
-static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
-                            int do_two) {
+// Does one inverse transform.
+static void ITransform_One_SSE2(const uint8_t* ref, const int16_t* in,
+                                uint8_t* dst) {
+  // This implementation makes use of 16-bit fixed point versions of two
+  // multiply constants:
+  //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
+  //    K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
+  //
+  // To be able to use signed 16-bit integers, we use the following trick to
+  // have constants within range:
+  // - Associated constants are obtained by subtracting the 16-bit fixed point
+  //   version of one:
+  //      k = K - (1 << 16)  =>  K = k + (1 << 16)
+  //      K1 = 85267  =>  k1 =  20091
+  //      K2 = 35468  =>  k2 = -30068
+  // - The multiplication of a variable by a constant become the sum of the
+  //   variable and the multiplication of that variable by the associated
+  //   constant:
+  //      (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
+  const __m128i k1k2 = _mm_set_epi16(-30068, -30068, -30068, -30068,
+                                     20091, 20091, 20091, 20091);
+  const __m128i k2k1 = _mm_set_epi16(20091, 20091, 20091, 20091,
+                                     -30068, -30068, -30068, -30068);
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i zero_four = _mm_set_epi16(0, 0, 0, 0, 4, 4, 4, 4);
+  __m128i T01, T23;
+
+  // Load and concatenate the transform coefficients.
+  const __m128i in01 = _mm_loadu_si128((const __m128i*)&in[0]);
+  const __m128i in23 = _mm_loadu_si128((const __m128i*)&in[8]);
+  // a00 a10 a20 a30   a01 a11 a21 a31
+  // a02 a12 a22 a32   a03 a13 a23 a33
+
+  // Vertical pass and subsequent transpose.
+  {
+    const __m128i in1 = _mm_unpackhi_epi64(in01, in01);
+    const __m128i in3 = _mm_unpackhi_epi64(in23, in23);
+
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
+    // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
+    const __m128i a_d3 = _mm_add_epi16(in01, in23);
+    const __m128i b_c3 = _mm_sub_epi16(in01, in23);
+    const __m128i c1d1 = _mm_mulhi_epi16(in1, k2k1);
+    const __m128i c2d2 = _mm_mulhi_epi16(in3, k1k2);
+    const __m128i c3 = _mm_unpackhi_epi64(b_c3, b_c3);
+    const __m128i c4 = _mm_sub_epi16(c1d1, c2d2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    const __m128i d4u = _mm_add_epi16(c1d1, c2d2);
+    const __m128i du = _mm_add_epi16(a_d3, d4u);
+    const __m128i d = _mm_unpackhi_epi64(du, du);
+
+    // Second pass.
+    const __m128i comb_ab = _mm_unpacklo_epi64(a_d3, b_c3);
+    const __m128i comb_dc = _mm_unpacklo_epi64(d, c);
+
+    const __m128i tmp01 = _mm_add_epi16(comb_ab, comb_dc);
+    const __m128i tmp32 = _mm_sub_epi16(comb_ab, comb_dc);
+    const __m128i tmp23 = _mm_shuffle_epi32(tmp32, _MM_SHUFFLE(1, 0, 3, 2));
+
+    const __m128i transpose_0 = _mm_unpacklo_epi16(tmp01, tmp23);
+    const __m128i transpose_1 = _mm_unpackhi_epi16(tmp01, tmp23);
+    // a00 a20 a01 a21   a02 a22 a03 a23
+    // a10 a30 a11 a31   a12 a32 a13 a33
+
+    T01 = _mm_unpacklo_epi16(transpose_0, transpose_1);
+    T23 = _mm_unpackhi_epi16(transpose_0, transpose_1);
+    // a00 a10 a20 a30   a01 a11 a21 a31
+    // a02 a12 a22 a32   a03 a13 a23 a33
+  }
+
+  // Horizontal pass and subsequent transpose.
+  {
+    const __m128i T1 = _mm_unpackhi_epi64(T01, T01);
+    const __m128i T3 = _mm_unpackhi_epi64(T23, T23);
+
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    const __m128i dc = _mm_add_epi16(T01, zero_four);
+
+    // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
+    // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
+    const __m128i a_d3 = _mm_add_epi16(dc, T23);
+    const __m128i b_c3 = _mm_sub_epi16(dc, T23);
+    const __m128i c1d1 = _mm_mulhi_epi16(T1, k2k1);
+    const __m128i c2d2 = _mm_mulhi_epi16(T3, k1k2);
+    const __m128i c3 = _mm_unpackhi_epi64(b_c3, b_c3);
+    const __m128i c4 = _mm_sub_epi16(c1d1, c2d2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    const __m128i d4u = _mm_add_epi16(c1d1, c2d2);
+    const __m128i du = _mm_add_epi16(a_d3, d4u);
+    const __m128i d = _mm_unpackhi_epi64(du, du);
+
+    // Second pass.
+    const __m128i comb_ab = _mm_unpacklo_epi64(a_d3, b_c3);
+    const __m128i comb_dc = _mm_unpacklo_epi64(d, c);
+
+    const __m128i tmp01 = _mm_add_epi16(comb_ab, comb_dc);
+    const __m128i tmp32 = _mm_sub_epi16(comb_ab, comb_dc);
+    const __m128i tmp23 = _mm_shuffle_epi32(tmp32, _MM_SHUFFLE(1, 0, 3, 2));
+
+    const __m128i shifted01 = _mm_srai_epi16(tmp01, 3);
+    const __m128i shifted23 = _mm_srai_epi16(tmp23, 3);
+    // a00 a01 a02 a03   a10 a11 a12 a13
+    // a20 a21 a22 a23   a30 a31 a32 a33
+
+    const __m128i transpose_0 = _mm_unpacklo_epi16(shifted01, shifted23);
+    const __m128i transpose_1 = _mm_unpackhi_epi16(shifted01, shifted23);
+    // a00 a20 a01 a21   a02 a22 a03 a23
+    // a10 a30 a11 a31   a12 a32 a13 a33
+
+    T01 = _mm_unpacklo_epi16(transpose_0, transpose_1);
+    T23 = _mm_unpackhi_epi16(transpose_0, transpose_1);
+    // a00 a10 a20 a30   a01 a11 a21 a31
+    // a02 a12 a22 a32   a03 a13 a23 a33
+  }
+
+  // Add inverse transform to 'ref' and store.
+  {
+    // Load the reference(s).
+    __m128i ref01, ref23, ref0123;
+    int32_t buf[4];
+
+    // Load four bytes/pixels per line.
+    const __m128i ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS]));
+    const __m128i ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS]));
+    const __m128i ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS]));
+    const __m128i ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS]));
+    ref01 = _mm_unpacklo_epi32(ref0, ref1);
+    ref23 = _mm_unpacklo_epi32(ref2, ref3);
+
+    // Convert to 16b.
+    ref01 = _mm_unpacklo_epi8(ref01, zero);
+    ref23 = _mm_unpacklo_epi8(ref23, zero);
+    // Add the inverse transform(s).
+    ref01 = _mm_add_epi16(ref01, T01);
+    ref23 = _mm_add_epi16(ref23, T23);
+    // Unsigned saturate to 8b.
+    ref0123 = _mm_packus_epi16(ref01, ref23);
+
+    _mm_storeu_si128((__m128i *)buf, ref0123);
+
+    // Store four bytes/pixels per line.
+    WebPInt32ToMem(&dst[0 * BPS], buf[0]);
+    WebPInt32ToMem(&dst[1 * BPS], buf[1]);
+    WebPInt32ToMem(&dst[2 * BPS], buf[2]);
+    WebPInt32ToMem(&dst[3 * BPS], buf[3]);
+  }
+}
+
+// Does two inverse transforms.
+static void ITransform_Two_SSE2(const uint8_t* ref, const int16_t* in,
+                                uint8_t* dst) {
   // This implementation makes use of 16-bit fixed point versions of two
   // multiply constants:
   //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
@@ -55,33 +206,21 @@
   __m128i T0, T1, T2, T3;
 
   // Load and concatenate the transform coefficients (we'll do two inverse
-  // transforms in parallel). In the case of only one inverse transform, the
-  // second half of the vectors will just contain random value we'll never
-  // use nor store.
+  // transforms in parallel).
   __m128i in0, in1, in2, in3;
   {
-    in0 = _mm_loadl_epi64((const __m128i*)&in[0]);
-    in1 = _mm_loadl_epi64((const __m128i*)&in[4]);
-    in2 = _mm_loadl_epi64((const __m128i*)&in[8]);
-    in3 = _mm_loadl_epi64((const __m128i*)&in[12]);
-    // a00 a10 a20 a30   x x x x
-    // a01 a11 a21 a31   x x x x
-    // a02 a12 a22 a32   x x x x
-    // a03 a13 a23 a33   x x x x
-    if (do_two) {
-      const __m128i inB0 = _mm_loadl_epi64((const __m128i*)&in[16]);
-      const __m128i inB1 = _mm_loadl_epi64((const __m128i*)&in[20]);
-      const __m128i inB2 = _mm_loadl_epi64((const __m128i*)&in[24]);
-      const __m128i inB3 = _mm_loadl_epi64((const __m128i*)&in[28]);
-      in0 = _mm_unpacklo_epi64(in0, inB0);
-      in1 = _mm_unpacklo_epi64(in1, inB1);
-      in2 = _mm_unpacklo_epi64(in2, inB2);
-      in3 = _mm_unpacklo_epi64(in3, inB3);
-      // a00 a10 a20 a30   b00 b10 b20 b30
-      // a01 a11 a21 a31   b01 b11 b21 b31
-      // a02 a12 a22 a32   b02 b12 b22 b32
-      // a03 a13 a23 a33   b03 b13 b23 b33
-    }
+    const __m128i tmp0 = _mm_loadu_si128((const __m128i*)&in[0]);
+    const __m128i tmp1 = _mm_loadu_si128((const __m128i*)&in[8]);
+    const __m128i tmp2 = _mm_loadu_si128((const __m128i*)&in[16]);
+    const __m128i tmp3 = _mm_loadu_si128((const __m128i*)&in[24]);
+    in0 = _mm_unpacklo_epi64(tmp0, tmp2);
+    in1 = _mm_unpackhi_epi64(tmp0, tmp2);
+    in2 = _mm_unpacklo_epi64(tmp1, tmp3);
+    in3 = _mm_unpackhi_epi64(tmp1, tmp3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
   }
 
   // Vertical pass and subsequent transpose.
@@ -154,19 +293,11 @@
     const __m128i zero = _mm_setzero_si128();
     // Load the reference(s).
     __m128i ref0, ref1, ref2, ref3;
-    if (do_two) {
-      // Load eight bytes/pixels per line.
-      ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
-      ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
-      ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
-      ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
-    } else {
-      // Load four bytes/pixels per line.
-      ref0 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[0 * BPS]));
-      ref1 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[1 * BPS]));
-      ref2 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[2 * BPS]));
-      ref3 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[3 * BPS]));
-    }
+    // Load eight bytes/pixels per line.
+    ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
+    ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
+    ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
+    ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
     // Convert to 16b.
     ref0 = _mm_unpacklo_epi8(ref0, zero);
     ref1 = _mm_unpacklo_epi8(ref1, zero);
@@ -182,20 +313,21 @@
     ref1 = _mm_packus_epi16(ref1, ref1);
     ref2 = _mm_packus_epi16(ref2, ref2);
     ref3 = _mm_packus_epi16(ref3, ref3);
-    // Store the results.
-    if (do_two) {
-      // Store eight bytes/pixels per line.
-      _mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
-      _mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
-      _mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
-      _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
-    } else {
-      // Store four bytes/pixels per line.
-      WebPUint32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
-      WebPUint32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
-      WebPUint32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
-      WebPUint32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
-    }
+    // Store eight bytes/pixels per line.
+    _mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
+    _mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
+    _mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
+    _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
+  }
+}
+
+// Does one or two inverse transforms.
+static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+                            int do_two) {
+  if (do_two) {
+    ITransform_Two_SSE2(ref, in, dst);
+  } else {
+    ITransform_One_SSE2(ref, in, dst);
   }
 }
 
@@ -487,7 +619,7 @@
 // helper for chroma-DC predictions
 static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 8; ++j) {
     _mm_storel_epi64((__m128i*)(dst + j * BPS), values);
   }
@@ -495,7 +627,7 @@
 
 static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 16; ++j) {
     _mm_store_si128((__m128i*)(dst + j * BPS), values);
   }
@@ -546,7 +678,7 @@
 static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) {
   int j;
   for (j = 0; j < 8; ++j) {
-    const __m128i values = _mm_set1_epi8(left[j]);
+    const __m128i values = _mm_set1_epi8((char)left[j]);
     _mm_storel_epi64((__m128i*)dst, values);
     dst += BPS;
   }
@@ -555,7 +687,7 @@
 static WEBP_INLINE void HE16_SSE2(uint8_t* dst, const uint8_t* left) {
   int j;
   for (j = 0; j < 16; ++j) {
-    const __m128i values = _mm_set1_epi8(left[j]);
+    const __m128i values = _mm_set1_epi8((char)left[j]);
     _mm_store_si128((__m128i*)dst, values);
     dst += BPS;
   }
@@ -728,10 +860,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
   const __m128i b = _mm_subs_epu8(a, lsb);
   const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
-  const uint32_t vals = _mm_cvtsi128_si32(avg);
+  const int vals = _mm_cvtsi128_si32(avg);
   int i;
   for (i = 0; i < 4; ++i) {
-    WebPUint32ToMem(dst + i * BPS, vals);
+    WebPInt32ToMem(dst + i * BPS, vals);
   }
 }
 
@@ -766,10 +898,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
@@ -783,15 +915,15 @@
   const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
   const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
   const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
-  const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
+  const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0);
   const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
 
   // these two are hard to implement in SSE2, so we keep the C-version:
   DST(0, 2) = AVG3(J, I, X);
@@ -813,11 +945,12 @@
   const __m128i abbc = _mm_or_si128(ab, bc);
   const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
   const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
-  const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+  const uint32_t extra_out =
+      (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
 
   // these two are hard to get and irregular
   DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -835,10 +968,10 @@
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 static WEBP_INLINE void HU4_SSE2(uint8_t* dst, const uint8_t* top) {
@@ -881,14 +1014,14 @@
 
 static WEBP_INLINE void TM4_SSE2(uint8_t* dst, const uint8_t* top) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+  const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
   const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
   int y;
   for (y = 0; y < 4; ++y, dst += BPS) {
     const int val = top[-2 - y] - top[-1];
     const __m128i base = _mm_set1_epi16(val);
     const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
-    WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+    WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
   }
 }
 
diff --git a/third_party/libwebp/src/dsp/filters.c b/third_party/libwebp/src/dsp/filters.c
index 069a22e..85eee50 100644
--- a/third_party/libwebp/src/dsp/filters.c
+++ b/third_party/libwebp/src/dsp/filters.c
@@ -33,9 +33,9 @@
                                       uint8_t* dst, int length, int inverse) {
   int i;
   if (inverse) {
-    for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
+    for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] + pred[i]);
   } else {
-    for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
+    for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] - pred[i]);
   }
 }
 
@@ -155,7 +155,7 @@
       const int pred = GradientPredictor_C(preds[w - 1],
                                            preds[w - stride],
                                            preds[w - stride - 1]);
-      out[w] = in[w] + (inverse ? pred : -pred);
+      out[w] = (uint8_t)(in[w] + (inverse ? pred : -pred));
     }
     ++row;
     preds += stride;
@@ -194,7 +194,7 @@
   uint8_t pred = (prev == NULL) ? 0 : prev[0];
   int i;
   for (i = 0; i < width; ++i) {
-    out[i] = pred + in[i];
+    out[i] = (uint8_t)(pred + in[i]);
     pred = out[i];
   }
 }
@@ -206,7 +206,7 @@
     HorizontalUnfilter_C(NULL, in, out, width);
   } else {
     int i;
-    for (i = 0; i < width; ++i) out[i] = prev[i] + in[i];
+    for (i = 0; i < width; ++i) out[i] = (uint8_t)(prev[i] + in[i]);
   }
 }
 #endif  // !WEBP_NEON_OMIT_C_CODE
@@ -220,7 +220,7 @@
     int i;
     for (i = 0; i < width; ++i) {
       top = prev[i];  // need to read this first, in case prev==out
-      left = in[i] + GradientPredictor_C(left, top, top_left);
+      left = (uint8_t)(in[i] + GradientPredictor_C(left, top, top_left));
       top_left = top;
       out[i] = left;
     }
@@ -233,6 +233,7 @@
 WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
 WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8FiltersInitMIPSdspR2(void);
 extern void VP8FiltersInitMSA(void);
 extern void VP8FiltersInitNEON(void);
@@ -254,7 +255,7 @@
 #endif
 
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8FiltersInitSSE2();
     }
@@ -271,7 +272,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     VP8FiltersInitNEON();
diff --git a/third_party/libwebp/src/dsp/filters_sse2.c b/third_party/libwebp/src/dsp/filters_sse2.c
index 5a18895..5c33ec1 100644
--- a/third_party/libwebp/src/dsp/filters_sse2.c
+++ b/third_party/libwebp/src/dsp/filters_sse2.c
@@ -163,7 +163,8 @@
     _mm_storel_epi64((__m128i*)(out + i), H);
   }
   for (; i < length; ++i) {
-    out[i] = row[i] - GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
+    const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
+    out[i] = (uint8_t)(row[i] - delta);
   }
 }
 
@@ -188,7 +189,7 @@
 
   // Filter line-by-line.
   while (row < last_row) {
-    out[0] = in[0] - in[-stride];
+    out[0] = (uint8_t)(in[0] - in[-stride]);
     GradientPredictDirect_SSE2(in + 1, in + 1 - stride, out + 1, width - 1);
     ++row;
     in += stride;
@@ -223,7 +224,7 @@
                                     uint8_t* out, int width) {
   int i;
   __m128i last;
-  out[0] = in[0] + (prev == NULL ? 0 : prev[0]);
+  out[0] = (uint8_t)(in[0] + (prev == NULL ? 0 : prev[0]));
   if (width <= 1) return;
   last = _mm_set_epi32(0, 0, 0, out[0]);
   for (i = 1; i + 8 <= width; i += 8) {
@@ -238,7 +239,7 @@
     _mm_storel_epi64((__m128i*)(out + i), A7);
     last = _mm_srli_epi64(A7, 56);
   }
-  for (; i < width; ++i) out[i] = in[i] + out[i - 1];
+  for (; i < width; ++i) out[i] = (uint8_t)(in[i] + out[i - 1]);
 }
 
 static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
@@ -259,7 +260,7 @@
       _mm_storeu_si128((__m128i*)&out[i +  0], C0);
       _mm_storeu_si128((__m128i*)&out[i + 16], C1);
     }
-    for (; i < width; ++i) out[i] = in[i] + prev[i];
+    for (; i < width; ++i) out[i] = (uint8_t)(in[i] + prev[i]);
   }
 }
 
@@ -296,7 +297,8 @@
       _mm_storel_epi64((__m128i*)&row[i], out);
     }
     for (; i < length; ++i) {
-      row[i] = in[i] + GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
+      const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
+      row[i] = (uint8_t)(in[i] + delta);
     }
   }
 }
@@ -306,7 +308,7 @@
   if (prev == NULL) {
     HorizontalUnfilter_SSE2(NULL, in, out, width);
   } else {
-    out[0] = in[0] + prev[0];  // predict from above
+    out[0] = (uint8_t)(in[0] + prev[0]);  // predict from above
     GradientPredictInverse_SSE2(in + 1, prev + 1, out + 1, width - 1);
   }
 }
@@ -318,7 +320,12 @@
 
 WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) {
   WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_SSE2;
+#if defined(CHROMIUM)
+  // TODO(crbug.com/654974)
+  (void)VerticalUnfilter_SSE2;
+#else
   WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter_SSE2;
+#endif
   WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter_SSE2;
 
   WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_SSE2;
diff --git a/third_party/libwebp/src/dsp/lossless.c b/third_party/libwebp/src/dsp/lossless.c
index 2667935..7be697a 100644
--- a/third_party/libwebp/src/dsp/lossless.c
+++ b/third_party/libwebp/src/dsp/lossless.c
@@ -29,8 +29,6 @@
 #include "src/dsp/lossless.h"
 #include "src/dsp/lossless_common.h"
 
-#define MAX_DIFF_COST (1e30f)
-
 //------------------------------------------------------------------------------
 // Image transforms.
 
@@ -57,7 +55,7 @@
 }
 
 static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
-  return Clip255(a + b - c);
+  return Clip255((uint32_t)(a + b - c));
 }
 
 static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
@@ -74,7 +72,7 @@
 }
 
 static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
-  return Clip255(a + (a - b) / 2);
+  return Clip255((uint32_t)(a + (a - b) / 2));
 }
 
 static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
@@ -89,7 +87,7 @@
 
 // gcc <= 4.9 on ARM generates incorrect code in Select() when Sub3() is
 // inlined.
-#if defined(__arm__) && LOCAL_GCC_VERSION <= 0x409
+#if defined(__arm__) && defined(__GNUC__) && LOCAL_GCC_VERSION <= 0x409
 # define LOCAL_INLINE __attribute__ ((noinline))
 #else
 # define LOCAL_INLINE WEBP_INLINE
@@ -115,88 +113,107 @@
 //------------------------------------------------------------------------------
 // Predictors
 
-static uint32_t Predictor0_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor0_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   (void)top;
   (void)left;
   return ARGB_BLACK;
 }
-static uint32_t Predictor1_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor1_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   (void)top;
-  return left;
+  return *left;
 }
-static uint32_t Predictor2_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor2_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   (void)left;
   return top[0];
 }
-static uint32_t Predictor3_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor3_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   (void)left;
   return top[1];
 }
-static uint32_t Predictor4_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor4_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   (void)left;
   return top[-1];
 }
-static uint32_t Predictor5_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average3(left, top[0], top[1]);
+uint32_t VP8LPredictor5_C(const uint32_t* const left,
+                          const uint32_t* const top) {
+  const uint32_t pred = Average3(*left, top[0], top[1]);
   return pred;
 }
-static uint32_t Predictor6_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[-1]);
+uint32_t VP8LPredictor6_C(const uint32_t* const left,
+                          const uint32_t* const top) {
+  const uint32_t pred = Average2(*left, top[-1]);
   return pred;
 }
-static uint32_t Predictor7_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[0]);
+uint32_t VP8LPredictor7_C(const uint32_t* const left,
+                          const uint32_t* const top) {
+  const uint32_t pred = Average2(*left, top[0]);
   return pred;
 }
-static uint32_t Predictor8_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor8_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   const uint32_t pred = Average2(top[-1], top[0]);
   (void)left;
   return pred;
 }
-static uint32_t Predictor9_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor9_C(const uint32_t* const left,
+                          const uint32_t* const top) {
   const uint32_t pred = Average2(top[0], top[1]);
   (void)left;
   return pred;
 }
-static uint32_t Predictor10_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+uint32_t VP8LPredictor10_C(const uint32_t* const left,
+                           const uint32_t* const top) {
+  const uint32_t pred = Average4(*left, top[-1], top[0], top[1]);
   return pred;
 }
-static uint32_t Predictor11_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Select(top[0], left, top[-1]);
+uint32_t VP8LPredictor11_C(const uint32_t* const left,
+                           const uint32_t* const top) {
+  const uint32_t pred = Select(top[0], *left, top[-1]);
   return pred;
 }
-static uint32_t Predictor12_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+uint32_t VP8LPredictor12_C(const uint32_t* const left,
+                           const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractFull(*left, top[0], top[-1]);
   return pred;
 }
-static uint32_t Predictor13_C(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+uint32_t VP8LPredictor13_C(const uint32_t* const left,
+                           const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractHalf(*left, top[0], top[-1]);
   return pred;
 }
 
-GENERATE_PREDICTOR_ADD(Predictor0_C, PredictorAdd0_C)
+static void PredictorAdd0_C(const uint32_t* in, const uint32_t* upper,
+                            int num_pixels, uint32_t* out) {
+  int x;
+  (void)upper;
+  for (x = 0; x < num_pixels; ++x) out[x] = VP8LAddPixels(in[x], ARGB_BLACK);
+}
 static void PredictorAdd1_C(const uint32_t* in, const uint32_t* upper,
                             int num_pixels, uint32_t* out) {
   int i;
   uint32_t left = out[-1];
+  (void)upper;
   for (i = 0; i < num_pixels; ++i) {
     out[i] = left = VP8LAddPixels(in[i], left);
   }
-  (void)upper;
 }
-GENERATE_PREDICTOR_ADD(Predictor2_C, PredictorAdd2_C)
-GENERATE_PREDICTOR_ADD(Predictor3_C, PredictorAdd3_C)
-GENERATE_PREDICTOR_ADD(Predictor4_C, PredictorAdd4_C)
-GENERATE_PREDICTOR_ADD(Predictor5_C, PredictorAdd5_C)
-GENERATE_PREDICTOR_ADD(Predictor6_C, PredictorAdd6_C)
-GENERATE_PREDICTOR_ADD(Predictor7_C, PredictorAdd7_C)
-GENERATE_PREDICTOR_ADD(Predictor8_C, PredictorAdd8_C)
-GENERATE_PREDICTOR_ADD(Predictor9_C, PredictorAdd9_C)
-GENERATE_PREDICTOR_ADD(Predictor10_C, PredictorAdd10_C)
-GENERATE_PREDICTOR_ADD(Predictor11_C, PredictorAdd11_C)
-GENERATE_PREDICTOR_ADD(Predictor12_C, PredictorAdd12_C)
-GENERATE_PREDICTOR_ADD(Predictor13_C, PredictorAdd13_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor2_C, PredictorAdd2_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor3_C, PredictorAdd3_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor4_C, PredictorAdd4_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor5_C, PredictorAdd5_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor6_C, PredictorAdd6_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor7_C, PredictorAdd7_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor8_C, PredictorAdd8_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor9_C, PredictorAdd9_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor10_C, PredictorAdd10_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor11_C, PredictorAdd11_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor12_C, PredictorAdd12_C)
+GENERATE_PREDICTOR_ADD(VP8LPredictor13_C, PredictorAdd13_C)
 
 //------------------------------------------------------------------------------
 
@@ -278,14 +295,14 @@
   int i;
   for (i = 0; i < num_pixels; ++i) {
     const uint32_t argb = src[i];
-    const uint32_t green = argb >> 8;
+    const int8_t green = (int8_t)(argb >> 8);
     const uint32_t red = argb >> 16;
     int new_red = red & 0xff;
     int new_blue = argb & 0xff;
-    new_red += ColorTransformDelta(m->green_to_red_, green);
+    new_red += ColorTransformDelta((int8_t)m->green_to_red_, green);
     new_red &= 0xff;
-    new_blue += ColorTransformDelta(m->green_to_blue_, green);
-    new_blue += ColorTransformDelta(m->red_to_blue_, new_red);
+    new_blue += ColorTransformDelta((int8_t)m->green_to_blue_, green);
+    new_blue += ColorTransformDelta((int8_t)m->red_to_blue_, (int8_t)new_red);
     new_blue &= 0xff;
     dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
   }
@@ -384,7 +401,7 @@
   assert(row_start < row_end);
   assert(row_end <= transform->ysize_);
   switch (transform->type_) {
-    case SUBTRACT_GREEN:
+    case SUBTRACT_GREEN_TRANSFORM:
       VP8LAddGreenToBlueAndRed(in, (row_end - row_start) * width, out);
       break;
     case PREDICTOR_TRANSFORM:
@@ -565,7 +582,6 @@
 
 // exposed plain-C implementations
 VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
-VP8LPredictorFunc VP8LPredictors_C[16];
 
 VP8LTransformColorInverseFunc VP8LTransformColorInverse;
 
@@ -578,7 +594,9 @@
 VP8LMapARGBFunc VP8LMapColor32b;
 VP8LMapAlphaFunc VP8LMapColor8b;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8LDspInitSSE2(void);
+extern void VP8LDspInitSSE41(void);
 extern void VP8LDspInitNEON(void);
 extern void VP8LDspInitMIPSdspR2(void);
 extern void VP8LDspInitMSA(void);
@@ -603,8 +621,7 @@
 } while (0);
 
 WEBP_DSP_INIT_FUNC(VP8LDspInit) {
-  COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors)
-  COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C)
+  COPY_PREDICTOR_ARRAY(VP8LPredictor, VP8LPredictors)
   COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
   COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd_C)
 
@@ -626,9 +643,14 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8LDspInitSSE2();
+#if defined(WEBP_HAVE_SSE41)
+      if (VP8GetCPUInfo(kSSE4_1)) {
+        VP8LDspInitSSE41();
+      }
+#endif
     }
 #endif
 #if defined(WEBP_USE_MIPS_DSP_R2)
@@ -643,7 +665,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     VP8LDspInitNEON();
diff --git a/third_party/libwebp/src/dsp/lossless.h b/third_party/libwebp/src/dsp/lossless.h
index b2bbdfc..de60d95 100644
--- a/third_party/libwebp/src/dsp/lossless.h
+++ b/third_party/libwebp/src/dsp/lossless.h
@@ -28,9 +28,39 @@
 //------------------------------------------------------------------------------
 // Decoding
 
-typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
+typedef uint32_t (*VP8LPredictorFunc)(const uint32_t* const left,
+                                      const uint32_t* const top);
 extern VP8LPredictorFunc VP8LPredictors[16];
-extern VP8LPredictorFunc VP8LPredictors_C[16];
+
+uint32_t VP8LPredictor0_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor1_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor2_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor3_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor4_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor5_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor6_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor7_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor8_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor9_C(const uint32_t* const left,
+                          const uint32_t* const top);
+uint32_t VP8LPredictor10_C(const uint32_t* const left,
+                           const uint32_t* const top);
+uint32_t VP8LPredictor11_C(const uint32_t* const left,
+                           const uint32_t* const top);
+uint32_t VP8LPredictor12_C(const uint32_t* const left,
+                           const uint32_t* const top);
+uint32_t VP8LPredictor13_C(const uint32_t* const left,
+                           const uint32_t* const top);
+
 // These Add/Sub function expects upper[-1] and out[-1] to be readable.
 typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
                                         const uint32_t* upper, int num_pixels,
@@ -152,9 +182,9 @@
 // -----------------------------------------------------------------------------
 // Huffman-cost related functions.
 
-typedef double (*VP8LCostFunc)(const uint32_t* population, int length);
-typedef double (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
-                                       int length);
+typedef float (*VP8LCostFunc)(const uint32_t* population, int length);
+typedef float (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
+                                      int length);
 typedef float (*VP8LCombinedShannonEntropyFunc)(const int X[256],
                                                 const int Y[256]);
 
@@ -163,12 +193,12 @@
 extern VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
 
 typedef struct {        // small struct to hold counters
-  int counts[2];        // index: 0=zero steak, 1=non-zero streak
+  int counts[2];        // index: 0=zero streak, 1=non-zero streak
   int streaks[2][2];    // [zero/non-zero][streak<3 / streak>=3]
 } VP8LStreaks;
 
 typedef struct {            // small struct to hold bit entropy results
-  double entropy;           // entropy
+  float entropy;            // entropy
   uint32_t sum;             // sum of the population
   int nonzeros;             // number of non-zero elements in the population
   uint32_t max_val;         // maximum value in the population
@@ -194,10 +224,14 @@
 void VP8LBitsEntropyUnrefined(const uint32_t* const array, int n,
                               VP8LBitEntropy* const entropy);
 
-typedef void (*VP8LHistogramAddFunc)(const VP8LHistogram* const a,
-                                     const VP8LHistogram* const b,
-                                     VP8LHistogram* const out);
-extern VP8LHistogramAddFunc VP8LHistogramAdd;
+typedef void (*VP8LAddVectorFunc)(const uint32_t* a, const uint32_t* b,
+                                  uint32_t* out, int size);
+extern VP8LAddVectorFunc VP8LAddVector;
+typedef void (*VP8LAddVectorEqFunc)(const uint32_t* a, uint32_t* out, int size);
+extern VP8LAddVectorEqFunc VP8LAddVectorEq;
+void VP8LHistogramAdd(const VP8LHistogram* const a,
+                      const VP8LHistogram* const b,
+                      VP8LHistogram* const out);
 
 // -----------------------------------------------------------------------------
 // PrefixEncode()
diff --git a/third_party/libwebp/src/dsp/lossless_common.h b/third_party/libwebp/src/dsp/lossless_common.h
index a2648d1..616b40e 100644
--- a/third_party/libwebp/src/dsp/lossless_common.h
+++ b/third_party/libwebp/src/dsp/lossless_common.h
@@ -16,6 +16,10 @@
 #ifndef WEBP_DSP_LOSSLESS_COMMON_H_
 #define WEBP_DSP_LOSSLESS_COMMON_H_
 
+#if defined(STARBOARD)
+#include "starboard/client_porting/poem/assert_poem.h"
+#endif
+
 #include "src/webp/types.h"
 
 #include "src/utils/utils.h"
@@ -177,24 +181,13 @@
 static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
                           int num_pixels, uint32_t* out) {           \
   int x;                                                             \
+  assert(upper != NULL);                                             \
   for (x = 0; x < num_pixels; ++x) {                                 \
-    const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x);        \
+    const uint32_t pred = (PREDICTOR)(&out[x - 1], upper + x);       \
     out[x] = VP8LAddPixels(in[x], pred);                             \
   }                                                                  \
 }
 
-// It subtracts the prediction from the input pixel and stores the residual
-// in the output pixel.
-#define GENERATE_PREDICTOR_SUB(PREDICTOR, PREDICTOR_SUB)             \
-static void PREDICTOR_SUB(const uint32_t* in, const uint32_t* upper, \
-                          int num_pixels, uint32_t* out) {           \
-  int x;                                                             \
-  for (x = 0; x < num_pixels; ++x) {                                 \
-    const uint32_t pred = (PREDICTOR)(in[x - 1], upper + x);         \
-    out[x] = VP8LSubPixels(in[x], pred);                             \
-  }                                                                  \
-}
-
 #ifdef __cplusplus
 }    // extern "C"
 #endif
diff --git a/third_party/libwebp/src/dsp/lossless_enc.c b/third_party/libwebp/src/dsp/lossless_enc.c
index d608326..cde1280 100644
--- a/third_party/libwebp/src/dsp/lossless_enc.c
+++ b/third_party/libwebp/src/dsp/lossless_enc.c
@@ -329,6 +329,15 @@
 static float FastSLog2Slow_C(uint32_t v) {
   assert(v >= LOG_LOOKUP_IDX_MAX);
   if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
+    // use clz if available
+    const int log_cnt = BitsLog2Floor(v) - 7;
+    const uint32_t y = 1 << log_cnt;
+    int correction = 0;
+    const float v_f = (float)v;
+    const uint32_t orig_v = v;
+    v >>= log_cnt;
+#else
     int log_cnt = 0;
     uint32_t y = 1;
     int correction = 0;
@@ -339,6 +348,7 @@
       v = v >> 1;
       y = y << 1;
     } while (v >= LOG_LOOKUP_IDX_MAX);
+#endif
     // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
     // Xf = floor(Xf) * (1 + (v % y) / v)
     // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
@@ -355,6 +365,14 @@
 static float FastLog2Slow_C(uint32_t v) {
   assert(v >= LOG_LOOKUP_IDX_MAX);
   if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
+    // use clz if available
+    const int log_cnt = BitsLog2Floor(v) - 7;
+    const uint32_t y = 1 << log_cnt;
+    const uint32_t orig_v = v;
+    double log_2;
+    v >>= log_cnt;
+#else
     int log_cnt = 0;
     uint32_t y = 1;
     const uint32_t orig_v = v;
@@ -364,6 +382,7 @@
       v = v >> 1;
       y = y << 1;
     } while (v >= LOG_LOOKUP_IDX_MAX);
+#endif
     log_2 = kLog2Table[v] + log_cnt;
     if (orig_v >= APPROX_LOG_MAX) {
       // Since the division is still expensive, add this correction factor only
@@ -383,7 +402,7 @@
 // Compute the combined Shanon's entropy for distribution {X} and {X+Y}
 static float CombinedShannonEntropy_C(const int X[256], const int Y[256]) {
   int i;
-  double retval = 0.;
+  float retval = 0.f;
   int sumX = 0, sumXY = 0;
   for (i = 0; i < 256; ++i) {
     const int x = X[i];
@@ -399,7 +418,7 @@
     }
   }
   retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
-  return (float)retval;
+  return retval;
 }
 
 void VP8LBitEntropyInit(VP8LBitEntropy* const entropy) {
@@ -503,11 +522,11 @@
 void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
   int i;
   for (i = 0; i < num_pixels; ++i) {
-    const int argb = argb_data[i];
+    const int argb = (int)argb_data[i];
     const int green = (argb >> 8) & 0xff;
     const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
     const uint32_t new_b = (((argb >>  0) & 0xff) - green) & 0xff;
-    argb_data[i] = (argb & 0xff00ff00u) | (new_r << 16) | new_b;
+    argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;
   }
 }
 
@@ -515,19 +534,23 @@
   return ((int)color_pred * color) >> 5;
 }
 
+static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
+  return (int8_t)(v & 0xff);
+}
+
 void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
                           int num_pixels) {
   int i;
   for (i = 0; i < num_pixels; ++i) {
     const uint32_t argb = data[i];
-    const uint32_t green = argb >> 8;
-    const uint32_t red = argb >> 16;
+    const int8_t green = U32ToS8(argb >>  8);
+    const int8_t red   = U32ToS8(argb >> 16);
     int new_red = red & 0xff;
     int new_blue = argb & 0xff;
-    new_red -= ColorTransformDelta(m->green_to_red_, green);
+    new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);
     new_red &= 0xff;
-    new_blue -= ColorTransformDelta(m->green_to_blue_, green);
-    new_blue -= ColorTransformDelta(m->red_to_blue_, red);
+    new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);
+    new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);
     new_blue &= 0xff;
     data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
   }
@@ -535,20 +558,20 @@
 
 static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
                                              uint32_t argb) {
-  const uint32_t green = argb >> 8;
+  const int8_t green = U32ToS8(argb >> 8);
   int new_red = argb >> 16;
-  new_red -= ColorTransformDelta(green_to_red, green);
+  new_red -= ColorTransformDelta((int8_t)green_to_red, green);
   return (new_red & 0xff);
 }
 
 static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
                                               uint8_t red_to_blue,
                                               uint32_t argb) {
-  const uint32_t green = argb >> 8;
-  const uint32_t red = argb >> 16;
-  uint8_t new_blue = argb;
-  new_blue -= ColorTransformDelta(green_to_blue, green);
-  new_blue -= ColorTransformDelta(red_to_blue, red);
+  const int8_t green = U32ToS8(argb >>  8);
+  const int8_t red   = U32ToS8(argb >> 16);
+  int new_blue = argb & 0xff;
+  new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);
+  new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);
   return (new_blue & 0xff);
 }
 
@@ -558,7 +581,7 @@
   while (tile_height-- > 0) {
     int x;
     for (x = 0; x < tile_width; ++x) {
-      ++histo[TransformColorRed(green_to_red, argb[x])];
+      ++histo[TransformColorRed((uint8_t)green_to_red, argb[x])];
     }
     argb += stride;
   }
@@ -571,7 +594,8 @@
   while (tile_height-- > 0) {
     int x;
     for (x = 0; x < tile_width; ++x) {
-      ++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[x])];
+      ++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue,
+                                 argb[x])];
     }
     argb += stride;
   }
@@ -612,17 +636,17 @@
 
 //------------------------------------------------------------------------------
 
-static double ExtraCost_C(const uint32_t* population, int length) {
+static float ExtraCost_C(const uint32_t* population, int length) {
   int i;
-  double cost = 0.;
+  float cost = 0.f;
   for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2];
   return cost;
 }
 
-static double ExtraCostCombined_C(const uint32_t* X, const uint32_t* Y,
+static float ExtraCostCombined_C(const uint32_t* X, const uint32_t* Y,
                                   int length) {
   int i;
-  double cost = 0.;
+  float cost = 0.f;
   for (i = 2; i < length - 2; ++i) {
     const int xy = X[i + 2] + Y[i + 2];
     cost += (i >> 1) * xy;
@@ -632,176 +656,71 @@
 
 //------------------------------------------------------------------------------
 
-static void HistogramAdd_C(const VP8LHistogram* const a,
-                           const VP8LHistogram* const b,
-                           VP8LHistogram* const out) {
+static void AddVector_C(const uint32_t* a, const uint32_t* b, uint32_t* out,
+                        int size) {
+  int i;
+  for (i = 0; i < size; ++i) out[i] = a[i] + b[i];
+}
+
+static void AddVectorEq_C(const uint32_t* a, uint32_t* out, int size) {
+  int i;
+  for (i = 0; i < size; ++i) out[i] += a[i];
+}
+
+#define ADD(X, ARG, LEN) do {                                                  \
+  if (a->is_used_[X]) {                                                        \
+    if (b->is_used_[X]) {                                                      \
+      VP8LAddVector(a->ARG, b->ARG, out->ARG, (LEN));                          \
+    } else {                                                                   \
+      memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0]));           \
+    }                                                                          \
+  } else if (b->is_used_[X]) {                                                 \
+    memcpy(&out->ARG[0], &b->ARG[0], (LEN) * sizeof(out->ARG[0]));             \
+  } else {                                                                     \
+    memset(&out->ARG[0], 0, (LEN) * sizeof(out->ARG[0]));                      \
+  }                                                                            \
+} while (0)
+
+#define ADD_EQ(X, ARG, LEN) do {                                               \
+  if (a->is_used_[X]) {                                                        \
+    if (out->is_used_[X]) {                                                    \
+      VP8LAddVectorEq(a->ARG, out->ARG, (LEN));                                \
+    } else {                                                                   \
+      memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0]));           \
+    }                                                                          \
+  }                                                                            \
+} while (0)
+
+void VP8LHistogramAdd(const VP8LHistogram* const a,
+                      const VP8LHistogram* const b, VP8LHistogram* const out) {
   int i;
   const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
   assert(a->palette_code_bits_ == b->palette_code_bits_);
+
   if (b != out) {
-    for (i = 0; i < literal_size; ++i) {
-      out->literal_[i] = a->literal_[i] + b->literal_[i];
-    }
-    for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
-      out->distance_[i] = a->distance_[i] + b->distance_[i];
-    }
-    for (i = 0; i < NUM_LITERAL_CODES; ++i) {
-      out->red_[i] = a->red_[i] + b->red_[i];
-      out->blue_[i] = a->blue_[i] + b->blue_[i];
-      out->alpha_[i] = a->alpha_[i] + b->alpha_[i];
+    ADD(0, literal_, literal_size);
+    ADD(1, red_, NUM_LITERAL_CODES);
+    ADD(2, blue_, NUM_LITERAL_CODES);
+    ADD(3, alpha_, NUM_LITERAL_CODES);
+    ADD(4, distance_, NUM_DISTANCE_CODES);
+    for (i = 0; i < 5; ++i) {
+      out->is_used_[i] = (a->is_used_[i] | b->is_used_[i]);
     }
   } else {
-    for (i = 0; i < literal_size; ++i) {
-      out->literal_[i] += a->literal_[i];
-    }
-    for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
-      out->distance_[i] += a->distance_[i];
-    }
-    for (i = 0; i < NUM_LITERAL_CODES; ++i) {
-      out->red_[i] += a->red_[i];
-      out->blue_[i] += a->blue_[i];
-      out->alpha_[i] += a->alpha_[i];
-    }
+    ADD_EQ(0, literal_, literal_size);
+    ADD_EQ(1, red_, NUM_LITERAL_CODES);
+    ADD_EQ(2, blue_, NUM_LITERAL_CODES);
+    ADD_EQ(3, alpha_, NUM_LITERAL_CODES);
+    ADD_EQ(4, distance_, NUM_DISTANCE_CODES);
+    for (i = 0; i < 5; ++i) out->is_used_[i] |= a->is_used_[i];
   }
 }
+#undef ADD
+#undef ADD_EQ
 
 //------------------------------------------------------------------------------
 // Image transforms.
 
-static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
-  return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
-}
-
-static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
-  return Average2(Average2(a0, a2), a1);
-}
-
-static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
-                                     uint32_t a2, uint32_t a3) {
-  return Average2(Average2(a0, a1), Average2(a2, a3));
-}
-
-static WEBP_INLINE uint32_t Clip255(uint32_t a) {
-  if (a < 256) {
-    return a;
-  }
-  // return 0, when a is a negative integer.
-  // return 255, when a is positive.
-  return ~a >> 24;
-}
-
-static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
-  return Clip255(a + b - c);
-}
-
-static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
-                                                   uint32_t c2) {
-  const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
-  const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
-                                         (c1 >> 16) & 0xff,
-                                         (c2 >> 16) & 0xff);
-  const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
-                                         (c1 >> 8) & 0xff,
-                                         (c2 >> 8) & 0xff);
-  const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
-  return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
-}
-
-static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
-  return Clip255(a + (a - b) / 2);
-}
-
-static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
-                                                   uint32_t c2) {
-  const uint32_t ave = Average2(c0, c1);
-  const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
-  const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
-  const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
-  const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
-  return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
-}
-
-// gcc-4.9 on ARM generates incorrect code in Select() when Sub3() is inlined.
-#if defined(__arm__) && \
-    (LOCAL_GCC_VERSION == 0x409 || LOCAL_GCC_VERSION == 0x408)
-# define LOCAL_INLINE __attribute__ ((noinline))
-#else
-# define LOCAL_INLINE WEBP_INLINE
-#endif
-
-static LOCAL_INLINE int Sub3(int a, int b, int c) {
-  const int pb = b - c;
-  const int pa = a - c;
-  return abs(pb) - abs(pa);
-}
-
-#undef LOCAL_INLINE
-
-static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
-  const int pa_minus_pb =
-      Sub3((a >> 24)       , (b >> 24)       , (c >> 24)       ) +
-      Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
-      Sub3((a >>  8) & 0xff, (b >>  8) & 0xff, (c >>  8) & 0xff) +
-      Sub3((a      ) & 0xff, (b      ) & 0xff, (c      ) & 0xff);
-  return (pa_minus_pb <= 0) ? a : b;
-}
-
-//------------------------------------------------------------------------------
-// Predictors
-
-static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[0];
-}
-static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[1];
-}
-static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[-1];
-}
-static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average3(left, top[0], top[1]);
-  return pred;
-}
-static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[-1]);
-  return pred;
-}
-static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[0]);
-  return pred;
-}
-static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(top[-1], top[0]);
-  (void)left;
-  return pred;
-}
-static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(top[0], top[1]);
-  (void)left;
-  return pred;
-}
-static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
-  return pred;
-}
-static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Select(top[0], left, top[-1]);
-  return pred;
-}
-static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
-  return pred;
-}
-static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
-  return pred;
-}
-
-//------------------------------------------------------------------------------
-
 static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
                             int num_pixels, uint32_t* out) {
   int i;
@@ -816,18 +735,33 @@
   (void)upper;
 }
 
-GENERATE_PREDICTOR_SUB(Predictor2, PredictorSub2_C)
-GENERATE_PREDICTOR_SUB(Predictor3, PredictorSub3_C)
-GENERATE_PREDICTOR_SUB(Predictor4, PredictorSub4_C)
-GENERATE_PREDICTOR_SUB(Predictor5, PredictorSub5_C)
-GENERATE_PREDICTOR_SUB(Predictor6, PredictorSub6_C)
-GENERATE_PREDICTOR_SUB(Predictor7, PredictorSub7_C)
-GENERATE_PREDICTOR_SUB(Predictor8, PredictorSub8_C)
-GENERATE_PREDICTOR_SUB(Predictor9, PredictorSub9_C)
-GENERATE_PREDICTOR_SUB(Predictor10, PredictorSub10_C)
-GENERATE_PREDICTOR_SUB(Predictor11, PredictorSub11_C)
-GENERATE_PREDICTOR_SUB(Predictor12, PredictorSub12_C)
-GENERATE_PREDICTOR_SUB(Predictor13, PredictorSub13_C)
+// It subtracts the prediction from the input pixel and stores the residual
+// in the output pixel.
+#define GENERATE_PREDICTOR_SUB(PREDICTOR_I)                                \
+static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in,              \
+                                          const uint32_t* upper,           \
+                                          int num_pixels, uint32_t* out) { \
+  int x;                                                                   \
+  assert(upper != NULL);                                                   \
+  for (x = 0; x < num_pixels; ++x) {                                       \
+    const uint32_t pred =                                                  \
+        VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x);             \
+    out[x] = VP8LSubPixels(in[x], pred);                                   \
+  }                                                                        \
+}
+
+GENERATE_PREDICTOR_SUB(2)
+GENERATE_PREDICTOR_SUB(3)
+GENERATE_PREDICTOR_SUB(4)
+GENERATE_PREDICTOR_SUB(5)
+GENERATE_PREDICTOR_SUB(6)
+GENERATE_PREDICTOR_SUB(7)
+GENERATE_PREDICTOR_SUB(8)
+GENERATE_PREDICTOR_SUB(9)
+GENERATE_PREDICTOR_SUB(10)
+GENERATE_PREDICTOR_SUB(11)
+GENERATE_PREDICTOR_SUB(12)
+GENERATE_PREDICTOR_SUB(13)
 
 //------------------------------------------------------------------------------
 
@@ -848,7 +782,8 @@
 VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;
 VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;
 
-VP8LHistogramAddFunc VP8LHistogramAdd;
+VP8LAddVectorFunc VP8LAddVector;
+VP8LAddVectorEqFunc VP8LAddVectorEq;
 
 VP8LVectorMismatchFunc VP8LVectorMismatch;
 VP8LBundleColorMapFunc VP8LBundleColorMap;
@@ -856,6 +791,7 @@
 VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
 VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8LEncDspInitSSE2(void);
 extern void VP8LEncDspInitSSE41(void);
 extern void VP8LEncDspInitNEON(void);
@@ -885,7 +821,8 @@
   VP8LGetEntropyUnrefined = GetEntropyUnrefined_C;
   VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_C;
 
-  VP8LHistogramAdd = HistogramAdd_C;
+  VP8LAddVector = AddVector_C;
+  VP8LAddVectorEq = AddVectorEq_C;
 
   VP8LVectorMismatch = VectorMismatch_C;
   VP8LBundleColorMap = VP8LBundleColorMap_C;
@@ -926,10 +863,10 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8LEncDspInitSSE2();
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
       if (VP8GetCPUInfo(kSSE4_1)) {
         VP8LEncDspInitSSE41();
       }
@@ -953,7 +890,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     VP8LEncDspInitNEON();
@@ -971,7 +908,8 @@
   assert(VP8LCombinedShannonEntropy != NULL);
   assert(VP8LGetEntropyUnrefined != NULL);
   assert(VP8LGetCombinedEntropyUnrefined != NULL);
-  assert(VP8LHistogramAdd != NULL);
+  assert(VP8LAddVector != NULL);
+  assert(VP8LAddVectorEq != NULL);
   assert(VP8LVectorMismatch != NULL);
   assert(VP8LBundleColorMap != NULL);
   assert(VP8LPredictorsSub[0] != NULL);
diff --git a/third_party/libwebp/src/dsp/lossless_enc_mips32.c b/third_party/libwebp/src/dsp/lossless_enc_mips32.c
index 33e455c..53cd699 100644
--- a/third_party/libwebp/src/dsp/lossless_enc_mips32.c
+++ b/third_party/libwebp/src/dsp/lossless_enc_mips32.c
@@ -109,8 +109,8 @@
 //     cost += i * *(pop + 1);
 //     pop += 2;
 //   }
-//   return (double)cost;
-static double ExtraCost_MIPS32(const uint32_t* const population, int length) {
+//   return (float)cost;
+static float ExtraCost_MIPS32(const uint32_t* const population, int length) {
   int i, temp0, temp1;
   const uint32_t* pop = &population[4];
   const uint32_t* const LoopEnd = &population[length];
@@ -136,7 +136,7 @@
     : "memory", "hi", "lo"
   );
 
-  return (double)((int64_t)temp0 << 32 | temp1);
+  return (float)((int64_t)temp0 << 32 | temp1);
 }
 
 // C version of this function:
@@ -154,9 +154,9 @@
 //     pX += 2;
 //     pY += 2;
 //   }
-//   return (double)cost;
-static double ExtraCostCombined_MIPS32(const uint32_t* const X,
-                                       const uint32_t* const Y, int length) {
+//   return (float)cost;
+static float ExtraCostCombined_MIPS32(const uint32_t* const X,
+                                      const uint32_t* const Y, int length) {
   int i, temp0, temp1, temp2, temp3;
   const uint32_t* pX = &X[4];
   const uint32_t* pY = &Y[4];
@@ -189,7 +189,7 @@
     : "memory", "hi", "lo"
   );
 
-  return (double)((int64_t)temp0 << 32 | temp1);
+  return (float)((int64_t)temp0 << 32 | temp1);
 }
 
 #define HUFFMAN_COST_PASS                                 \
@@ -350,65 +350,29 @@
     ASM_END_COMMON_0                                    \
     ASM_END_COMMON_1
 
-#define ADD_VECTOR(A, B, OUT, SIZE, EXTRA_SIZE)  do {   \
-  const uint32_t* pa = (const uint32_t*)(A);            \
-  const uint32_t* pb = (const uint32_t*)(B);            \
-  uint32_t* pout = (uint32_t*)(OUT);                    \
-  const uint32_t* const LoopEnd = pa + (SIZE);          \
-  assert((SIZE) % 4 == 0);                              \
-  ASM_START                                             \
-  ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)              \
-  ASM_END_0                                             \
-  if ((EXTRA_SIZE) > 0) {                               \
-    const int last = (EXTRA_SIZE);                      \
-    int i;                                              \
-    for (i = 0; i < last; ++i) pout[i] = pa[i] + pb[i]; \
-  }                                                     \
-} while (0)
-
-#define ADD_VECTOR_EQ(A, OUT, SIZE, EXTRA_SIZE)  do {   \
-  const uint32_t* pa = (const uint32_t*)(A);            \
-  uint32_t* pout = (uint32_t*)(OUT);                    \
-  const uint32_t* const LoopEnd = pa + (SIZE);          \
-  assert((SIZE) % 4 == 0);                              \
-  ASM_START                                             \
-  ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)            \
-  ASM_END_1                                             \
-  if ((EXTRA_SIZE) > 0) {                               \
-    const int last = (EXTRA_SIZE);                      \
-    int i;                                              \
-    for (i = 0; i < last; ++i) pout[i] += pa[i];        \
-  }                                                     \
-} while (0)
-
-static void HistogramAdd_MIPS32(const VP8LHistogram* const a,
-                                const VP8LHistogram* const b,
-                                VP8LHistogram* const out) {
+static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
+                             uint32_t* pout, int size) {
   uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
-  const int extra_cache_size = VP8LHistogramNumCodes(a->palette_code_bits_)
-                             - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
-  assert(a->palette_code_bits_ == b->palette_code_bits_);
-
-  if (b != out) {
-    ADD_VECTOR(a->literal_, b->literal_, out->literal_,
-               NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
-    ADD_VECTOR(a->distance_, b->distance_, out->distance_,
-               NUM_DISTANCE_CODES, 0);
-    ADD_VECTOR(a->red_, b->red_, out->red_, NUM_LITERAL_CODES, 0);
-    ADD_VECTOR(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES, 0);
-    ADD_VECTOR(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
-  } else {
-    ADD_VECTOR_EQ(a->literal_, out->literal_,
-                  NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
-    ADD_VECTOR_EQ(a->distance_, out->distance_, NUM_DISTANCE_CODES, 0);
-    ADD_VECTOR_EQ(a->red_, out->red_, NUM_LITERAL_CODES, 0);
-    ADD_VECTOR_EQ(a->blue_, out->blue_, NUM_LITERAL_CODES, 0);
-    ADD_VECTOR_EQ(a->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
-  }
+  const int end = ((size) / 4) * 4;
+  const uint32_t* const LoopEnd = pa + end;
+  int i;
+  ASM_START
+  ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
+  ASM_END_0
+  for (i = 0; i < size - end; ++i) pout[i] = pa[i] + pb[i];
 }
 
-#undef ADD_VECTOR_EQ
-#undef ADD_VECTOR
+static void AddVectorEq_MIPS32(const uint32_t* pa, uint32_t* pout, int size) {
+  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+  const int end = ((size) / 4) * 4;
+  const uint32_t* const LoopEnd = pa + end;
+  int i;
+  ASM_START
+  ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
+  ASM_END_1
+  for (i = 0; i < size - end; ++i) pout[i] += pa[i];
+}
+
 #undef ASM_END_1
 #undef ASM_END_0
 #undef ASM_END_COMMON_1
@@ -428,7 +392,8 @@
   VP8LExtraCostCombined = ExtraCostCombined_MIPS32;
   VP8LGetEntropyUnrefined = GetEntropyUnrefined_MIPS32;
   VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_MIPS32;
-  VP8LHistogramAdd = HistogramAdd_MIPS32;
+  VP8LAddVector = AddVector_MIPS32;
+  VP8LAddVectorEq = AddVectorEq_MIPS32;
 }
 
 #else  // !WEBP_USE_MIPS32
diff --git a/third_party/libwebp/src/dsp/lossless_enc_neon.c b/third_party/libwebp/src/dsp/lossless_enc_neon.c
index 7c7b73f..e32c796 100644
--- a/third_party/libwebp/src/dsp/lossless_enc_neon.c
+++ b/third_party/libwebp/src/dsp/lossless_enc_neon.c
@@ -25,7 +25,7 @@
 
 // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
 // non-standard versions there.
-#if defined(__APPLE__) && defined(__aarch64__) && \
+#if defined(__APPLE__) && WEBP_AARCH64 && \
     defined(__apple_build_version__) && (__apple_build_version__< 6020037)
 #define USE_VTBLQ
 #endif
diff --git a/third_party/libwebp/src/dsp/lossless_enc_sse2.c b/third_party/libwebp/src/dsp/lossless_enc_sse2.c
index f84a990..66cbaab 100644
--- a/third_party/libwebp/src/dsp/lossless_enc_sse2.c
+++ b/third_party/libwebp/src/dsp/lossless_enc_sse2.c
@@ -54,8 +54,8 @@
   const __m128i mults_rb = MK_CST_16(CST_5b(m->green_to_red_),
                                      CST_5b(m->green_to_blue_));
   const __m128i mults_b2 = MK_CST_16(CST_5b(m->red_to_blue_), 0);
-  const __m128i mask_ag = _mm_set1_epi32(0xff00ff00);  // alpha-green masks
-  const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff);  // red-blue masks
+  const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00);  // alpha-green masks
+  const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff);       // red-blue masks
   int i;
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]); // argb
@@ -170,12 +170,13 @@
 
 //------------------------------------------------------------------------------
 
+// Note we are adding uint32_t's as *signed* int32's (using _mm_add_epi32). But
+// that's ok since the histogram values are less than 1<<28 (max picture size).
 #define LINE_SIZE 16    // 8 or 16
 static void AddVector_SSE2(const uint32_t* a, const uint32_t* b, uint32_t* out,
                            int size) {
   int i;
-  assert(size % LINE_SIZE == 0);
-  for (i = 0; i < size; i += LINE_SIZE) {
+  for (i = 0; i + LINE_SIZE <= size; i += LINE_SIZE) {
     const __m128i a0 = _mm_loadu_si128((const __m128i*)&a[i +  0]);
     const __m128i a1 = _mm_loadu_si128((const __m128i*)&a[i +  4]);
 #if (LINE_SIZE == 16)
@@ -195,12 +196,14 @@
     _mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
 #endif
   }
+  for (; i < size; ++i) {
+    out[i] = a[i] + b[i];
+  }
 }
 
 static void AddVectorEq_SSE2(const uint32_t* a, uint32_t* out, int size) {
   int i;
-  assert(size % LINE_SIZE == 0);
-  for (i = 0; i < size; i += LINE_SIZE) {
+  for (i = 0; i + LINE_SIZE <= size; i += LINE_SIZE) {
     const __m128i a0 = _mm_loadu_si128((const __m128i*)&a[i +  0]);
     const __m128i a1 = _mm_loadu_si128((const __m128i*)&a[i +  4]);
 #if (LINE_SIZE == 16)
@@ -220,109 +223,64 @@
     _mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
 #endif
   }
+  for (; i < size; ++i) {
+    out[i] += a[i];
+  }
 }
 #undef LINE_SIZE
 
-// Note we are adding uint32_t's as *signed* int32's (using _mm_add_epi32). But
-// that's ok since the histogram values are less than 1<<28 (max picture size).
-static void HistogramAdd_SSE2(const VP8LHistogram* const a,
-                              const VP8LHistogram* const b,
-                              VP8LHistogram* const out) {
-  int i;
-  const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
-  assert(a->palette_code_bits_ == b->palette_code_bits_);
-  if (b != out) {
-    AddVector_SSE2(a->literal_, b->literal_, out->literal_, NUM_LITERAL_CODES);
-    AddVector_SSE2(a->red_, b->red_, out->red_, NUM_LITERAL_CODES);
-    AddVector_SSE2(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES);
-    AddVector_SSE2(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES);
-  } else {
-    AddVectorEq_SSE2(a->literal_, out->literal_, NUM_LITERAL_CODES);
-    AddVectorEq_SSE2(a->red_, out->red_, NUM_LITERAL_CODES);
-    AddVectorEq_SSE2(a->blue_, out->blue_, NUM_LITERAL_CODES);
-    AddVectorEq_SSE2(a->alpha_, out->alpha_, NUM_LITERAL_CODES);
-  }
-  for (i = NUM_LITERAL_CODES; i < literal_size; ++i) {
-    out->literal_[i] = a->literal_[i] + b->literal_[i];
-  }
-  for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
-    out->distance_[i] = a->distance_[i] + b->distance_[i];
-  }
-}
-
 //------------------------------------------------------------------------------
 // Entropy
 
-// Checks whether the X or Y contribution is worth computing and adding.
-// Used in loop unrolling.
-#define ANALYZE_X_OR_Y(x_or_y, j)                                           \
-  do {                                                                      \
-    if ((x_or_y)[i + (j)] != 0) retval -= VP8LFastSLog2((x_or_y)[i + (j)]); \
-  } while (0)
-
-// Checks whether the X + Y contribution is worth computing and adding.
-// Used in loop unrolling.
-#define ANALYZE_XY(j)                  \
-  do {                                 \
-    if (tmp[j] != 0) {                 \
-      retval -= VP8LFastSLog2(tmp[j]); \
-      ANALYZE_X_OR_Y(X, j);            \
-    }                                  \
-  } while (0)
+// TODO(https://crbug.com/webp/499): this function produces different results
+// from the C code due to use of double/float resulting in output differences
+// when compared to -noasm.
+#if !(defined(WEBP_HAVE_SLOW_CLZ_CTZ) || defined(__i386__) || defined(_M_IX86))
 
 static float CombinedShannonEntropy_SSE2(const int X[256], const int Y[256]) {
   int i;
-  double retval = 0.;
-  int sumX, sumXY;
-  int32_t tmp[4];
-  __m128i zero = _mm_setzero_si128();
-  // Sums up X + Y, 4 ints at a time (and will merge it at the end for sumXY).
-  __m128i sumXY_128 = zero;
-  __m128i sumX_128 = zero;
+  float retval = 0.f;
+  int sumX = 0, sumXY = 0;
+  const __m128i zero = _mm_setzero_si128();
 
-  for (i = 0; i < 256; i += 4) {
-    const __m128i x = _mm_loadu_si128((const __m128i*)(X + i));
-    const __m128i y = _mm_loadu_si128((const __m128i*)(Y + i));
-
-    // Check if any X is non-zero: this actually provides a speedup as X is
-    // usually sparse.
-    if (_mm_movemask_epi8(_mm_cmpeq_epi32(x, zero)) != 0xFFFF) {
-      const __m128i xy_128 = _mm_add_epi32(x, y);
-      sumXY_128 = _mm_add_epi32(sumXY_128, xy_128);
-
-      sumX_128 = _mm_add_epi32(sumX_128, x);
-
-      // Analyze the different X + Y.
-      _mm_storeu_si128((__m128i*)tmp, xy_128);
-
-      ANALYZE_XY(0);
-      ANALYZE_XY(1);
-      ANALYZE_XY(2);
-      ANALYZE_XY(3);
-    } else {
-      // X is fully 0, so only deal with Y.
-      sumXY_128 = _mm_add_epi32(sumXY_128, y);
-
-      ANALYZE_X_OR_Y(Y, 0);
-      ANALYZE_X_OR_Y(Y, 1);
-      ANALYZE_X_OR_Y(Y, 2);
-      ANALYZE_X_OR_Y(Y, 3);
+  for (i = 0; i < 256; i += 16) {
+    const __m128i x0 = _mm_loadu_si128((const __m128i*)(X + i +  0));
+    const __m128i y0 = _mm_loadu_si128((const __m128i*)(Y + i +  0));
+    const __m128i x1 = _mm_loadu_si128((const __m128i*)(X + i +  4));
+    const __m128i y1 = _mm_loadu_si128((const __m128i*)(Y + i +  4));
+    const __m128i x2 = _mm_loadu_si128((const __m128i*)(X + i +  8));
+    const __m128i y2 = _mm_loadu_si128((const __m128i*)(Y + i +  8));
+    const __m128i x3 = _mm_loadu_si128((const __m128i*)(X + i + 12));
+    const __m128i y3 = _mm_loadu_si128((const __m128i*)(Y + i + 12));
+    const __m128i x4 = _mm_packs_epi16(_mm_packs_epi32(x0, x1),
+                                       _mm_packs_epi32(x2, x3));
+    const __m128i y4 = _mm_packs_epi16(_mm_packs_epi32(y0, y1),
+                                       _mm_packs_epi32(y2, y3));
+    const int32_t mx = _mm_movemask_epi8(_mm_cmpgt_epi8(x4, zero));
+    int32_t my = _mm_movemask_epi8(_mm_cmpgt_epi8(y4, zero)) | mx;
+    while (my) {
+      const int32_t j = BitsCtz(my);
+      int xy;
+      if ((mx >> j) & 1) {
+        const int x = X[i + j];
+        sumXY += x;
+        retval -= VP8LFastSLog2(x);
+      }
+      xy = X[i + j] + Y[i + j];
+      sumX += xy;
+      retval -= VP8LFastSLog2(xy);
+      my &= my - 1;
     }
   }
-
-  // Sum up sumX_128 to get sumX.
-  _mm_storeu_si128((__m128i*)tmp, sumX_128);
-  sumX = tmp[3] + tmp[2] + tmp[1] + tmp[0];
-
-  // Sum up sumXY_128 to get sumXY.
-  _mm_storeu_si128((__m128i*)tmp, sumXY_128);
-  sumXY = tmp[3] + tmp[2] + tmp[1] + tmp[0];
-
   retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
-  return (float)retval;
+  return retval;
 }
-#undef ANALYZE_X_OR_Y
-#undef ANALYZE_XY
+
+#else
+
+#define DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC   // won't be faster
+
+#endif
 
 //------------------------------------------------------------------------------
 
@@ -384,7 +342,7 @@
   assert(xbits <= 3);
   switch (xbits) {
     case 0: {
-      const __m128i ff = _mm_set1_epi16(0xff00);
+      const __m128i ff = _mm_set1_epi16((short)0xff00);
       const __m128i zero = _mm_setzero_si128();
       // Store 0xff000000 | (row[x] << 8).
       for (x = 0; x + 16 <= width; x += 16, dst += 16) {
@@ -403,7 +361,7 @@
       break;
     }
     case 1: {
-      const __m128i ff = _mm_set1_epi16(0xff00);
+      const __m128i ff = _mm_set1_epi16((short)0xff00);
       const __m128i mul = _mm_set1_epi16(0x110);
       for (x = 0; x + 16 <= width; x += 16, dst += 8) {
         // 0a0b | (where a/b are 4 bits).
@@ -418,7 +376,7 @@
       break;
     }
     case 2: {
-      const __m128i mask_or = _mm_set1_epi32(0xff000000);
+      const __m128i mask_or = _mm_set1_epi32((int)0xff000000);
       const __m128i mul_cst = _mm_set1_epi16(0x0104);
       const __m128i mask_mul = _mm_set1_epi16(0x0f00);
       for (x = 0; x + 16 <= width; x += 16, dst += 4) {
@@ -469,31 +427,34 @@
 static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper,
                                int num_pixels, uint32_t* out) {
   int i;
-  const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+  const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
     const __m128i res = _mm_sub_epi8(src, black);
     _mm_storeu_si128((__m128i*)&out[i], res);
   }
   if (i != num_pixels) {
-    VP8LPredictorsSub_C[0](in + i, upper + i, num_pixels - i, out + i);
+    VP8LPredictorsSub_C[0](in + i, NULL, num_pixels - i, out + i);
   }
+  (void)upper;
 }
 
-#define GENERATE_PREDICTOR_1(X, IN)                                           \
-static void PredictorSub##X##_SSE2(const uint32_t* in, const uint32_t* upper, \
-                                   int num_pixels, uint32_t* out) {           \
-  int i;                                                                      \
-  for (i = 0; i + 4 <= num_pixels; i += 4) {                                  \
-    const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);              \
-    const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN));              \
-    const __m128i res = _mm_sub_epi8(src, pred);                              \
-    _mm_storeu_si128((__m128i*)&out[i], res);                                 \
-  }                                                                           \
-  if (i != num_pixels) {                                                      \
-    VP8LPredictorsSub_C[(X)](in + i, upper + i, num_pixels - i, out + i);     \
-  }                                                                           \
-}
+#define GENERATE_PREDICTOR_1(X, IN)                                         \
+  static void PredictorSub##X##_SSE2(const uint32_t* const in,              \
+                                     const uint32_t* const upper,           \
+                                     int num_pixels, uint32_t* const out) { \
+    int i;                                                                  \
+    for (i = 0; i + 4 <= num_pixels; i += 4) {                              \
+      const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);          \
+      const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN));          \
+      const __m128i res = _mm_sub_epi8(src, pred);                          \
+      _mm_storeu_si128((__m128i*)&out[i], res);                             \
+    }                                                                       \
+    if (i != num_pixels) {                                                  \
+      VP8LPredictorsSub_C[(X)](in + i, WEBP_OFFSET_PTR(upper, i),           \
+                               num_pixels - i, out + i);                    \
+    }                                                                       \
+  }
 
 GENERATE_PREDICTOR_1(1, in[i - 1])       // Predictor1: L
 GENERATE_PREDICTOR_1(2, upper[i])        // Predictor2: T
@@ -675,8 +636,11 @@
   VP8LTransformColor = TransformColor_SSE2;
   VP8LCollectColorBlueTransforms = CollectColorBlueTransforms_SSE2;
   VP8LCollectColorRedTransforms = CollectColorRedTransforms_SSE2;
-  VP8LHistogramAdd = HistogramAdd_SSE2;
+  VP8LAddVector = AddVector_SSE2;
+  VP8LAddVectorEq = AddVectorEq_SSE2;
+#if !defined(DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC)
   VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
+#endif
   VP8LVectorMismatch = VectorMismatch_SSE2;
   VP8LBundleColorMap = BundleColorMap_SSE2;
 
diff --git a/third_party/libwebp/src/dsp/lossless_enc_sse41.c b/third_party/libwebp/src/dsp/lossless_enc_sse41.c
index 2e12a71..ad358a6 100644
--- a/third_party/libwebp/src/dsp/lossless_enc_sse41.c
+++ b/third_party/libwebp/src/dsp/lossless_enc_sse41.c
@@ -44,46 +44,47 @@
 //------------------------------------------------------------------------------
 // Color Transform
 
-#define SPAN 8
+#define MK_CST_16(HI, LO) \
+  _mm_set1_epi32((int)(((uint32_t)(HI) << 16) | ((LO) & 0xffff)))
+
 static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
                                              int tile_width, int tile_height,
                                              int green_to_blue, int red_to_blue,
                                              int histo[]) {
-  const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue));
-  const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue));
-  const __m128i mask_g = _mm_set1_epi16(0xff00);   // green mask
-  const __m128i mask_gb = _mm_set1_epi32(0xffff);  // green/blue mask
-  const __m128i mask_b = _mm_set1_epi16(0x00ff);   // blue mask
-  const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1,
-                                            -1, -1, -1, -1, -1, -1, -1);
-  const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1,
-                                            2, -1, 6, -1, 10, -1, 14);
-  int y;
-  for (y = 0; y < tile_height; ++y) {
-    const uint32_t* const src = argb + y * stride;
-    int i, x;
-    for (x = 0; x + SPAN <= tile_width; x += SPAN) {
-      uint16_t values[SPAN];
-      const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
-      const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
-      const __m128i r0 = _mm_shuffle_epi8(in0, shuffler_lo);
-      const __m128i r1 = _mm_shuffle_epi8(in1, shuffler_hi);
-      const __m128i r = _mm_or_si128(r0, r1);         // r 0
-      const __m128i gb0 = _mm_and_si128(in0, mask_gb);
-      const __m128i gb1 = _mm_and_si128(in1, mask_gb);
-      const __m128i gb = _mm_packus_epi32(gb0, gb1);  // g b
-      const __m128i g = _mm_and_si128(gb, mask_g);    // g 0
-      const __m128i A = _mm_mulhi_epi16(r, mults_r);  // x dbr
-      const __m128i B = _mm_mulhi_epi16(g, mults_g);  // x dbg
-      const __m128i C = _mm_sub_epi8(gb, B);          // x b'
-      const __m128i D = _mm_sub_epi8(C, A);           // x b''
-      const __m128i E = _mm_and_si128(D, mask_b);     // 0 b''
-      _mm_storeu_si128((__m128i*)values, E);
-      for (i = 0; i < SPAN; ++i) ++histo[values[i]];
+  const __m128i mult =
+      MK_CST_16(CST_5b(red_to_blue) + 256,CST_5b(green_to_blue));
+  const __m128i perm =
+      _mm_setr_epi8(-1, 1, -1, 2, -1, 5, -1, 6, -1, 9, -1, 10, -1, 13, -1, 14);
+  if (tile_width >= 4) {
+    int y;
+    for (y = 0; y < tile_height; ++y) {
+      const uint32_t* const src = argb + y * stride;
+      const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
+      const __m128i B1 = _mm_shuffle_epi8(A1, perm);
+      const __m128i C1 = _mm_mulhi_epi16(B1, mult);
+      const __m128i D1 = _mm_sub_epi16(A1, C1);
+      __m128i E = _mm_add_epi16(_mm_srli_epi32(D1, 16), D1);
+      int x;
+      for (x = 4; x + 4 <= tile_width; x += 4) {
+        const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
+        __m128i B2, C2, D2;
+        ++histo[_mm_extract_epi8(E,  0)];
+        B2 = _mm_shuffle_epi8(A2, perm);
+        ++histo[_mm_extract_epi8(E,  4)];
+        C2 = _mm_mulhi_epi16(B2, mult);
+        ++histo[_mm_extract_epi8(E,  8)];
+        D2 = _mm_sub_epi16(A2, C2);
+        ++histo[_mm_extract_epi8(E, 12)];
+        E = _mm_add_epi16(_mm_srli_epi32(D2, 16), D2);
+      }
+      ++histo[_mm_extract_epi8(E,  0)];
+      ++histo[_mm_extract_epi8(E,  4)];
+      ++histo[_mm_extract_epi8(E,  8)];
+      ++histo[_mm_extract_epi8(E, 12)];
     }
   }
   {
-    const int left_over = tile_width & (SPAN - 1);
+    const int left_over = tile_width & 3;
     if (left_over > 0) {
       VP8LCollectColorBlueTransforms_C(argb + tile_width - left_over, stride,
                                        left_over, tile_height,
@@ -95,33 +96,37 @@
 static void CollectColorRedTransforms_SSE41(const uint32_t* argb, int stride,
                                             int tile_width, int tile_height,
                                             int green_to_red, int histo[]) {
-  const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_red));
-  const __m128i mask_g = _mm_set1_epi32(0x00ff00);  // green mask
-  const __m128i mask = _mm_set1_epi16(0xff);
 
-  int y;
-  for (y = 0; y < tile_height; ++y) {
-    const uint32_t* const src = argb + y * stride;
-    int i, x;
-    for (x = 0; x + SPAN <= tile_width; x += SPAN) {
-      uint16_t values[SPAN];
-      const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
-      const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
-      const __m128i g0 = _mm_and_si128(in0, mask_g);  // 0 0  | g 0
-      const __m128i g1 = _mm_and_si128(in1, mask_g);
-      const __m128i g = _mm_packus_epi32(g0, g1);     // g 0
-      const __m128i A0 = _mm_srli_epi32(in0, 16);     // 0 0  | x r
-      const __m128i A1 = _mm_srli_epi32(in1, 16);
-      const __m128i A = _mm_packus_epi32(A0, A1);     // x r
-      const __m128i B = _mm_mulhi_epi16(g, mults_g);  // x dr
-      const __m128i C = _mm_sub_epi8(A, B);           // x r'
-      const __m128i D = _mm_and_si128(C, mask);       // 0 r'
-      _mm_storeu_si128((__m128i*)values, D);
-      for (i = 0; i < SPAN; ++i) ++histo[values[i]];
+  const __m128i mult = MK_CST_16(0, CST_5b(green_to_red));
+  const __m128i mask_g = _mm_set1_epi32(0x0000ff00);
+  if (tile_width >= 4) {
+    int y;
+    for (y = 0; y < tile_height; ++y) {
+      const uint32_t* const src = argb + y * stride;
+      const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
+      const __m128i B1 = _mm_and_si128(A1, mask_g);
+      const __m128i C1 = _mm_madd_epi16(B1, mult);
+      __m128i D = _mm_sub_epi16(A1, C1);
+      int x;
+      for (x = 4; x + 4 <= tile_width; x += 4) {
+        const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
+        __m128i B2, C2;
+        ++histo[_mm_extract_epi8(D,  2)];
+        B2 = _mm_and_si128(A2, mask_g);
+        ++histo[_mm_extract_epi8(D,  6)];
+        C2 = _mm_madd_epi16(B2, mult);
+        ++histo[_mm_extract_epi8(D, 10)];
+        ++histo[_mm_extract_epi8(D, 14)];
+        D = _mm_sub_epi16(A2, C2);
+      }
+      ++histo[_mm_extract_epi8(D,  2)];
+      ++histo[_mm_extract_epi8(D,  6)];
+      ++histo[_mm_extract_epi8(D, 10)];
+      ++histo[_mm_extract_epi8(D, 14)];
     }
   }
   {
-    const int left_over = tile_width & (SPAN - 1);
+    const int left_over = tile_width & 3;
     if (left_over > 0) {
       VP8LCollectColorRedTransforms_C(argb + tile_width - left_over, stride,
                                       left_over, tile_height, green_to_red,
@@ -130,6 +135,8 @@
   }
 }
 
+#undef MK_CST_16
+
 //------------------------------------------------------------------------------
 // Entry point
 
diff --git a/third_party/libwebp/src/dsp/lossless_mips_dsp_r2.c b/third_party/libwebp/src/dsp/lossless_mips_dsp_r2.c
index 9888854..bfe5ea6 100644
--- a/third_party/libwebp/src/dsp/lossless_mips_dsp_r2.c
+++ b/third_party/libwebp/src/dsp/lossless_mips_dsp_r2.c
@@ -188,46 +188,51 @@
   return Average2(Average2(a0, a1), Average2(a2, a3));
 }
 
-static uint32_t Predictor5_MIPSdspR2(uint32_t left, const uint32_t* const top) {
-  return Average3(left, top[0], top[1]);
+static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
+                                     const uint32_t* const top) {
+  return Average3(*left, top[0], top[1]);
 }
 
-static uint32_t Predictor6_MIPSdspR2(uint32_t left, const uint32_t* const top) {
-  return Average2(left, top[-1]);
+static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
+                                     const uint32_t* const top) {
+  return Average2(*left, top[-1]);
 }
 
-static uint32_t Predictor7_MIPSdspR2(uint32_t left, const uint32_t* const top) {
-  return Average2(left, top[0]);
+static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
+                                     const uint32_t* const top) {
+  return Average2(*left, top[0]);
 }
 
-static uint32_t Predictor8_MIPSdspR2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor8_MIPSdspR2(const uint32_t* const left,
+                                     const uint32_t* const top) {
   (void)left;
   return Average2(top[-1], top[0]);
 }
 
-static uint32_t Predictor9_MIPSdspR2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor9_MIPSdspR2(const uint32_t* const left,
+                                     const uint32_t* const top) {
   (void)left;
   return Average2(top[0], top[1]);
 }
 
-static uint32_t Predictor10_MIPSdspR2(uint32_t left,
+static uint32_t Predictor10_MIPSdspR2(const uint32_t* const left,
                                       const uint32_t* const top) {
-  return Average4(left, top[-1], top[0], top[1]);
+  return Average4(*left, top[-1], top[0], top[1]);
 }
 
-static uint32_t Predictor11_MIPSdspR2(uint32_t left,
+static uint32_t Predictor11_MIPSdspR2(const uint32_t* const left,
                                       const uint32_t* const top) {
-  return Select(top[0], left, top[-1]);
+  return Select(top[0], *left, top[-1]);
 }
 
-static uint32_t Predictor12_MIPSdspR2(uint32_t left,
+static uint32_t Predictor12_MIPSdspR2(const uint32_t* const left,
                                       const uint32_t* const top) {
-  return ClampedAddSubtractFull(left, top[0], top[-1]);
+  return ClampedAddSubtractFull(*left, top[0], top[-1]);
 }
 
-static uint32_t Predictor13_MIPSdspR2(uint32_t left,
+static uint32_t Predictor13_MIPSdspR2(const uint32_t* const left,
                                       const uint32_t* const top) {
-  return ClampedAddSubtractHalf(left, top[0], top[-1]);
+  return ClampedAddSubtractHalf(*left, top[0], top[-1]);
 }
 
 // Add green to blue and red channels (i.e. perform the inverse transform of
diff --git a/third_party/libwebp/src/dsp/lossless_neon.c b/third_party/libwebp/src/dsp/lossless_neon.c
index 76a1b6f..ddc9b61 100644
--- a/third_party/libwebp/src/dsp/lossless_neon.c
+++ b/third_party/libwebp/src/dsp/lossless_neon.c
@@ -188,17 +188,21 @@
   return avg;
 }
 
-static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
-  return Average3_NEON(left, top[0], top[1]);
+static uint32_t Predictor5_NEON(const uint32_t* const left,
+                                const uint32_t* const top) {
+  return Average3_NEON(*left, top[0], top[1]);
 }
-static uint32_t Predictor6_NEON(uint32_t left, const uint32_t* const top) {
-  return Average2_NEON(left, top[-1]);
+static uint32_t Predictor6_NEON(const uint32_t* const left,
+                                const uint32_t* const top) {
+  return Average2_NEON(*left, top[-1]);
 }
-static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
-  return Average2_NEON(left, top[0]);
+static uint32_t Predictor7_NEON(const uint32_t* const left,
+                                const uint32_t* const top) {
+  return Average2_NEON(*left, top[0]);
 }
-static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
-  return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
+static uint32_t Predictor13_NEON(const uint32_t* const left,
+                                 const uint32_t* const top) {
+  return ClampedAddSubtractHalf_NEON(*left, top[0], top[-1]);
 }
 
 // Batch versions of those functions.
@@ -494,7 +498,7 @@
 
 // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
 // non-standard versions there.
-#if defined(__APPLE__) && defined(__aarch64__) && \
+#if defined(__APPLE__) && WEBP_AARCH64 && \
     defined(__apple_build_version__) && (__apple_build_version__< 6020037)
 #define USE_VTBLQ
 #endif
diff --git a/third_party/libwebp/src/dsp/lossless_sse2.c b/third_party/libwebp/src/dsp/lossless_sse2.c
index 17d7576..4b6a532 100644
--- a/third_party/libwebp/src/dsp/lossless_sse2.c
+++ b/third_party/libwebp/src/dsp/lossless_sse2.c
@@ -18,7 +18,6 @@
 #include "src/dsp/common_sse2.h"
 #include "src/dsp/lossless.h"
 #include "src/dsp/lossless_common.h"
-#include <assert.h>
 #include <emmintrin.h>
 
 //------------------------------------------------------------------------------
@@ -28,23 +27,22 @@
                                                         uint32_t c1,
                                                         uint32_t c2) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
-  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
-  const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+  const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
   const __m128i V1 = _mm_add_epi16(C0, C1);
   const __m128i V2 = _mm_sub_epi16(V1, C2);
   const __m128i b = _mm_packus_epi16(V2, V2);
-  const uint32_t output = _mm_cvtsi128_si32(b);
-  return output;
+  return (uint32_t)_mm_cvtsi128_si32(b);
 }
 
 static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0,
                                                         uint32_t c1,
                                                         uint32_t c2) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
-  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
-  const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+  const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
   const __m128i avg = _mm_add_epi16(C1, C0);
   const __m128i A0 = _mm_srli_epi16(avg, 1);
   const __m128i A1 = _mm_sub_epi16(A0, B0);
@@ -53,16 +51,15 @@
   const __m128i A3 = _mm_srai_epi16(A2, 1);
   const __m128i A4 = _mm_add_epi16(A0, A3);
   const __m128i A5 = _mm_packus_epi16(A4, A4);
-  const uint32_t output = _mm_cvtsi128_si32(A5);
-  return output;
+  return (uint32_t)_mm_cvtsi128_si32(A5);
 }
 
 static WEBP_INLINE uint32_t Select_SSE2(uint32_t a, uint32_t b, uint32_t c) {
   int pa_minus_pb;
   const __m128i zero = _mm_setzero_si128();
-  const __m128i A0 = _mm_cvtsi32_si128(a);
-  const __m128i B0 = _mm_cvtsi32_si128(b);
-  const __m128i C0 = _mm_cvtsi32_si128(c);
+  const __m128i A0 = _mm_cvtsi32_si128((int)a);
+  const __m128i B0 = _mm_cvtsi32_si128((int)b);
+  const __m128i C0 = _mm_cvtsi32_si128((int)c);
   const __m128i AC0 = _mm_subs_epu8(A0, C0);
   const __m128i CA0 = _mm_subs_epu8(C0, A0);
   const __m128i BC0 = _mm_subs_epu8(B0, C0);
@@ -95,8 +92,8 @@
                                              __m128i* const avg) {
   // (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1)
   const __m128i ones = _mm_set1_epi8(1);
-  const __m128i A0 = _mm_cvtsi32_si128(a0);
-  const __m128i A1 = _mm_cvtsi32_si128(a1);
+  const __m128i A0 = _mm_cvtsi32_si128((int)a0);
+  const __m128i A1 = _mm_cvtsi32_si128((int)a1);
   const __m128i avg1 = _mm_avg_epu8(A0, A1);
   const __m128i one = _mm_and_si128(_mm_xor_si128(A0, A1), ones);
   *avg = _mm_sub_epi8(avg1, one);
@@ -104,8 +101,8 @@
 
 static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero);
-  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+  const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a0), zero);
+  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
   const __m128i sum = _mm_add_epi16(A1, A0);
   return _mm_srli_epi16(sum, 1);
 }
@@ -113,19 +110,18 @@
 static WEBP_INLINE uint32_t Average2_SSE2(uint32_t a0, uint32_t a1) {
   __m128i output;
   Average2_uint32_SSE2(a0, a1, &output);
-  return _mm_cvtsi128_si32(output);
+  return (uint32_t)_mm_cvtsi128_si32(output);
 }
 
 static WEBP_INLINE uint32_t Average3_SSE2(uint32_t a0, uint32_t a1,
                                           uint32_t a2) {
   const __m128i zero = _mm_setzero_si128();
   const __m128i avg1 = Average2_uint32_16_SSE2(a0, a2);
-  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
   const __m128i sum = _mm_add_epi16(avg1, A1);
   const __m128i avg2 = _mm_srli_epi16(sum, 1);
   const __m128i A2 = _mm_packus_epi16(avg2, avg2);
-  const uint32_t output = _mm_cvtsi128_si32(A2);
-  return output;
+  return (uint32_t)_mm_cvtsi128_si32(A2);
 }
 
 static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
@@ -135,46 +131,54 @@
   const __m128i sum = _mm_add_epi16(avg2, avg1);
   const __m128i avg3 = _mm_srli_epi16(sum, 1);
   const __m128i A0 = _mm_packus_epi16(avg3, avg3);
-  const uint32_t output = _mm_cvtsi128_si32(A0);
-  return output;
+  return (uint32_t)_mm_cvtsi128_si32(A0);
 }
 
-static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average3_SSE2(left, top[0], top[1]);
+static uint32_t Predictor5_SSE2(const uint32_t* const left,
+                                const uint32_t* const top) {
+  const uint32_t pred = Average3_SSE2(*left, top[0], top[1]);
   return pred;
 }
-static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2_SSE2(left, top[-1]);
+static uint32_t Predictor6_SSE2(const uint32_t* const left,
+                                const uint32_t* const top) {
+  const uint32_t pred = Average2_SSE2(*left, top[-1]);
   return pred;
 }
-static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2_SSE2(left, top[0]);
+static uint32_t Predictor7_SSE2(const uint32_t* const left,
+                                const uint32_t* const top) {
+  const uint32_t pred = Average2_SSE2(*left, top[0]);
   return pred;
 }
-static uint32_t Predictor8_SSE2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor8_SSE2(const uint32_t* const left,
+                                const uint32_t* const top) {
   const uint32_t pred = Average2_SSE2(top[-1], top[0]);
   (void)left;
   return pred;
 }
-static uint32_t Predictor9_SSE2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor9_SSE2(const uint32_t* const left,
+                                const uint32_t* const top) {
   const uint32_t pred = Average2_SSE2(top[0], top[1]);
   (void)left;
   return pred;
 }
-static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average4_SSE2(left, top[-1], top[0], top[1]);
+static uint32_t Predictor10_SSE2(const uint32_t* const left,
+                                 const uint32_t* const top) {
+  const uint32_t pred = Average4_SSE2(*left, top[-1], top[0], top[1]);
   return pred;
 }
-static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Select_SSE2(top[0], left, top[-1]);
+static uint32_t Predictor11_SSE2(const uint32_t* const left,
+                                 const uint32_t* const top) {
+  const uint32_t pred = Select_SSE2(top[0], *left, top[-1]);
   return pred;
 }
-static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractFull_SSE2(left, top[0], top[-1]);
+static uint32_t Predictor12_SSE2(const uint32_t* const left,
+                                 const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractFull_SSE2(*left, top[0], top[-1]);
   return pred;
 }
-static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractHalf_SSE2(left, top[0], top[-1]);
+static uint32_t Predictor13_SSE2(const uint32_t* const left,
+                                 const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractHalf_SSE2(*left, top[0], top[-1]);
   return pred;
 }
 
@@ -184,22 +188,23 @@
 static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
                                int num_pixels, uint32_t* out) {
   int i;
-  const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+  const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
     const __m128i res = _mm_add_epi8(src, black);
     _mm_storeu_si128((__m128i*)&out[i], res);
   }
   if (i != num_pixels) {
-    VP8LPredictorsAdd_C[0](in + i, upper + i, num_pixels - i, out + i);
+    VP8LPredictorsAdd_C[0](in + i, NULL, num_pixels - i, out + i);
   }
+  (void)upper;
 }
 
 // Predictor1: left.
 static void PredictorAdd1_SSE2(const uint32_t* in, const uint32_t* upper,
                                int num_pixels, uint32_t* out) {
   int i;
-  __m128i prev = _mm_set1_epi32(out[-1]);
+  __m128i prev = _mm_set1_epi32((int)out[-1]);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     // a | b | c | d
     const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
@@ -276,12 +281,12 @@
 #undef GENERATE_PREDICTOR_2
 
 // Predictor10: average of (average of (L,TL), average of (T, TR)).
-#define DO_PRED10(OUT) do {               \
-  __m128i avgLTL, avg;                    \
-  Average2_m128i(&L, &TL, &avgLTL);       \
-  Average2_m128i(&avgTTR, &avgLTL, &avg); \
-  L = _mm_add_epi8(avg, src);             \
-  out[i + (OUT)] = _mm_cvtsi128_si32(L);  \
+#define DO_PRED10(OUT) do {                         \
+  __m128i avgLTL, avg;                              \
+  Average2_m128i(&L, &TL, &avgLTL);                 \
+  Average2_m128i(&avgTTR, &avgLTL, &avg);           \
+  L = _mm_add_epi8(avg, src);                       \
+  out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L);  \
 } while (0)
 
 #define DO_PRED10_SHIFT do {                                  \
@@ -294,7 +299,7 @@
 static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
                                 int num_pixels, uint32_t* out) {
   int i;
-  __m128i L = _mm_cvtsi32_si128(out[-1]);
+  __m128i L = _mm_cvtsi32_si128((int)out[-1]);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
     __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -327,7 +332,7 @@
   const __m128i B = _mm_andnot_si128(mask, T);                         \
   const __m128i pred = _mm_or_si128(A, B); /* pred = (pa > b)? L : T*/ \
   L = _mm_add_epi8(src, pred);                                         \
-  out[i + (OUT)] = _mm_cvtsi128_si32(L);                               \
+  out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L);                     \
 } while (0)
 
 #define DO_PRED11_SHIFT do {                                \
@@ -342,7 +347,7 @@
                                 int num_pixels, uint32_t* out) {
   int i;
   __m128i pa;
-  __m128i L = _mm_cvtsi32_si128(out[-1]);
+  __m128i L = _mm_cvtsi32_si128((int)out[-1]);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
     __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -375,12 +380,12 @@
 #undef DO_PRED11_SHIFT
 
 // Predictor12: ClampedAddSubtractFull.
-#define DO_PRED12(DIFF, LANE, OUT) do {            \
-  const __m128i all = _mm_add_epi16(L, (DIFF));    \
-  const __m128i alls = _mm_packus_epi16(all, all); \
-  const __m128i res = _mm_add_epi8(src, alls);     \
-  out[i + (OUT)] = _mm_cvtsi128_si32(res);         \
-  L = _mm_unpacklo_epi8(res, zero);                \
+#define DO_PRED12(DIFF, LANE, OUT) do {              \
+  const __m128i all = _mm_add_epi16(L, (DIFF));      \
+  const __m128i alls = _mm_packus_epi16(all, all);   \
+  const __m128i res = _mm_add_epi8(src, alls);       \
+  out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(res); \
+  L = _mm_unpacklo_epi8(res, zero);                  \
 } while (0)
 
 #define DO_PRED12_SHIFT(DIFF, LANE) do {                    \
@@ -393,7 +398,7 @@
                                 int num_pixels, uint32_t* out) {
   int i;
   const __m128i zero = _mm_setzero_si128();
-  const __m128i L8 = _mm_cvtsi32_si128(out[-1]);
+  const __m128i L8 = _mm_cvtsi32_si128((int)out[-1]);
   __m128i L = _mm_unpacklo_epi8(L8, zero);
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     // Load 4 pixels at a time.
@@ -459,7 +464,7 @@
   const __m128i mults_b2 = MK_CST_16(CST(red_to_blue_), 0);
 #undef MK_CST_16
 #undef CST
-  const __m128i mask_ag = _mm_set1_epi32(0xff00ff00);  // alpha-green masks
+  const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00);  // alpha-green masks
   int i;
   for (i = 0; i + 4 <= num_pixels; i += 4) {
     const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb
@@ -523,7 +528,7 @@
 
 static void ConvertBGRAToRGBA_SSE2(const uint32_t* src,
                                    int num_pixels, uint8_t* dst) {
-  const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu);
+  const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ff);
   const __m128i* in = (const __m128i*)src;
   __m128i* out = (__m128i*)dst;
   while (num_pixels >= 8) {
@@ -552,7 +557,7 @@
 static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src,
                                        int num_pixels, uint8_t* dst) {
   const __m128i mask_0x0f = _mm_set1_epi8(0x0f);
-  const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+  const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
   const __m128i* in = (const __m128i*)src;
   __m128i* out = (__m128i*)dst;
   while (num_pixels >= 8) {
@@ -587,8 +592,8 @@
 
 static void ConvertBGRAToRGB565_SSE2(const uint32_t* src,
                                      int num_pixels, uint8_t* dst) {
-  const __m128i mask_0xe0 = _mm_set1_epi8(0xe0);
-  const __m128i mask_0xf8 = _mm_set1_epi8(0xf8);
+  const __m128i mask_0xe0 = _mm_set1_epi8((char)0xe0);
+  const __m128i mask_0xf8 = _mm_set1_epi8((char)0xf8);
   const __m128i mask_0x07 = _mm_set1_epi8(0x07);
   const __m128i* in = (const __m128i*)src;
   __m128i* out = (__m128i*)dst;
diff --git a/third_party/libwebp/src/dsp/lossless_sse41.c b/third_party/libwebp/src/dsp/lossless_sse41.c
new file mode 100644
index 0000000..bb7ce76
--- /dev/null
+++ b/third_party/libwebp/src/dsp/lossless_sse41.c
@@ -0,0 +1,133 @@
+// Copyright 2021 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE41 variant of methods for lossless decoder
+
+#include "src/dsp/dsp.h"
+
+#if defined(WEBP_USE_SSE41)
+
+#include "src/dsp/common_sse41.h"
+#include "src/dsp/lossless.h"
+#include "src/dsp/lossless_common.h"
+
+//------------------------------------------------------------------------------
+// Color-space conversion functions
+
+static void TransformColorInverse_SSE41(const VP8LMultipliers* const m,
+                                        const uint32_t* const src,
+                                        int num_pixels, uint32_t* dst) {
+// sign-extended multiplying constants, pre-shifted by 5.
+#define CST(X)  (((int16_t)(m->X << 8)) >> 5)   // sign-extend
+  const __m128i mults_rb =
+      _mm_set1_epi32((int)((uint32_t)CST(green_to_red_) << 16 |
+                           (CST(green_to_blue_) & 0xffff)));
+  const __m128i mults_b2 = _mm_set1_epi32(CST(red_to_blue_));
+#undef CST
+  const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00);
+  const __m128i perm1 = _mm_setr_epi8(-1, 1, -1, 1, -1, 5, -1, 5,
+                                      -1, 9, -1, 9, -1, 13, -1, 13);
+  const __m128i perm2 = _mm_setr_epi8(-1, 2, -1, -1, -1, 6, -1, -1,
+                                      -1, 10, -1, -1, -1, 14, -1, -1);
+  int i;
+  for (i = 0; i + 4 <= num_pixels; i += 4) {
+    const __m128i A = _mm_loadu_si128((const __m128i*)(src + i));
+    const __m128i B = _mm_shuffle_epi8(A, perm1); // argb -> g0g0
+    const __m128i C = _mm_mulhi_epi16(B, mults_rb);
+    const __m128i D = _mm_add_epi8(A, C);
+    const __m128i E = _mm_shuffle_epi8(D, perm2);
+    const __m128i F = _mm_mulhi_epi16(E, mults_b2);
+    const __m128i G = _mm_add_epi8(D, F);
+    const __m128i out = _mm_blendv_epi8(G, A, mask_ag);
+    _mm_storeu_si128((__m128i*)&dst[i], out);
+  }
+  // Fall-back to C-version for left-overs.
+  if (i != num_pixels) {
+    VP8LTransformColorInverse_C(m, src + i, num_pixels - i, dst + i);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+#define ARGB_TO_RGB_SSE41 do {                        \
+  while (num_pixels >= 16) {                          \
+    const __m128i in0 = _mm_loadu_si128(in + 0);      \
+    const __m128i in1 = _mm_loadu_si128(in + 1);      \
+    const __m128i in2 = _mm_loadu_si128(in + 2);      \
+    const __m128i in3 = _mm_loadu_si128(in + 3);      \
+    const __m128i a0 = _mm_shuffle_epi8(in0, perm0);  \
+    const __m128i a1 = _mm_shuffle_epi8(in1, perm1);  \
+    const __m128i a2 = _mm_shuffle_epi8(in2, perm2);  \
+    const __m128i a3 = _mm_shuffle_epi8(in3, perm3);  \
+    const __m128i b0 = _mm_blend_epi16(a0, a1, 0xc0); \
+    const __m128i b1 = _mm_blend_epi16(a1, a2, 0xf0); \
+    const __m128i b2 = _mm_blend_epi16(a2, a3, 0xfc); \
+    _mm_storeu_si128(out + 0, b0);                    \
+    _mm_storeu_si128(out + 1, b1);                    \
+    _mm_storeu_si128(out + 2, b2);                    \
+    in += 4;                                          \
+    out += 3;                                         \
+    num_pixels -= 16;                                 \
+  }                                                   \
+} while (0)
+
+static void ConvertBGRAToRGB_SSE41(const uint32_t* src, int num_pixels,
+                                   uint8_t* dst) {
+  const __m128i* in = (const __m128i*)src;
+  __m128i* out = (__m128i*)dst;
+  const __m128i perm0 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9,
+                                      8, 14, 13, 12, -1, -1, -1, -1);
+  const __m128i perm1 = _mm_shuffle_epi32(perm0, 0x39);
+  const __m128i perm2 = _mm_shuffle_epi32(perm0, 0x4e);
+  const __m128i perm3 = _mm_shuffle_epi32(perm0, 0x93);
+
+  ARGB_TO_RGB_SSE41;
+
+  // left-overs
+  if (num_pixels > 0) {
+    VP8LConvertBGRAToRGB_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+  }
+}
+
+static void ConvertBGRAToBGR_SSE41(const uint32_t* src,
+                                   int num_pixels, uint8_t* dst) {
+  const __m128i* in = (const __m128i*)src;
+  __m128i* out = (__m128i*)dst;
+  const __m128i perm0 = _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 10,
+                                      12, 13, 14, -1, -1, -1, -1);
+  const __m128i perm1 = _mm_shuffle_epi32(perm0, 0x39);
+  const __m128i perm2 = _mm_shuffle_epi32(perm0, 0x4e);
+  const __m128i perm3 = _mm_shuffle_epi32(perm0, 0x93);
+
+  ARGB_TO_RGB_SSE41;
+
+  // left-overs
+  if (num_pixels > 0) {
+    VP8LConvertBGRAToBGR_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+  }
+}
+
+#undef ARGB_TO_RGB_SSE41
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8LDspInitSSE41(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitSSE41(void) {
+  VP8LTransformColorInverse = TransformColorInverse_SSE41;
+  VP8LConvertBGRAToRGB = ConvertBGRAToRGB_SSE41;
+  VP8LConvertBGRAToBGR = ConvertBGRAToBGR_SSE41;
+}
+
+#else  // !WEBP_USE_SSE41
+
+WEBP_DSP_INIT_STUB(VP8LDspInitSSE41)
+
+#endif  // WEBP_USE_SSE41
diff --git a/third_party/libwebp/src/dsp/msa_macro.h b/third_party/libwebp/src/dsp/msa_macro.h
index dfacda6..51f6c64 100644
--- a/third_party/libwebp/src/dsp/msa_macro.h
+++ b/third_party/libwebp/src/dsp/msa_macro.h
@@ -14,6 +14,10 @@
 #ifndef WEBP_DSP_MSA_MACRO_H_
 #define WEBP_DSP_MSA_MACRO_H_
 
+#include "src/dsp/dsp.h"
+
+#if defined(WEBP_USE_MSA)
+
 #include <stdint.h>
 #include <msa.h>
 
@@ -1389,4 +1393,5 @@
 } while (0)
 #define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
 
-#endif  /* WEBP_DSP_MSA_MACRO_H_ */
+#endif  // WEBP_USE_MSA
+#endif  // WEBP_DSP_MSA_MACRO_H_
diff --git a/third_party/libwebp/src/dsp/neon.h b/third_party/libwebp/src/dsp/neon.h
index aa1dea1..14acb40 100644
--- a/third_party/libwebp/src/dsp/neon.h
+++ b/third_party/libwebp/src/dsp/neon.h
@@ -12,14 +12,16 @@
 #ifndef WEBP_DSP_NEON_H_
 #define WEBP_DSP_NEON_H_
 
-#include <arm_neon.h>
-
 #include "src/dsp/dsp.h"
 
+#if defined(WEBP_USE_NEON)
+
+#include <arm_neon.h>
+
 // Right now, some intrinsics functions seem slower, so we disable them
 // everywhere except newer clang/gcc or aarch64 where the inline assembly is
 // incompatible.
-#if LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,9) || defined(__aarch64__)
+#if LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 9) || WEBP_AARCH64
 #define WEBP_USE_INTRINSICS   // use intrinsics when possible
 #endif
 
@@ -44,7 +46,7 @@
 // if using intrinsics, this flag avoids some functions that make gcc-4.6.3
 // crash ("internal compiler error: in immed_double_const, at emit-rtl.").
 // (probably similar to gcc.gnu.org/bugzilla/show_bug.cgi?id=48183)
-#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
+#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
 #define WORK_AROUND_GCC
 #endif
 
@@ -98,4 +100,5 @@
 } while (0)
 #endif
 
+#endif  // WEBP_USE_NEON
 #endif  // WEBP_DSP_NEON_H_
diff --git a/third_party/libwebp/src/dsp/quant.h b/third_party/libwebp/src/dsp/quant.h
new file mode 100644
index 0000000..bf7734c
--- /dev/null
+++ b/third_party/libwebp/src/dsp/quant.h
@@ -0,0 +1,90 @@
+// Copyright 2018 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+
+#ifndef WEBP_DSP_QUANT_H_
+#define WEBP_DSP_QUANT_H_
+
+#include <string.h>
+
+#include "src/dsp/dsp.h"
+#include "src/webp/types.h"
+
+#if defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && \
+    !defined(WEBP_HAVE_NEON_RTCD)
+#include <arm_neon.h>
+
+#define IsFlat IsFlat_NEON
+
+static uint32_t horizontal_add_uint32x4(const uint32x4_t a) {
+#if WEBP_AARCH64
+  return vaddvq_u32(a);
+#else
+  const uint64x2_t b = vpaddlq_u32(a);
+  const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
+                                vreinterpret_u32_u64(vget_high_u64(b)));
+  return vget_lane_u32(c, 0);
+#endif
+}
+
+static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
+                              int thresh) {
+  const int16x8_t tst_ones = vdupq_n_s16(-1);
+  uint32x4_t sum = vdupq_n_u32(0);
+
+  for (int i = 0; i < num_blocks; ++i) {
+    // Set DC to zero.
+    const int16x8_t a_0 = vsetq_lane_s16(0, vld1q_s16(levels), 0);
+    const int16x8_t a_1 = vld1q_s16(levels + 8);
+
+    const uint16x8_t b_0 = vshrq_n_u16(vtstq_s16(a_0, tst_ones), 15);
+    const uint16x8_t b_1 = vshrq_n_u16(vtstq_s16(a_1, tst_ones), 15);
+
+    sum = vpadalq_u16(sum, b_0);
+    sum = vpadalq_u16(sum, b_1);
+
+    levels += 16;
+  }
+  return thresh >= (int)horizontal_add_uint32x4(sum);
+}
+
+#else
+
+#define IsFlat IsFlat_C
+
+static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
+                              int thresh) {
+  int score = 0;
+  while (num_blocks-- > 0) {      // TODO(skal): refine positional scoring?
+    int i;
+    for (i = 1; i < 16; ++i) {    // omit DC, we're only interested in AC
+      score += (levels[i] != 0);
+      if (score > thresh) return 0;
+    }
+    levels += 16;
+  }
+  return 1;
+}
+
+#endif  // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) &&
+        // !defined(WEBP_HAVE_NEON_RTCD)
+
+static WEBP_INLINE int IsFlatSource16(const uint8_t* src) {
+  const uint32_t v = src[0] * 0x01010101u;
+  int i;
+  for (i = 0; i < 16; ++i) {
+    if (memcmp(src + 0, &v, 4) || memcmp(src +  4, &v, 4) ||
+        memcmp(src + 8, &v, 4) || memcmp(src + 12, &v, 4)) {
+      return 0;
+    }
+    src += BPS;
+  }
+  return 1;
+}
+
+#endif  // WEBP_DSP_QUANT_H_
diff --git a/third_party/libwebp/src/dsp/rescaler.c b/third_party/libwebp/src/dsp/rescaler.c
index bd3e143..440b07d 100644
--- a/third_party/libwebp/src/dsp/rescaler.c
+++ b/third_party/libwebp/src/dsp/rescaler.c
@@ -25,6 +25,7 @@
 
 #define ROUNDER (WEBP_RESCALER_ONE >> 1)
 #define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+#define MULT_FIX_FLOOR(x, y) (((uint64_t)(x) * (y)) >> WEBP_RESCALER_RFIX)
 
 //------------------------------------------------------------------------------
 // Row import
@@ -41,8 +42,9 @@
     int x_out = channel;
     // simple bilinear interpolation
     int accum = wrk->x_add;
-    int left = src[x_in];
-    int right = (wrk->src_width > 1) ? src[x_in + x_stride] : left;
+    rescaler_t left = (rescaler_t)src[x_in];
+    rescaler_t right =
+        (wrk->src_width > 1) ? (rescaler_t)src[x_in + x_stride] : left;
     x_in += x_stride;
     while (1) {
       wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
@@ -53,7 +55,7 @@
         left = right;
         x_in += x_stride;
         assert(x_in < wrk->src_width * x_stride);
-        right = src[x_in];
+        right = (rescaler_t)src[x_in];
         accum += wrk->x_add;
       }
     }
@@ -112,8 +114,7 @@
     for (x_out = 0; x_out < x_out_max; ++x_out) {
       const uint32_t J = frow[x_out];
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   } else {
     const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@@ -123,8 +124,7 @@
                        + (uint64_t)B * irow[x_out];
       const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
@@ -141,22 +141,21 @@
   assert(!wrk->y_expand);
   if (yscale) {
     for (x_out = 0; x_out < x_out_max; ++x_out) {
-      const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale);
+      const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale);
       const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = frac;   // new fractional start
     }
   } else {
     for (x_out = 0; x_out < x_out_max; ++x_out) {
       const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = 0;
     }
   }
 }
 
+#undef MULT_FIX_FLOOR
 #undef MULT_FIX
 #undef ROUNDER
 
@@ -202,6 +201,7 @@
 WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
 WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void WebPRescalerDspInitSSE2(void);
 extern void WebPRescalerDspInitMIPS32(void);
 extern void WebPRescalerDspInitMIPSdspR2(void);
@@ -219,7 +219,7 @@
   WebPRescalerImportRowShrink = WebPRescalerImportRowShrink_C;
 
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPRescalerDspInitSSE2();
     }
@@ -241,7 +241,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     WebPRescalerDspInitNEON();
diff --git a/third_party/libwebp/src/dsp/rescaler_mips32.c b/third_party/libwebp/src/dsp/rescaler_mips32.c
index 542f7e5..61f63c6 100644
--- a/third_party/libwebp/src/dsp/rescaler_mips32.c
+++ b/third_party/libwebp/src/dsp/rescaler_mips32.c
@@ -209,6 +209,7 @@
   }
 }
 
+#if 0  // disabled for now. TODO(skal): make match the C-code
 static void ExportRowShrink_MIPS32(WebPRescaler* const wrk) {
   const int x_out_max = wrk->dst_width * wrk->num_channels;
   uint8_t* dst = wrk->dst;
@@ -273,6 +274,7 @@
     );
   }
 }
+#endif  // 0
 
 //------------------------------------------------------------------------------
 // Entry point
@@ -283,7 +285,7 @@
   WebPRescalerImportRowExpand = ImportRowExpand_MIPS32;
   WebPRescalerImportRowShrink = ImportRowShrink_MIPS32;
   WebPRescalerExportRowExpand = ExportRowExpand_MIPS32;
-  WebPRescalerExportRowShrink = ExportRowShrink_MIPS32;
+//  WebPRescalerExportRowShrink = ExportRowShrink_MIPS32;
 }
 
 #else  // !WEBP_USE_MIPS32
diff --git a/third_party/libwebp/src/dsp/rescaler_mips_dsp_r2.c b/third_party/libwebp/src/dsp/rescaler_mips_dsp_r2.c
index b78aac1..419b741 100644
--- a/third_party/libwebp/src/dsp/rescaler_mips_dsp_r2.c
+++ b/third_party/libwebp/src/dsp/rescaler_mips_dsp_r2.c
@@ -20,10 +20,12 @@
 
 #define ROUNDER (WEBP_RESCALER_ONE >> 1)
 #define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+#define MULT_FIX_FLOOR(x, y) (((uint64_t)(x) * (y)) >> WEBP_RESCALER_RFIX)
 
 //------------------------------------------------------------------------------
 // Row export
 
+#if 0  // disabled for now. TODO(skal): make match the C-code
 static void ExportRowShrink_MIPSdspR2(WebPRescaler* const wrk) {
   int i;
   const int x_out_max = wrk->dst_width * wrk->num_channels;
@@ -105,10 +107,9 @@
       );
     }
     for (i = 0; i < (x_out_max & 0x3); ++i) {
-      const uint32_t frac = (uint32_t)MULT_FIX(*frow++, yscale);
+      const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(*frow++, yscale);
       const int v = (int)MULT_FIX(*irow - frac, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      *dst++ = v;
+      *dst++ = (v > 255) ? 255u : (uint8_t)v;
       *irow++ = frac;   // new fractional start
     }
   } else {
@@ -154,13 +155,13 @@
       );
     }
     for (i = 0; i < (x_out_max & 0x3); ++i) {
-      const int v = (int)MULT_FIX(*irow, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      *dst++ = v;
+      const int v = (int)MULT_FIX_FLOOR(*irow, wrk->fxy_scale);
+      *dst++ = (v > 255) ? 255u : (uint8_t)v;
       *irow++ = 0;
     }
   }
 }
+#endif  // 0
 
 static void ExportRowExpand_MIPSdspR2(WebPRescaler* const wrk) {
   int i;
@@ -216,8 +217,7 @@
     for (i = 0; i < (x_out_max & 0x3); ++i) {
       const uint32_t J = *frow++;
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      *dst++ = v;
+      *dst++ = (v > 255) ? 255u : (uint8_t)v;
     }
   } else {
     const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@@ -288,12 +288,12 @@
                        + (uint64_t)B * *irow++;
       const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      *dst++ = v;
+      *dst++ = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
 
+#undef MULT_FIX_FLOOR
 #undef MULT_FIX
 #undef ROUNDER
 
@@ -304,7 +304,7 @@
 
 WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPSdspR2(void) {
   WebPRescalerExportRowExpand = ExportRowExpand_MIPSdspR2;
-  WebPRescalerExportRowShrink = ExportRowShrink_MIPSdspR2;
+//  WebPRescalerExportRowShrink = ExportRowShrink_MIPSdspR2;
 }
 
 #else  // !WEBP_USE_MIPS_DSP_R2
diff --git a/third_party/libwebp/src/dsp/rescaler_msa.c b/third_party/libwebp/src/dsp/rescaler_msa.c
index f3bc99f..256dbdd 100644
--- a/third_party/libwebp/src/dsp/rescaler_msa.c
+++ b/third_party/libwebp/src/dsp/rescaler_msa.c
@@ -22,6 +22,7 @@
 
 #define ROUNDER (WEBP_RESCALER_ONE >> 1)
 #define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+#define MULT_FIX_FLOOR(x, y) (((uint64_t)(x) * (y)) >> WEBP_RESCALER_RFIX)
 
 #define CALC_MULT_FIX_16(in0, in1, in2, in3, scale, shift, dst) do {  \
   v4u32 tmp0, tmp1, tmp2, tmp3;                                       \
@@ -165,8 +166,7 @@
     for (x_out = 0; x_out < length; ++x_out) {
       const uint32_t J = frow[x_out];
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
@@ -240,8 +240,7 @@
                        + (uint64_t)B * irow[x_out];
       const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
@@ -262,6 +261,7 @@
   }
 }
 
+#if 0  // disabled for now. TODO(skal): make match the C-code
 static WEBP_INLINE void ExportRowShrink_0(const uint32_t* frow, uint32_t* irow,
                                           uint8_t* dst, int length,
                                           const uint32_t yscale,
@@ -340,10 +340,9 @@
       length -= 4;
     }
     for (x_out = 0; x_out < length; ++x_out) {
-      const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale);
+      const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale);
       const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = frac;
     }
   }
@@ -404,8 +403,7 @@
     }
     for (x_out = 0; x_out < length; ++x_out) {
       const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = 0;
     }
   }
@@ -426,6 +424,7 @@
     ExportRowShrink_1(irow, dst, x_out_max, wrk);
   }
 }
+#endif  // 0
 
 //------------------------------------------------------------------------------
 // Entry point
@@ -434,7 +433,7 @@
 
 WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMSA(void) {
   WebPRescalerExportRowExpand = RescalerExportRowExpand_MIPSdspR2;
-  WebPRescalerExportRowShrink = RescalerExportRowShrink_MIPSdspR2;
+//  WebPRescalerExportRowShrink = RescalerExportRowShrink_MIPSdspR2;
 }
 
 #else     // !WEBP_USE_MSA
diff --git a/third_party/libwebp/src/dsp/rescaler_neon.c b/third_party/libwebp/src/dsp/rescaler_neon.c
index 3eff9fb..b976a85 100644
--- a/third_party/libwebp/src/dsp/rescaler_neon.c
+++ b/third_party/libwebp/src/dsp/rescaler_neon.c
@@ -22,6 +22,7 @@
 
 #define ROUNDER (WEBP_RESCALER_ONE >> 1)
 #define MULT_FIX_C(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+#define MULT_FIX_FLOOR_C(x, y) (((uint64_t)(x) * (y)) >> WEBP_RESCALER_RFIX)
 
 #define LOAD_32x4(SRC, DST) const uint32x4_t DST = vld1q_u32((SRC))
 #define LOAD_32x8(SRC, DST0, DST1)                                    \
@@ -35,8 +36,11 @@
 
 #if (WEBP_RESCALER_RFIX == 32)
 #define MAKE_HALF_CST(C) vdupq_n_s32((int32_t)((C) >> 1))
-#define MULT_FIX(A, B) /* note: B is actualy scale>>1. See MAKE_HALF_CST */ \
+// note: B is actualy scale>>1. See MAKE_HALF_CST
+#define MULT_FIX(A, B) \
     vreinterpretq_u32_s32(vqrdmulhq_s32(vreinterpretq_s32_u32((A)), (B)))
+#define MULT_FIX_FLOOR(A, B) \
+    vreinterpretq_u32_s32(vqdmulhq_s32(vreinterpretq_s32_u32((A)), (B)))
 #else
 #error "MULT_FIX/WEBP_RESCALER_RFIX need some more work"
 #endif
@@ -77,14 +81,13 @@
       const uint32x4_t B1 = MULT_FIX(A1, fy_scale_half);
       const uint16x4_t C0 = vmovn_u32(B0);
       const uint16x4_t C1 = vmovn_u32(B1);
-      const uint8x8_t D = vmovn_u16(vcombine_u16(C0, C1));
+      const uint8x8_t D = vqmovn_u16(vcombine_u16(C0, C1));
       vst1_u8(dst + x_out, D);
     }
     for (; x_out < x_out_max; ++x_out) {
       const uint32_t J = frow[x_out];
       const int v = (int)MULT_FIX_C(J, fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   } else {
     const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@@ -98,7 +101,7 @@
       const uint32x4_t D1 = MULT_FIX(C1, fy_scale_half);
       const uint16x4_t E0 = vmovn_u32(D0);
       const uint16x4_t E1 = vmovn_u32(D1);
-      const uint8x8_t F = vmovn_u16(vcombine_u16(E0, E1));
+      const uint8x8_t F = vqmovn_u16(vcombine_u16(E0, E1));
       vst1_u8(dst + x_out, F);
     }
     for (; x_out < x_out_max; ++x_out) {
@@ -106,8 +109,7 @@
                        + (uint64_t)B * irow[x_out];
       const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
       const int v = (int)MULT_FIX_C(J, fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
@@ -131,23 +133,22 @@
     for (x_out = 0; x_out < max_span; x_out += 8) {
       LOAD_32x8(frow + x_out, in0, in1);
       LOAD_32x8(irow + x_out, in2, in3);
-      const uint32x4_t A0 = MULT_FIX(in0, yscale_half);
-      const uint32x4_t A1 = MULT_FIX(in1, yscale_half);
+      const uint32x4_t A0 = MULT_FIX_FLOOR(in0, yscale_half);
+      const uint32x4_t A1 = MULT_FIX_FLOOR(in1, yscale_half);
       const uint32x4_t B0 = vqsubq_u32(in2, A0);
       const uint32x4_t B1 = vqsubq_u32(in3, A1);
       const uint32x4_t C0 = MULT_FIX(B0, fxy_scale_half);
       const uint32x4_t C1 = MULT_FIX(B1, fxy_scale_half);
       const uint16x4_t D0 = vmovn_u32(C0);
       const uint16x4_t D1 = vmovn_u32(C1);
-      const uint8x8_t E = vmovn_u16(vcombine_u16(D0, D1));
+      const uint8x8_t E = vqmovn_u16(vcombine_u16(D0, D1));
       vst1_u8(dst + x_out, E);
       STORE_32x8(A0, A1, irow + x_out);
     }
     for (; x_out < x_out_max; ++x_out) {
-      const uint32_t frac = (uint32_t)MULT_FIX_C(frow[x_out], yscale);
-      const int v = (int)MULT_FIX_C(irow[x_out] - frac, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      const uint32_t frac = (uint32_t)MULT_FIX_FLOOR_C(frow[x_out], yscale);
+      const int v = (int)MULT_FIX_C(irow[x_out] - frac, fxy_scale);
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = frac;   // new fractional start
     }
   } else {
@@ -157,19 +158,24 @@
       const uint32x4_t A1 = MULT_FIX(in1, fxy_scale_half);
       const uint16x4_t B0 = vmovn_u32(A0);
       const uint16x4_t B1 = vmovn_u32(A1);
-      const uint8x8_t C = vmovn_u16(vcombine_u16(B0, B1));
+      const uint8x8_t C = vqmovn_u16(vcombine_u16(B0, B1));
       vst1_u8(dst + x_out, C);
       STORE_32x8(zero, zero, irow + x_out);
     }
     for (; x_out < x_out_max; ++x_out) {
       const int v = (int)MULT_FIX_C(irow[x_out], fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = 0;
     }
   }
 }
 
+#undef MULT_FIX_FLOOR_C
+#undef MULT_FIX_C
+#undef MULT_FIX_FLOOR
+#undef MULT_FIX
+#undef ROUNDER
+
 //------------------------------------------------------------------------------
 
 extern void WebPRescalerDspInitNEON(void);
diff --git a/third_party/libwebp/src/dsp/rescaler_sse2.c b/third_party/libwebp/src/dsp/rescaler_sse2.c
index 64c50de..3f18e94 100644
--- a/third_party/libwebp/src/dsp/rescaler_sse2.c
+++ b/third_party/libwebp/src/dsp/rescaler_sse2.c
@@ -25,6 +25,7 @@
 
 #define ROUNDER (WEBP_RESCALER_ONE >> 1)
 #define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+#define MULT_FIX_FLOOR(x, y) (((uint64_t)(x) * (y)) >> WEBP_RESCALER_RFIX)
 
 // input: 8 bytes ABCDEFGH -> output: A0E0B0F0C0G0D0H0
 static void LoadTwoPixels_SSE2(const uint8_t* const src, __m128i* out) {
@@ -84,7 +85,7 @@
       const __m128i mult = _mm_cvtsi32_si128(((x_add - accum) << 16) | accum);
       const __m128i out = _mm_madd_epi16(cur_pixels, mult);
       assert(sizeof(*frow) == sizeof(uint32_t));
-      WebPUint32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
+      WebPInt32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
       frow += 1;
       if (frow >= frow_end) break;
       accum -= wrk->x_sub;
@@ -131,7 +132,7 @@
     __m128i base = zero;
     accum += wrk->x_add;
     while (accum > 0) {
-      const __m128i A = _mm_cvtsi32_si128(WebPMemToUint32(src));
+      const __m128i A = _mm_cvtsi32_si128(WebPMemToInt32(src));
       src += 4;
       base = _mm_unpacklo_epi8(A, zero);
       // To avoid overflow, we need: base * x_add / x_sub < 32768
@@ -197,7 +198,7 @@
                                         const __m128i* const mult,
                                         uint8_t* const dst) {
   const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
-  const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0);
+  const __m128i mask = _mm_set_epi32(~0, 0, ~0, 0);
   const __m128i B0 = _mm_mul_epu32(*A0, *mult);
   const __m128i B1 = _mm_mul_epu32(*A1, *mult);
   const __m128i B2 = _mm_mul_epu32(*A2, *mult);
@@ -244,8 +245,7 @@
     for (; x_out < x_out_max; ++x_out) {
       const uint32_t J = frow[x_out];
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   } else {
     const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@@ -278,8 +278,7 @@
                        + (uint64_t)B * irow[x_out];
       const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
       const int v = (int)MULT_FIX(J, wrk->fy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
     }
   }
 }
@@ -298,20 +297,15 @@
     const int scale_xy = wrk->fxy_scale;
     const __m128i mult_xy = _mm_set_epi32(0, scale_xy, 0, scale_xy);
     const __m128i mult_y = _mm_set_epi32(0, yscale, 0, yscale);
-    const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
     for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
       __m128i A0, A1, A2, A3, B0, B1, B2, B3;
       LoadDispatchAndMult_SSE2(irow + x_out, NULL, &A0, &A1, &A2, &A3);
       LoadDispatchAndMult_SSE2(frow + x_out, &mult_y, &B0, &B1, &B2, &B3);
       {
-        const __m128i C0 = _mm_add_epi64(B0, rounder);
-        const __m128i C1 = _mm_add_epi64(B1, rounder);
-        const __m128i C2 = _mm_add_epi64(B2, rounder);
-        const __m128i C3 = _mm_add_epi64(B3, rounder);
-        const __m128i D0 = _mm_srli_epi64(C0, WEBP_RESCALER_RFIX);   // = frac
-        const __m128i D1 = _mm_srli_epi64(C1, WEBP_RESCALER_RFIX);
-        const __m128i D2 = _mm_srli_epi64(C2, WEBP_RESCALER_RFIX);
-        const __m128i D3 = _mm_srli_epi64(C3, WEBP_RESCALER_RFIX);
+        const __m128i D0 = _mm_srli_epi64(B0, WEBP_RESCALER_RFIX);   // = frac
+        const __m128i D1 = _mm_srli_epi64(B1, WEBP_RESCALER_RFIX);
+        const __m128i D2 = _mm_srli_epi64(B2, WEBP_RESCALER_RFIX);
+        const __m128i D3 = _mm_srli_epi64(B3, WEBP_RESCALER_RFIX);
         const __m128i E0 = _mm_sub_epi64(A0, D0);   // irow[x] - frac
         const __m128i E1 = _mm_sub_epi64(A1, D1);
         const __m128i E2 = _mm_sub_epi64(A2, D2);
@@ -326,10 +320,9 @@
       }
     }
     for (; x_out < x_out_max; ++x_out) {
-      const uint32_t frac = (int)MULT_FIX(frow[x_out], yscale);
+      const uint32_t frac = (int)MULT_FIX_FLOOR(frow[x_out], yscale);
       const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = frac;   // new fractional start
     }
   } else {
@@ -345,13 +338,13 @@
     }
     for (; x_out < x_out_max; ++x_out) {
       const int v = (int)MULT_FIX(irow[x_out], scale);
-      assert(v >= 0 && v <= 255);
-      dst[x_out] = v;
+      dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
       irow[x_out] = 0;
     }
   }
 }
 
+#undef MULT_FIX_FLOOR
 #undef MULT_FIX
 #undef ROUNDER
 
diff --git a/third_party/libwebp/src/dsp/ssim.c b/third_party/libwebp/src/dsp/ssim.c
index 989ce82..9a1341e 100644
--- a/third_party/libwebp/src/dsp/ssim.c
+++ b/third_party/libwebp/src/dsp/ssim.c
@@ -137,6 +137,7 @@
 VP8AccumulateSSEFunc VP8AccumulateSSE;
 #endif
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8SSIMDspInitSSE2(void);
 
 WEBP_DSP_INIT_FUNC(VP8SSIMDspInit) {
@@ -150,7 +151,7 @@
 #endif
 
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       VP8SSIMDspInitSSE2();
     }
diff --git a/third_party/libwebp/src/dsp/upsampling.c b/third_party/libwebp/src/dsp/upsampling.c
index 9b60da5..983b9c4 100644
--- a/third_party/libwebp/src/dsp/upsampling.c
+++ b/third_party/libwebp/src/dsp/upsampling.c
@@ -215,6 +215,7 @@
 
 WebPYUV444Converter WebPYUV444Converters[MODE_LAST];
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void WebPInitYUV444ConvertersMIPSdspR2(void);
 extern void WebPInitYUV444ConvertersSSE2(void);
 extern void WebPInitYUV444ConvertersSSE41(void);
@@ -233,12 +234,12 @@
   WebPYUV444Converters[MODE_rgbA_4444] = WebPYuv444ToRgba4444_C;
 
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPInitYUV444ConvertersSSE2();
     }
 #endif
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
     if (VP8GetCPUInfo(kSSE4_1)) {
       WebPInitYUV444ConvertersSSE41();
     }
@@ -278,12 +279,12 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPInitUpsamplersSSE2();
     }
 #endif
-#if defined(WEBP_USE_SSE41)
+#if defined(WEBP_HAVE_SSE41)
     if (VP8GetCPUInfo(kSSE4_1)) {
       WebPInitUpsamplersSSE41();
     }
@@ -300,7 +301,7 @@
 #endif
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     WebPInitUpsamplersNEON();
diff --git a/third_party/libwebp/src/dsp/upsampling_msa.c b/third_party/libwebp/src/dsp/upsampling_msa.c
index d5bf4db..aa50c39 100644
--- a/third_party/libwebp/src/dsp/upsampling_msa.c
+++ b/third_party/libwebp/src/dsp/upsampling_msa.c
@@ -580,9 +580,9 @@
   const uint32_t l_uv = ((cur_u[0]) | ((cur_v[0]) << 16));               \
   const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;            \
   const uint8_t* ptop_y = &top_y[1];                                     \
-  uint8_t *ptop_dst = top_dst + XSTEP;                                   \
+  uint8_t* ptop_dst = top_dst + XSTEP;                                   \
   const uint8_t* pbot_y = &bot_y[1];                                     \
-  uint8_t *pbot_dst = bot_dst + XSTEP;                                   \
+  uint8_t* pbot_dst = bot_dst + XSTEP;                                   \
                                                                          \
   FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst);                      \
   if (bot_y != NULL) {                                                   \
diff --git a/third_party/libwebp/src/dsp/upsampling_neon.c b/third_party/libwebp/src/dsp/upsampling_neon.c
index ff05bab..f104697 100644
--- a/third_party/libwebp/src/dsp/upsampling_neon.c
+++ b/third_party/libwebp/src/dsp/upsampling_neon.c
@@ -64,8 +64,8 @@
 } while (0)
 
 // Turn the macro into a function for reducing code-size when non-critical
-static void Upsample16Pixels_NEON(const uint8_t *r1, const uint8_t *r2,
-                                  uint8_t *out) {
+static void Upsample16Pixels_NEON(const uint8_t* r1, const uint8_t* r2,
+                                  uint8_t* out) {
   UPSAMPLE_16PIXELS(r1, r2, out);
 }
 
@@ -117,7 +117,7 @@
   vst4_u8(out, v255_r_g_b);                                             \
 } while (0)
 
-#if !defined(WEBP_SWAP_16BIT_CSP)
+#if (WEBP_SWAP_16BIT_CSP == 0)
 #define ZIP_U8(lo, hi) vzip_u8((lo), (hi))
 #else
 #define ZIP_U8(lo, hi) vzip_u8((hi), (lo))
@@ -196,14 +196,14 @@
 }
 
 #define NEON_UPSAMPLE_FUNC(FUNC_NAME, FMT, XSTEP)                       \
-static void FUNC_NAME(const uint8_t *top_y, const uint8_t *bottom_y,    \
-                      const uint8_t *top_u, const uint8_t *top_v,       \
-                      const uint8_t *cur_u, const uint8_t *cur_v,       \
-                      uint8_t *top_dst, uint8_t *bottom_dst, int len) { \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,    \
+                      const uint8_t* top_u, const uint8_t* top_v,       \
+                      const uint8_t* cur_u, const uint8_t* cur_v,       \
+                      uint8_t* top_dst, uint8_t* bottom_dst, int len) { \
   int block;                                                            \
   /* 16 byte aligned array to cache reconstructed u and v */            \
   uint8_t uv_buf[2 * 32 + 15];                                          \
-  uint8_t *const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);     \
+  uint8_t* const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);     \
   const int uv_len = (len + 1) >> 1;                                    \
   /* 9 pixels must be read-able for each block */                       \
   const int num_blocks = (uv_len - 1) >> 3;                             \
diff --git a/third_party/libwebp/src/dsp/upsampling_sse2.c b/third_party/libwebp/src/dsp/upsampling_sse2.c
index 45a3746..9a81ae7 100644
--- a/third_party/libwebp/src/dsp/upsampling_sse2.c
+++ b/third_party/libwebp/src/dsp/upsampling_sse2.c
@@ -127,7 +127,7 @@
   int uv_pos, pos;                                                             \
   /* 16byte-aligned array to cache reconstructed u and v */                    \
   uint8_t uv_buf[14 * 32 + 15] = { 0 };                                        \
-  uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);             \
+  uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~(uintptr_t)15);  \
   uint8_t* const r_v = r_u + 32;                                               \
                                                                                \
   assert(top_y != NULL);                                                       \
diff --git a/third_party/libwebp/src/dsp/yuv.c b/third_party/libwebp/src/dsp/yuv.c
index 0567aaa..cec404a 100644
--- a/third_party/libwebp/src/dsp/yuv.c
+++ b/third_party/libwebp/src/dsp/yuv.c
@@ -70,6 +70,7 @@
 
 WebPSamplerRowFunc WebPSamplers[MODE_LAST];
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void WebPInitSamplersSSE2(void);
 extern void WebPInitSamplersSSE41(void);
 extern void WebPInitSamplersMIPS32(void);
@@ -90,16 +91,16 @@
 
   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPInitSamplersSSE2();
     }
-#endif  // WEBP_USE_SSE2
-#if defined(WEBP_USE_SSE41)
+#endif  // WEBP_HAVE_SSE2
+#if defined(WEBP_HAVE_SSE41)
     if (VP8GetCPUInfo(kSSE4_1)) {
       WebPInitSamplersSSE41();
     }
-#endif  // WEBP_USE_SSE41
+#endif  // WEBP_HAVE_SSE41
 #if defined(WEBP_USE_MIPS32)
     if (VP8GetCPUInfo(kMIPS32)) {
       WebPInitSamplersMIPS32();
@@ -202,50 +203,6 @@
 
 //-----------------------------------------------------------------------------
 
-#if !WEBP_NEON_OMIT_C_CODE
-#define MAX_Y ((1 << 10) - 1)    // 10b precision over 16b-arithmetic
-static uint16_t clip_y(int v) {
-  return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
-}
-
-static uint64_t SharpYUVUpdateY_C(const uint16_t* ref, const uint16_t* src,
-                                  uint16_t* dst, int len) {
-  uint64_t diff = 0;
-  int i;
-  for (i = 0; i < len; ++i) {
-    const int diff_y = ref[i] - src[i];
-    const int new_y = (int)dst[i] + diff_y;
-    dst[i] = clip_y(new_y);
-    diff += (uint64_t)abs(diff_y);
-  }
-  return diff;
-}
-
-static void SharpYUVUpdateRGB_C(const int16_t* ref, const int16_t* src,
-                                int16_t* dst, int len) {
-  int i;
-  for (i = 0; i < len; ++i) {
-    const int diff_uv = ref[i] - src[i];
-    dst[i] += diff_uv;
-  }
-}
-
-static void SharpYUVFilterRow_C(const int16_t* A, const int16_t* B, int len,
-                                const uint16_t* best_y, uint16_t* out) {
-  int i;
-  for (i = 0; i < len; ++i, ++A, ++B) {
-    const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4;
-    const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4;
-    out[2 * i + 0] = clip_y(best_y[2 * i + 0] + v0);
-    out[2 * i + 1] = clip_y(best_y[2 * i + 1] + v1);
-  }
-}
-#endif  // !WEBP_NEON_OMIT_C_CODE
-
-#undef MAX_Y
-
-//-----------------------------------------------------------------------------
-
 void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width);
 void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width);
 void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb,
@@ -255,18 +212,9 @@
 void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
                             int src_width, int do_store);
 
-uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* ref, const uint16_t* src,
-                                uint16_t* dst, int len);
-void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src,
-                              int16_t* dst, int len);
-void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len,
-                              const uint16_t* best_y, uint16_t* out);
-
 extern void WebPInitConvertARGBToYUVSSE2(void);
 extern void WebPInitConvertARGBToYUVSSE41(void);
 extern void WebPInitConvertARGBToYUVNEON(void);
-extern void WebPInitSharpYUVSSE2(void);
-extern void WebPInitSharpYUVNEON(void);
 
 WEBP_DSP_INIT_FUNC(WebPInitConvertARGBToYUV) {
   WebPConvertARGBToY = ConvertARGBToY_C;
@@ -277,40 +225,29 @@
 
   WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C;
 
-#if !WEBP_NEON_OMIT_C_CODE
-  WebPSharpYUVUpdateY = SharpYUVUpdateY_C;
-  WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_C;
-  WebPSharpYUVFilterRow = SharpYUVFilterRow_C;
-#endif
-
   if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
+#if defined(WEBP_HAVE_SSE2)
     if (VP8GetCPUInfo(kSSE2)) {
       WebPInitConvertARGBToYUVSSE2();
-      WebPInitSharpYUVSSE2();
     }
-#endif  // WEBP_USE_SSE2
-#if defined(WEBP_USE_SSE41)
+#endif  // WEBP_HAVE_SSE2
+#if defined(WEBP_HAVE_SSE41)
     if (VP8GetCPUInfo(kSSE4_1)) {
       WebPInitConvertARGBToYUVSSE41();
     }
-#endif  // WEBP_USE_SSE41
+#endif  // WEBP_HAVE_SSE41
   }
 
-#if defined(WEBP_USE_NEON)
+#if defined(WEBP_HAVE_NEON)
   if (WEBP_NEON_OMIT_C_CODE ||
       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
     WebPInitConvertARGBToYUVNEON();
-    WebPInitSharpYUVNEON();
   }
-#endif  // WEBP_USE_NEON
+#endif  // WEBP_HAVE_NEON
 
   assert(WebPConvertARGBToY != NULL);
   assert(WebPConvertARGBToUV != NULL);
   assert(WebPConvertRGB24ToY != NULL);
   assert(WebPConvertBGR24ToY != NULL);
   assert(WebPConvertRGBA32ToUV != NULL);
-  assert(WebPSharpYUVUpdateY != NULL);
-  assert(WebPSharpYUVUpdateRGB != NULL);
-  assert(WebPSharpYUVFilterRow != NULL);
 }
diff --git a/third_party/libwebp/src/dsp/yuv.h b/third_party/libwebp/src/dsp/yuv.h
index eb78727..66a397d 100644
--- a/third_party/libwebp/src/dsp/yuv.h
+++ b/third_party/libwebp/src/dsp/yuv.h
@@ -10,7 +10,7 @@
 // inline YUV<->RGB conversion function
 //
 // The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
-// More information at: http://en.wikipedia.org/wiki/YCbCr
+// More information at: https://en.wikipedia.org/wiki/YCbCr
 // Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
 // U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
 // V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
@@ -207,4 +207,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_DSP_YUV_H_ */
+#endif  // WEBP_DSP_YUV_H_
diff --git a/third_party/libwebp/src/dsp/yuv_neon.c b/third_party/libwebp/src/dsp/yuv_neon.c
index a34d602..ff77b00 100644
--- a/third_party/libwebp/src/dsp/yuv_neon.c
+++ b/third_party/libwebp/src/dsp/yuv_neon.c
@@ -173,116 +173,8 @@
   WebPConvertRGBA32ToUV = ConvertRGBA32ToUV_NEON;
 }
 
-//------------------------------------------------------------------------------
-
-#define MAX_Y ((1 << 10) - 1)    // 10b precision over 16b-arithmetic
-static uint16_t clip_y_NEON(int v) {
-  return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
-}
-
-static uint64_t SharpYUVUpdateY_NEON(const uint16_t* ref, const uint16_t* src,
-                                     uint16_t* dst, int len) {
-  int i;
-  const int16x8_t zero = vdupq_n_s16(0);
-  const int16x8_t max = vdupq_n_s16(MAX_Y);
-  uint64x2_t sum = vdupq_n_u64(0);
-  uint64_t diff;
-
-  for (i = 0; i + 8 <= len; i += 8) {
-    const int16x8_t A = vreinterpretq_s16_u16(vld1q_u16(ref + i));
-    const int16x8_t B = vreinterpretq_s16_u16(vld1q_u16(src + i));
-    const int16x8_t C = vreinterpretq_s16_u16(vld1q_u16(dst + i));
-    const int16x8_t D = vsubq_s16(A, B);       // diff_y
-    const int16x8_t F = vaddq_s16(C, D);       // new_y
-    const uint16x8_t H =
-        vreinterpretq_u16_s16(vmaxq_s16(vminq_s16(F, max), zero));
-    const int16x8_t I = vabsq_s16(D);          // abs(diff_y)
-    vst1q_u16(dst + i, H);
-    sum = vpadalq_u32(sum, vpaddlq_u16(vreinterpretq_u16_s16(I)));
-  }
-  diff = vgetq_lane_u64(sum, 0) + vgetq_lane_u64(sum, 1);
-  for (; i < len; ++i) {
-    const int diff_y = ref[i] - src[i];
-    const int new_y = (int)(dst[i]) + diff_y;
-    dst[i] = clip_y_NEON(new_y);
-    diff += (uint64_t)(abs(diff_y));
-  }
-  return diff;
-}
-
-static void SharpYUVUpdateRGB_NEON(const int16_t* ref, const int16_t* src,
-                                   int16_t* dst, int len) {
-  int i;
-  for (i = 0; i + 8 <= len; i += 8) {
-    const int16x8_t A = vld1q_s16(ref + i);
-    const int16x8_t B = vld1q_s16(src + i);
-    const int16x8_t C = vld1q_s16(dst + i);
-    const int16x8_t D = vsubq_s16(A, B);   // diff_uv
-    const int16x8_t E = vaddq_s16(C, D);   // new_uv
-    vst1q_s16(dst + i, E);
-  }
-  for (; i < len; ++i) {
-    const int diff_uv = ref[i] - src[i];
-    dst[i] += diff_uv;
-  }
-}
-
-static void SharpYUVFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
-                                   const uint16_t* best_y, uint16_t* out) {
-  int i;
-  const int16x8_t max = vdupq_n_s16(MAX_Y);
-  const int16x8_t zero = vdupq_n_s16(0);
-  for (i = 0; i + 8 <= len; i += 8) {
-    const int16x8_t a0 = vld1q_s16(A + i + 0);
-    const int16x8_t a1 = vld1q_s16(A + i + 1);
-    const int16x8_t b0 = vld1q_s16(B + i + 0);
-    const int16x8_t b1 = vld1q_s16(B + i + 1);
-    const int16x8_t a0b1 = vaddq_s16(a0, b1);
-    const int16x8_t a1b0 = vaddq_s16(a1, b0);
-    const int16x8_t a0a1b0b1 = vaddq_s16(a0b1, a1b0);  // A0+A1+B0+B1
-    const int16x8_t a0b1_2 = vaddq_s16(a0b1, a0b1);    // 2*(A0+B1)
-    const int16x8_t a1b0_2 = vaddq_s16(a1b0, a1b0);    // 2*(A1+B0)
-    const int16x8_t c0 = vshrq_n_s16(vaddq_s16(a0b1_2, a0a1b0b1), 3);
-    const int16x8_t c1 = vshrq_n_s16(vaddq_s16(a1b0_2, a0a1b0b1), 3);
-    const int16x8_t d0 = vaddq_s16(c1, a0);
-    const int16x8_t d1 = vaddq_s16(c0, a1);
-    const int16x8_t e0 = vrshrq_n_s16(d0, 1);
-    const int16x8_t e1 = vrshrq_n_s16(d1, 1);
-    const int16x8x2_t f = vzipq_s16(e0, e1);
-    const int16x8_t g0 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 0));
-    const int16x8_t g1 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 8));
-    const int16x8_t h0 = vaddq_s16(g0, f.val[0]);
-    const int16x8_t h1 = vaddq_s16(g1, f.val[1]);
-    const int16x8_t i0 = vmaxq_s16(vminq_s16(h0, max), zero);
-    const int16x8_t i1 = vmaxq_s16(vminq_s16(h1, max), zero);
-    vst1q_u16(out + 2 * i + 0, vreinterpretq_u16_s16(i0));
-    vst1q_u16(out + 2 * i + 8, vreinterpretq_u16_s16(i1));
-  }
-  for (; i < len; ++i) {
-    const int a0b1 = A[i + 0] + B[i + 1];
-    const int a1b0 = A[i + 1] + B[i + 0];
-    const int a0a1b0b1 = a0b1 + a1b0 + 8;
-    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
-    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
-    out[2 * i + 0] = clip_y_NEON(best_y[2 * i + 0] + v0);
-    out[2 * i + 1] = clip_y_NEON(best_y[2 * i + 1] + v1);
-  }
-}
-#undef MAX_Y
-
-//------------------------------------------------------------------------------
-
-extern void WebPInitSharpYUVNEON(void);
-
-WEBP_TSAN_IGNORE_FUNCTION void WebPInitSharpYUVNEON(void) {
-  WebPSharpYUVUpdateY = SharpYUVUpdateY_NEON;
-  WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_NEON;
-  WebPSharpYUVFilterRow = SharpYUVFilterRow_NEON;
-}
-
 #else  // !WEBP_USE_NEON
 
 WEBP_DSP_INIT_STUB(WebPInitConvertARGBToYUVNEON)
-WEBP_DSP_INIT_STUB(WebPInitSharpYUVNEON)
 
 #endif  // WEBP_USE_NEON
diff --git a/third_party/libwebp/src/dsp/yuv_sse2.c b/third_party/libwebp/src/dsp/yuv_sse2.c
index baa48d5..01a48f9 100644
--- a/third_party/libwebp/src/dsp/yuv_sse2.c
+++ b/third_party/libwebp/src/dsp/yuv_sse2.c
@@ -15,10 +15,12 @@
 
 #if defined(WEBP_USE_SSE2)
 
-#include "src/dsp/common_sse2.h"
 #include <stdlib.h>
 #include <emmintrin.h>
 
+#include "src/dsp/common_sse2.h"
+#include "src/utils/utils.h"
+
 //-----------------------------------------------------------------------------
 // Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
 
@@ -74,7 +76,7 @@
 // Load and replicate the U/V samples
 static WEBP_INLINE __m128i Load_UV_HI_8_SSE2(const uint8_t* src) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+  const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
   const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
   return _mm_unpacklo_epi16(tmp1, tmp1);   // replicate samples
 }
@@ -130,7 +132,7 @@
   const __m128i rg0 = _mm_packus_epi16(*B, *A);
   const __m128i ba0 = _mm_packus_epi16(*R, *G);
 #endif
-  const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+  const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
   const __m128i rb1 = _mm_unpacklo_epi8(rg0, ba0);  // rbrbrbrbrb...
   const __m128i ga1 = _mm_unpackhi_epi8(rg0, ba0);  // gagagagaga...
   const __m128i rb2 = _mm_and_si128(rb1, mask_0xf0);
@@ -147,9 +149,10 @@
   const __m128i r0 = _mm_packus_epi16(*R, *R);
   const __m128i g0 = _mm_packus_epi16(*G, *G);
   const __m128i b0 = _mm_packus_epi16(*B, *B);
-  const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8(0xf8));
+  const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8((char)0xf8));
   const __m128i b1 = _mm_and_si128(_mm_srli_epi16(b0, 3), _mm_set1_epi8(0x1f));
-  const __m128i g1 = _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0xe0)), 5);
+  const __m128i g1 =
+      _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8((char)0xe0)), 5);
   const __m128i g2 = _mm_slli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0x1c)), 3);
   const __m128i rg = _mm_or_si128(r1, g1);
   const __m128i gb = _mm_or_si128(g2, b1);
@@ -747,128 +750,9 @@
   WebPConvertRGBA32ToUV = ConvertRGBA32ToUV_SSE2;
 }
 
-//------------------------------------------------------------------------------
-
-#define MAX_Y ((1 << 10) - 1)    // 10b precision over 16b-arithmetic
-static uint16_t clip_y(int v) {
-  return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
-}
-
-static uint64_t SharpYUVUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
-                                     uint16_t* dst, int len) {
-  uint64_t diff = 0;
-  uint32_t tmp[4];
-  int i;
-  const __m128i zero = _mm_setzero_si128();
-  const __m128i max = _mm_set1_epi16(MAX_Y);
-  const __m128i one = _mm_set1_epi16(1);
-  __m128i sum = zero;
-
-  for (i = 0; i + 8 <= len; i += 8) {
-    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
-    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
-    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
-    const __m128i D = _mm_sub_epi16(A, B);       // diff_y
-    const __m128i E = _mm_cmpgt_epi16(zero, D);  // sign (-1 or 0)
-    const __m128i F = _mm_add_epi16(C, D);       // new_y
-    const __m128i G = _mm_or_si128(E, one);      // -1 or 1
-    const __m128i H = _mm_max_epi16(_mm_min_epi16(F, max), zero);
-    const __m128i I = _mm_madd_epi16(D, G);      // sum(abs(...))
-    _mm_storeu_si128((__m128i*)(dst + i), H);
-    sum = _mm_add_epi32(sum, I);
-  }
-  _mm_storeu_si128((__m128i*)tmp, sum);
-  diff = tmp[3] + tmp[2] + tmp[1] + tmp[0];
-  for (; i < len; ++i) {
-    const int diff_y = ref[i] - src[i];
-    const int new_y = (int)dst[i] + diff_y;
-    dst[i] = clip_y(new_y);
-    diff += (uint64_t)abs(diff_y);
-  }
-  return diff;
-}
-
-static void SharpYUVUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
-                                   int16_t* dst, int len) {
-  int i = 0;
-  for (i = 0; i + 8 <= len; i += 8) {
-    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
-    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
-    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
-    const __m128i D = _mm_sub_epi16(A, B);   // diff_uv
-    const __m128i E = _mm_add_epi16(C, D);   // new_uv
-    _mm_storeu_si128((__m128i*)(dst + i), E);
-  }
-  for (; i < len; ++i) {
-    const int diff_uv = ref[i] - src[i];
-    dst[i] += diff_uv;
-  }
-}
-
-static void SharpYUVFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
-                                   const uint16_t* best_y, uint16_t* out) {
-  int i;
-  const __m128i kCst8 = _mm_set1_epi16(8);
-  const __m128i max = _mm_set1_epi16(MAX_Y);
-  const __m128i zero = _mm_setzero_si128();
-  for (i = 0; i + 8 <= len; i += 8) {
-    const __m128i a0 = _mm_loadu_si128((const __m128i*)(A + i + 0));
-    const __m128i a1 = _mm_loadu_si128((const __m128i*)(A + i + 1));
-    const __m128i b0 = _mm_loadu_si128((const __m128i*)(B + i + 0));
-    const __m128i b1 = _mm_loadu_si128((const __m128i*)(B + i + 1));
-    const __m128i a0b1 = _mm_add_epi16(a0, b1);
-    const __m128i a1b0 = _mm_add_epi16(a1, b0);
-    const __m128i a0a1b0b1 = _mm_add_epi16(a0b1, a1b0);  // A0+A1+B0+B1
-    const __m128i a0a1b0b1_8 = _mm_add_epi16(a0a1b0b1, kCst8);
-    const __m128i a0b1_2 = _mm_add_epi16(a0b1, a0b1);    // 2*(A0+B1)
-    const __m128i a1b0_2 = _mm_add_epi16(a1b0, a1b0);    // 2*(A1+B0)
-    const __m128i c0 = _mm_srai_epi16(_mm_add_epi16(a0b1_2, a0a1b0b1_8), 3);
-    const __m128i c1 = _mm_srai_epi16(_mm_add_epi16(a1b0_2, a0a1b0b1_8), 3);
-    const __m128i d0 = _mm_add_epi16(c1, a0);
-    const __m128i d1 = _mm_add_epi16(c0, a1);
-    const __m128i e0 = _mm_srai_epi16(d0, 1);
-    const __m128i e1 = _mm_srai_epi16(d1, 1);
-    const __m128i f0 = _mm_unpacklo_epi16(e0, e1);
-    const __m128i f1 = _mm_unpackhi_epi16(e0, e1);
-    const __m128i g0 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
-    const __m128i g1 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 8));
-    const __m128i h0 = _mm_add_epi16(g0, f0);
-    const __m128i h1 = _mm_add_epi16(g1, f1);
-    const __m128i i0 = _mm_max_epi16(_mm_min_epi16(h0, max), zero);
-    const __m128i i1 = _mm_max_epi16(_mm_min_epi16(h1, max), zero);
-    _mm_storeu_si128((__m128i*)(out + 2 * i + 0), i0);
-    _mm_storeu_si128((__m128i*)(out + 2 * i + 8), i1);
-  }
-  for (; i < len; ++i) {
-    //   (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
-    // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
-    // We reuse the common sub-expressions.
-    const int a0b1 = A[i + 0] + B[i + 1];
-    const int a1b0 = A[i + 1] + B[i + 0];
-    const int a0a1b0b1 = a0b1 + a1b0 + 8;
-    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
-    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
-    out[2 * i + 0] = clip_y(best_y[2 * i + 0] + v0);
-    out[2 * i + 1] = clip_y(best_y[2 * i + 1] + v1);
-  }
-}
-
-#undef MAX_Y
-
-//------------------------------------------------------------------------------
-
-extern void WebPInitSharpYUVSSE2(void);
-
-WEBP_TSAN_IGNORE_FUNCTION void WebPInitSharpYUVSSE2(void) {
-  WebPSharpYUVUpdateY = SharpYUVUpdateY_SSE2;
-  WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_SSE2;
-  WebPSharpYUVFilterRow = SharpYUVFilterRow_SSE2;
-}
-
 #else  // !WEBP_USE_SSE2
 
 WEBP_DSP_INIT_STUB(WebPInitSamplersSSE2)
 WEBP_DSP_INIT_STUB(WebPInitConvertARGBToYUVSSE2)
-WEBP_DSP_INIT_STUB(WebPInitSharpYUVSSE2)
 
 #endif  // WEBP_USE_SSE2
diff --git a/third_party/libwebp/src/dsp/yuv_sse41.c b/third_party/libwebp/src/dsp/yuv_sse41.c
index 579d1f7..f79b802 100644
--- a/third_party/libwebp/src/dsp/yuv_sse41.c
+++ b/third_party/libwebp/src/dsp/yuv_sse41.c
@@ -15,10 +15,12 @@
 
 #if defined(WEBP_USE_SSE41)
 
-#include "src/dsp/common_sse41.h"
 #include <stdlib.h>
 #include <smmintrin.h>
 
+#include "src/dsp/common_sse41.h"
+#include "src/utils/utils.h"
+
 //-----------------------------------------------------------------------------
 // Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
 
@@ -74,7 +76,7 @@
 // Load and replicate the U/V samples
 static WEBP_INLINE __m128i Load_UV_HI_8_SSE41(const uint8_t* src) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+  const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
   const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
   return _mm_unpacklo_epi16(tmp1, tmp1);   // replicate samples
 }
diff --git a/third_party/libwebp/src/enc/Makefile.am b/third_party/libwebp/src/enc/Makefile.am
index 27d5228..2fec804 100644
--- a/third_party/libwebp/src/enc/Makefile.am
+++ b/third_party/libwebp/src/enc/Makefile.am
@@ -37,6 +37,7 @@
 noinst_HEADERS =
 noinst_HEADERS += ../webp/format_constants.h
 
+libwebpencode_la_LIBADD = ../../sharpyuv/libsharpyuv.la
 libwebpencode_la_LDFLAGS = -lm
 libwebpencode_la_CPPFLAGS = $(AM_CPPFLAGS)
 libwebpencodeincludedir = $(includedir)/webp
diff --git a/third_party/libwebp/src/enc/alpha_enc.c b/third_party/libwebp/src/enc/alpha_enc.c
index dce9ca9..26f0034 100644
--- a/third_party/libwebp/src/enc/alpha_enc.c
+++ b/third_party/libwebp/src/enc/alpha_enc.c
@@ -13,6 +13,7 @@
 
 #include <assert.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "src/enc/vp8i_enc.h"
 #include "src/dsp/dsp.h"
@@ -86,7 +87,7 @@
   // a decoder bug related to alpha with color cache.
   // See: https://code.google.com/p/webp/issues/detail?id=239
   // Need to re-enable this later.
-  ok = (VP8LEncodeStream(&config, &picture, bw, 0 /*use_cache*/) == VP8_ENC_OK);
+  ok = VP8LEncodeStream(&config, &picture, bw, /*use_cache=*/0);
   WebPPictureFree(&picture);
   ok = ok && !bw->error_;
   if (!ok) {
@@ -140,6 +141,11 @@
                               !reduce_levels, &tmp_bw, &result->stats);
     if (ok) {
       output = VP8LBitWriterFinish(&tmp_bw);
+      if (tmp_bw.error_) {
+        VP8LBitWriterWipeOut(&tmp_bw);
+        memset(&result->bw, 0, sizeof(result->bw));
+        return 0;
+      }
       output_size = VP8LBitWriterNumBytes(&tmp_bw);
       if (output_size > data_size) {
         // compressed size is larger than source! Revert to uncompressed mode.
@@ -148,6 +154,7 @@
       }
     } else {
       VP8LBitWriterWipeOut(&tmp_bw);
+      memset(&result->bw, 0, sizeof(result->bw));
       return 0;
     }
   }
@@ -162,7 +169,7 @@
   header = method | (filter << 2);
   if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
 
-  VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size);
+  if (!VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size)) ok = 0;
   ok = ok && VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN);
   ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
 
@@ -303,7 +310,7 @@
   int ok = 1;
   const int reduce_levels = (quality < 100);
 
-  // quick sanity checks
+  // quick correctness checks
   assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
   assert(enc != NULL && pic != NULL && pic->a != NULL);
   assert(output != NULL && output_size != NULL);
@@ -312,11 +319,11 @@
   assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);
 
   if (quality < 0 || quality > 100) {
-    return 0;
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
   }
 
   if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
-    return 0;
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
   }
 
   if (method == ALPHA_NO_COMPRESSION) {
@@ -326,7 +333,7 @@
 
   quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
   if (quant_alpha == NULL) {
-    return 0;
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
   }
 
   // Extract alpha data (width x height) from raw_data (stride x height).
@@ -346,6 +353,9 @@
     ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method,
                                filter, reduce_levels, effort_level, output,
                                output_size, pic->stats);
+    if (!ok) {
+      WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);  // imprecise
+    }
 #if !defined(WEBP_DISABLE_STATS)
     if (pic->stats != NULL) {  // need stats?
       pic->stats->coded_size += (int)(*output_size);
@@ -361,7 +371,7 @@
 //------------------------------------------------------------------------------
 // Main calls
 
-static int CompressAlphaJob(void* arg1, void* dummy) {
+static int CompressAlphaJob(void* arg1, void* unused) {
   VP8Encoder* const enc = (VP8Encoder*)arg1;
   const WebPConfig* config = enc->config_;
   uint8_t* alpha_data = NULL;
@@ -375,13 +385,13 @@
                    filter, effort_level, &alpha_data, &alpha_size)) {
     return 0;
   }
-  if (alpha_size != (uint32_t)alpha_size) {  // Sanity check.
+  if (alpha_size != (uint32_t)alpha_size) {  // Soundness check.
     WebPSafeFree(alpha_data);
     return 0;
   }
   enc->alpha_data_size_ = (uint32_t)alpha_size;
   enc->alpha_data_ = alpha_data;
-  (void)dummy;
+  (void)unused;
   return 1;
 }
 
@@ -405,7 +415,7 @@
       WebPWorker* const worker = &enc->alpha_worker_;
       // Makes sure worker is good to go.
       if (!WebPGetWorkerInterface()->Reset(worker)) {
-        return 0;
+        return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
       }
       WebPGetWorkerInterface()->Launch(worker);
       return 1;
diff --git a/third_party/libwebp/src/enc/analysis_enc.c b/third_party/libwebp/src/enc/analysis_enc.c
index a47ff7d..962eaa9 100644
--- a/third_party/libwebp/src/enc/analysis_enc.c
+++ b/third_party/libwebp/src/enc/analysis_enc.c
@@ -126,16 +126,6 @@
   histo->last_non_zero = 1;
 }
 
-static void MergeHistograms(const VP8Histogram* const in,
-                            VP8Histogram* const out) {
-  if (in->max_value > out->max_value) {
-    out->max_value = in->max_value;
-  }
-  if (in->last_non_zero > out->last_non_zero) {
-    out->last_non_zero = in->last_non_zero;
-  }
-}
-
 //------------------------------------------------------------------------------
 // Simplified k-Means, to assign Nb segments based on alpha-histogram
 
@@ -285,49 +275,6 @@
   return 0;
 }
 
-static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
-                                   int best_alpha) {
-  uint8_t modes[16];
-  const int max_mode = MAX_INTRA4_MODE;
-  int i4_alpha;
-  VP8Histogram total_histo;
-  int cur_histo = 0;
-  InitHistogram(&total_histo);
-
-  VP8IteratorStartI4(it);
-  do {
-    int mode;
-    int best_mode_alpha = DEFAULT_ALPHA;
-    VP8Histogram histos[2];
-    const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC + VP8Scan[it->i4_];
-
-    VP8MakeIntra4Preds(it);
-    for (mode = 0; mode < max_mode; ++mode) {
-      int alpha;
-
-      InitHistogram(&histos[cur_histo]);
-      VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
-                          0, 1, &histos[cur_histo]);
-      alpha = GetAlpha(&histos[cur_histo]);
-      if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) {
-        best_mode_alpha = alpha;
-        modes[it->i4_] = mode;
-        cur_histo ^= 1;   // keep track of best histo so far.
-      }
-    }
-    // accumulate best histogram
-    MergeHistograms(&histos[cur_histo ^ 1], &total_histo);
-    // Note: we reuse the original samples for predictors
-  } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF_ENC));
-
-  i4_alpha = GetAlpha(&total_histo);
-  if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) {
-    VP8SetIntra4Mode(it, modes);
-    best_alpha = i4_alpha;
-  }
-  return best_alpha;
-}
-
 static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
   int best_alpha = DEFAULT_ALPHA;
   int smallest_alpha = 0;
@@ -371,13 +318,6 @@
     best_alpha = FastMBAnalyze(it);
   } else {
     best_alpha = MBAnalyzeBestIntra16Mode(it);
-    if (enc->method_ >= 5) {
-      // We go and make a fast decision for intra4/intra16.
-      // It's usually not a good and definitive pick, but helps seeding the
-      // stats about level bit-cost.
-      // TODO(skal): improve criterion.
-      best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha);
-    }
   }
   best_uv_alpha = MBAnalyzeBestUVMode(it);
 
@@ -451,14 +391,16 @@
   return ok;
 }
 
+#ifdef WEBP_USE_THREAD
 static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) {
   int i;
   for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i];
   dst->alpha += src->alpha;
   dst->uv_alpha += src->uv_alpha;
 }
+#endif
 
-// initialize the job struct with some TODOs
+// initialize the job struct with some tasks to perform
 static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job,
                            int start_row, int end_row) {
   WebPGetWorkerInterface()->Init(&job->worker);
@@ -485,10 +427,10 @@
       (enc->method_ <= 1);  // for method 0 - 1, we need preds_[] to be filled.
   if (do_segments) {
     const int last_row = enc->mb_h_;
-    // We give a little more than a half work to the main thread.
-    const int split_row = (9 * last_row + 15) >> 4;
     const int total_mb = last_row * enc->mb_w_;
 #ifdef WEBP_USE_THREAD
+    // We give a little more than a half work to the main thread.
+    const int split_row = (9 * last_row + 15) >> 4;
     const int kMinSplitRow = 2;  // minimal rows needed for mt to be worth it
     const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow);
 #else
@@ -498,6 +440,7 @@
         WebPGetWorkerInterface();
     SegmentJob main_job;
     if (do_mt) {
+#ifdef WEBP_USE_THREAD
       SegmentJob side_job;
       // Note the use of '&' instead of '&&' because we must call the functions
       // no matter what.
@@ -515,6 +458,7 @@
       }
       worker_interface->End(&side_job.worker);
       if (ok) MergeJobs(&side_job, &main_job);  // merge results together
+#endif  // WEBP_USE_THREAD
     } else {
       // Even for single-thread case, we use the generic Worker tools.
       InitSegmentJob(enc, &main_job, 0, last_row);
@@ -530,6 +474,10 @@
   } else {   // Use only one default segment.
     ResetAllMBInfo(enc);
   }
+  if (!ok) {
+    return WebPEncodingSetError(enc->pic_,
+                                VP8_ENC_ERROR_OUT_OF_MEMORY);  // imprecise
+  }
   return ok;
 }
 
diff --git a/third_party/libwebp/src/enc/backward_references_cost_enc.c b/third_party/libwebp/src/enc/backward_references_cost_enc.c
index 7175496..6968ef3 100644
--- a/third_party/libwebp/src/enc/backward_references_cost_enc.c
+++ b/third_party/libwebp/src/enc/backward_references_cost_enc.c
@@ -15,10 +15,11 @@
 //
 
 #include <assert.h>
+#include <float.h>
 
+#include "src/dsp/lossless_common.h"
 #include "src/enc/backward_references_enc.h"
 #include "src/enc/histogram_enc.h"
-#include "src/dsp/lossless_common.h"
 #include "src/utils/color_cache_utils.h"
 #include "src/utils/utils.h"
 
@@ -30,15 +31,15 @@
                                       const PixOrCopy v);
 
 typedef struct {
-  double alpha_[VALUES_IN_BYTE];
-  double red_[VALUES_IN_BYTE];
-  double blue_[VALUES_IN_BYTE];
-  double distance_[NUM_DISTANCE_CODES];
-  double* literal_;
+  float alpha_[VALUES_IN_BYTE];
+  float red_[VALUES_IN_BYTE];
+  float blue_[VALUES_IN_BYTE];
+  float distance_[NUM_DISTANCE_CODES];
+  float* literal_;
 } CostModel;
 
 static void ConvertPopulationCountTableToBitEstimates(
-    int num_symbols, const uint32_t population_counts[], double output[]) {
+    int num_symbols, const uint32_t population_counts[], float output[]) {
   uint32_t sum = 0;
   int nonzeros = 0;
   int i;
@@ -51,7 +52,7 @@
   if (nonzeros <= 1) {
     memset(output, 0, num_symbols * sizeof(*output));
   } else {
-    const double logsum = VP8LFastLog2(sum);
+    const float logsum = VP8LFastLog2(sum);
     for (i = 0; i < num_symbols; ++i) {
       output[i] = logsum - VP8LFastLog2(population_counts[i]);
     }
@@ -67,7 +68,7 @@
 
   // The following code is similar to VP8LHistogramCreate but converts the
   // distance to plane code.
-  VP8LHistogramInit(histo, cache_bits);
+  VP8LHistogramInit(histo, cache_bits, /*init_arrays=*/ 1);
   while (VP8LRefsCursorOk(&c)) {
     VP8LHistogramAddSinglePixOrCopy(histo, c.cur_pos, VP8LDistanceToPlaneCode,
                                     xsize);
@@ -75,8 +76,8 @@
   }
 
   ConvertPopulationCountTableToBitEstimates(
-      VP8LHistogramNumCodes(histo->palette_code_bits_),
-      histo->literal_, m->literal_);
+      VP8LHistogramNumCodes(histo->palette_code_bits_), histo->literal_,
+      m->literal_);
   ConvertPopulationCountTableToBitEstimates(
       VALUES_IN_BYTE, histo->red_, m->red_);
   ConvertPopulationCountTableToBitEstimates(
@@ -92,27 +93,27 @@
   return ok;
 }
 
-static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) {
+static WEBP_INLINE float GetLiteralCost(const CostModel* const m, uint32_t v) {
   return m->alpha_[v >> 24] +
          m->red_[(v >> 16) & 0xff] +
          m->literal_[(v >> 8) & 0xff] +
          m->blue_[v & 0xff];
 }
 
-static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) {
+static WEBP_INLINE float GetCacheCost(const CostModel* const m, uint32_t idx) {
   const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx;
   return m->literal_[literal_idx];
 }
 
-static WEBP_INLINE double GetLengthCost(const CostModel* const m,
-                                        uint32_t length) {
+static WEBP_INLINE float GetLengthCost(const CostModel* const m,
+                                       uint32_t length) {
   int code, extra_bits;
   VP8LPrefixEncodeBits(length, &code, &extra_bits);
   return m->literal_[VALUES_IN_BYTE + code] + extra_bits;
 }
 
-static WEBP_INLINE double GetDistanceCost(const CostModel* const m,
-                                          uint32_t distance) {
+static WEBP_INLINE float GetDistanceCost(const CostModel* const m,
+                                         uint32_t distance) {
   int code, extra_bits;
   VP8LPrefixEncodeBits(distance, &code, &extra_bits);
   return m->distance_[code] + extra_bits;
@@ -122,20 +123,20 @@
     const uint32_t* const argb, VP8LColorCache* const hashers,
     const CostModel* const cost_model, int idx, int use_color_cache,
     float prev_cost, float* const cost, uint16_t* const dist_array) {
-  double cost_val = prev_cost;
+  float cost_val = prev_cost;
   const uint32_t color = argb[idx];
   const int ix = use_color_cache ? VP8LColorCacheContains(hashers, color) : -1;
   if (ix >= 0) {
     // use_color_cache is true and hashers contains color
-    const double mul0 = 0.68;
+    const float mul0 = 0.68f;
     cost_val += GetCacheCost(cost_model, ix) * mul0;
   } else {
-    const double mul1 = 0.82;
+    const float mul1 = 0.82f;
     if (use_color_cache) VP8LColorCacheInsert(hashers, color);
     cost_val += GetLiteralCost(cost_model, color) * mul1;
   }
   if (cost[idx] > cost_val) {
-    cost[idx] = (float)cost_val;
+    cost[idx] = cost_val;
     dist_array[idx] = 1;  // only one is inserted.
   }
 }
@@ -172,7 +173,7 @@
 
 // The GetLengthCost(cost_model, k) are cached in a CostCacheInterval.
 typedef struct {
-  double cost_;
+  float cost_;
   int start_;
   int end_;       // Exclusive.
 } CostCacheInterval;
@@ -187,7 +188,7 @@
   int count_;  // The number of stored intervals.
   CostCacheInterval* cache_intervals_;
   size_t cache_intervals_size_;
-  double cost_cache_[MAX_LENGTH];  // Contains the GetLengthCost(cost_model, k).
+  float cost_cache_[MAX_LENGTH];  // Contains the GetLengthCost(cost_model, k).
   float* costs_;
   uint16_t* dist_array_;
   // Most of the time, we only need few intervals -> use a free-list, to avoid
@@ -262,10 +263,13 @@
   CostManagerInitFreeList(manager);
 
   // Fill in the cost_cache_.
-  manager->cache_intervals_size_ = 1;
-  manager->cost_cache_[0] = GetLengthCost(cost_model, 0);
-  for (i = 1; i < cost_cache_size; ++i) {
+  // Has to be done in two passes due to a GCC bug on i686
+  // related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
+  for (i = 0; i < cost_cache_size; ++i) {
     manager->cost_cache_[i] = GetLengthCost(cost_model, i);
+  }
+  manager->cache_intervals_size_ = 1;
+  for (i = 1; i < cost_cache_size; ++i) {
     // Get the number of bound intervals.
     if (manager->cost_cache_[i] != manager->cost_cache_[i - 1]) {
       ++manager->cache_intervals_size_;
@@ -294,7 +298,7 @@
     cur->end_ = 1;
     cur->cost_ = manager->cost_cache_[0];
     for (i = 1; i < cost_cache_size; ++i) {
-      const double cost_val = manager->cost_cache_[i];
+      const float cost_val = manager->cost_cache_[i];
       if (cost_val != cur->cost_) {
         ++cur;
         // Initialize an interval.
@@ -303,6 +307,8 @@
       }
       cur->end_ = i + 1;
     }
+    assert((size_t)(cur - manager->cache_intervals_) + 1 ==
+           manager->cache_intervals_size_);
   }
 
   manager->costs_ = (float*)WebPSafeMalloc(pix_count, sizeof(*manager->costs_));
@@ -311,7 +317,7 @@
     return 0;
   }
   // Set the initial costs_ high for every pixel as we will keep the minimum.
-  for (i = 0; i < pix_count; ++i) manager->costs_[i] = 1e38f;
+  for (i = 0; i < pix_count; ++i) manager->costs_[i] = FLT_MAX;
 
   return 1;
 }
@@ -457,7 +463,7 @@
 // If handling the interval or one of its subintervals becomes to heavy, its
 // contribution is added to the costs right away.
 static WEBP_INLINE void PushInterval(CostManager* const manager,
-                                     double distance_cost, int position,
+                                     float distance_cost, int position,
                                      int len) {
   size_t i;
   CostInterval* interval = manager->head_;
@@ -474,7 +480,7 @@
       const int k = j - position;
       float cost_tmp;
       assert(k >= 0 && k < MAX_LENGTH);
-      cost_tmp = (float)(distance_cost + manager->cost_cache_[k]);
+      cost_tmp = distance_cost + manager->cost_cache_[k];
 
       if (manager->costs_[j] > cost_tmp) {
         manager->costs_[j] = cost_tmp;
@@ -492,7 +498,7 @@
     const int end = position + (cost_cache_intervals[i].end_ > len
                                  ? len
                                  : cost_cache_intervals[i].end_);
-    const float cost = (float)(distance_cost + cost_cache_intervals[i].cost_);
+    const float cost = distance_cost + cost_cache_intervals[i].cost_;
 
     for (; interval != NULL && interval->start_ < end;
          interval = interval_next) {
@@ -570,22 +576,21 @@
   const int pix_count = xsize * ysize;
   const int use_color_cache = (cache_bits > 0);
   const size_t literal_array_size =
-      sizeof(double) * (NUM_LITERAL_CODES + NUM_LENGTH_CODES +
-                        ((cache_bits > 0) ? (1 << cache_bits) : 0));
+      sizeof(float) * (VP8LHistogramNumCodes(cache_bits));
   const size_t cost_model_size = sizeof(CostModel) + literal_array_size;
   CostModel* const cost_model =
       (CostModel*)WebPSafeCalloc(1ULL, cost_model_size);
   VP8LColorCache hashers;
   CostManager* cost_manager =
-      (CostManager*)WebPSafeMalloc(1ULL, sizeof(*cost_manager));
+      (CostManager*)WebPSafeCalloc(1ULL, sizeof(*cost_manager));
   int offset_prev = -1, len_prev = -1;
-  double offset_cost = -1;
+  float offset_cost = -1.f;
   int first_offset_is_constant = -1;  // initialized with 'impossible' value
   int reach = 0;
 
   if (cost_model == NULL || cost_manager == NULL) goto Error;
 
-  cost_model->literal_ = (double*)(cost_model + 1);
+  cost_model->literal_ = (float*)(cost_model + 1);
   if (use_color_cache) {
     cc_init = VP8LColorCacheInit(&hashers, cache_bits);
     if (!cc_init) goto Error;
@@ -675,7 +680,7 @@
   }
 
   ok = !refs->error_;
-Error:
+ Error:
   if (cc_init) VP8LColorCacheClear(&hashers);
   CostManagerClear(cost_manager);
   WebPSafeFree(cost_model);
diff --git a/third_party/libwebp/src/enc/backward_references_enc.c b/third_party/libwebp/src/enc/backward_references_enc.c
index 3923018..dc98bf1 100644
--- a/third_party/libwebp/src/enc/backward_references_enc.c
+++ b/third_party/libwebp/src/enc/backward_references_enc.c
@@ -10,16 +10,20 @@
 // Author: Jyrki Alakuijala (jyrki@google.com)
 //
 
+#include "src/enc/backward_references_enc.h"
+
 #include <assert.h>
+#include <float.h>
 #include <math.h>
 
-#include "src/enc/backward_references_enc.h"
-#include "src/enc/histogram_enc.h"
+#include "src/dsp/dsp.h"
 #include "src/dsp/lossless.h"
 #include "src/dsp/lossless_common.h"
-#include "src/dsp/dsp.h"
+#include "src/enc/histogram_enc.h"
+#include "src/enc/vp8i_enc.h"
 #include "src/utils/color_cache_utils.h"
 #include "src/utils/utils.h"
+#include "src/webp/encode.h"
 
 #define MIN_BLOCK_SIZE 256  // minimum block size for backward references
 
@@ -103,6 +107,20 @@
   }
 }
 
+// Swaps the content of two VP8LBackwardRefs.
+static void BackwardRefsSwap(VP8LBackwardRefs* const refs1,
+                             VP8LBackwardRefs* const refs2) {
+  const int point_to_refs1 =
+      (refs1->tail_ != NULL && refs1->tail_ == &refs1->refs_);
+  const int point_to_refs2 =
+      (refs2->tail_ != NULL && refs2->tail_ == &refs2->refs_);
+  const VP8LBackwardRefs tmp = *refs1;
+  *refs1 = *refs2;
+  *refs2 = tmp;
+  if (point_to_refs2) refs1->tail_ = &refs1->refs_;
+  if (point_to_refs1) refs2->tail_ = &refs2->refs_;
+}
+
 void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size) {
   assert(refs != NULL);
   memset(refs, 0, sizeof(*refs));
@@ -154,6 +172,22 @@
   return b;
 }
 
+// Return 1 on success, 0 on error.
+static int BackwardRefsClone(const VP8LBackwardRefs* const from,
+                             VP8LBackwardRefs* const to) {
+  const PixOrCopyBlock* block_from = from->refs_;
+  VP8LClearBackwardRefs(to);
+  while (block_from != NULL) {
+    PixOrCopyBlock* const block_to = BackwardRefsNewBlock(to);
+    if (block_to == NULL) return 0;
+    memcpy(block_to->start_, block_from->start_,
+           block_from->size_ * sizeof(PixOrCopy));
+    block_to->size_ = block_from->size_;
+    block_from = block_from->next_;
+  }
+  return 1;
+}
+
 extern void VP8LBackwardRefsCursorAdd(VP8LBackwardRefs* const refs,
                                       const PixOrCopy v);
 void VP8LBackwardRefsCursorAdd(VP8LBackwardRefs* const refs,
@@ -191,13 +225,14 @@
 
 // -----------------------------------------------------------------------------
 
-#define HASH_MULTIPLIER_HI (0xc6a4a793ULL)
-#define HASH_MULTIPLIER_LO (0x5bd1e996ULL)
+static const uint32_t kHashMultiplierHi = 0xc6a4a793u;
+static const uint32_t kHashMultiplierLo = 0x5bd1e996u;
 
-static WEBP_INLINE uint32_t GetPixPairHash64(const uint32_t* const argb) {
+static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
+uint32_t GetPixPairHash64(const uint32_t* const argb) {
   uint32_t key;
-  key  = (argb[1] * HASH_MULTIPLIER_HI) & 0xffffffffu;
-  key += (argb[0] * HASH_MULTIPLIER_LO) & 0xffffffffu;
+  key  = argb[1] * kHashMultiplierHi;
+  key += argb[0] * kHashMultiplierLo;
   key = key >> (32 - HASH_BITS);
   return key;
 }
@@ -223,10 +258,13 @@
 
 int VP8LHashChainFill(VP8LHashChain* const p, int quality,
                       const uint32_t* const argb, int xsize, int ysize,
-                      int low_effort) {
+                      int low_effort, const WebPPicture* const pic,
+                      int percent_range, int* const percent) {
   const int size = xsize * ysize;
   const int iter_max = GetMaxItersForQuality(quality);
   const uint32_t window_size = GetWindowSizeForHashChain(quality, xsize);
+  int remaining_percent = percent_range;
+  int percent_start = *percent;
   int pos;
   int argb_comp;
   uint32_t base_position;
@@ -244,7 +282,12 @@
 
   hash_to_first_index =
       (int32_t*)WebPSafeMalloc(HASH_SIZE, sizeof(*hash_to_first_index));
-  if (hash_to_first_index == NULL) return 0;
+  if (hash_to_first_index == NULL) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+
+  percent_range = remaining_percent / 2;
+  remaining_percent -= percent_range;
 
   // Set the int32_t array to -1.
   memset(hash_to_first_index, 0xff, HASH_SIZE * sizeof(*hash_to_first_index));
@@ -291,12 +334,22 @@
       hash_to_first_index[hash_code] = pos++;
       argb_comp = argb_comp_next;
     }
+
+    if (!WebPReportProgress(
+            pic, percent_start + percent_range * pos / (size - 2), percent)) {
+      WebPSafeFree(hash_to_first_index);
+      return 0;
+    }
   }
   // Process the penultimate pixel.
   chain[pos] = hash_to_first_index[GetPixPairHash64(argb + pos)];
 
   WebPSafeFree(hash_to_first_index);
 
+  percent_start += percent_range;
+  if (!WebPReportProgress(pic, percent_start, percent)) return 0;
+  percent_range = remaining_percent;
+
   // Find the best match interval at each pixel, defined by an offset to the
   // pixel and a length. The right-most pixel cannot match anything to the right
   // (hence a best length of 0) and the left-most pixel nothing to the left
@@ -385,8 +438,17 @@
         max_base_position = base_position;
       }
     }
+
+    if (!WebPReportProgress(pic,
+                            percent_start + percent_range *
+                                                (size - 2 - base_position) /
+                                                (size - 2),
+                            percent)) {
+      return 0;
+    }
   }
-  return 1;
+
+  return WebPReportProgress(pic, percent_start + percent_range, percent);
 }
 
 static WEBP_INLINE void AddSingleLiteral(uint32_t pixel, int use_color_cache,
@@ -696,7 +758,7 @@
                                   int* const best_cache_bits) {
   int i;
   const int cache_bits_max = (quality <= 25) ? 0 : *best_cache_bits;
-  double entropy_min = MAX_ENTROPY;
+  float entropy_min = MAX_ENTROPY;
   int cc_init[MAX_COLOR_CACHE_BITS + 1] = { 0 };
   VP8LColorCache hashers[MAX_COLOR_CACHE_BITS + 1];
   VP8LRefsCursor c = VP8LRefsCursorInit(refs);
@@ -715,6 +777,7 @@
   for (i = 0; i <= cache_bits_max; ++i) {
     histos[i] = VP8LAllocateHistogram(i);
     if (histos[i] == NULL) goto Error;
+    VP8LHistogramInit(histos[i], i, /*init_arrays=*/ 1);
     if (i == 0) continue;
     cc_init[i] = VP8LColorCacheInit(&hashers[i], i);
     if (!cc_init[i]) goto Error;
@@ -751,12 +814,18 @@
         }
       }
     } else {
+      int code, extra_bits, extra_bits_value;
       // We should compute the contribution of the (distance,length)
       // histograms but those are the same independently from the cache size.
       // As those constant contributions are in the end added to the other
-      // histogram contributions, we can safely ignore them.
+      // histogram contributions, we can ignore them, except for the length
+      // prefix that is part of the literal_ histogram.
       int len = PixOrCopyLength(v);
       uint32_t argb_prev = *argb ^ 0xffffffffu;
+      VP8LPrefixEncode(len, &code, &extra_bits, &extra_bits_value);
+      for (i = 0; i <= cache_bits_max; ++i) {
+        ++histos[i]->literal_[NUM_LITERAL_CODES + code];
+      }
       // Update the color caches.
       do {
         if (*argb != argb_prev) {
@@ -774,14 +843,14 @@
   }
 
   for (i = 0; i <= cache_bits_max; ++i) {
-    const double entropy = VP8LHistogramEstimateBits(histos[i]);
+    const float entropy = VP8LHistogramEstimateBits(histos[i]);
     if (i == 0 || entropy < entropy_min) {
       entropy_min = entropy;
       *best_cache_bits = i;
     }
   }
   ok = 1;
-Error:
+ Error:
   for (i = 0; i <= cache_bits_max; ++i) {
     if (cc_init[i]) VP8LColorCacheClear(&hashers[i]);
     VP8LFreeHistogram(histos[i]);
@@ -840,16 +909,21 @@
     int xsize, int ysize, const uint32_t* const argb, int cache_bits,
     const VP8LHashChain* const hash_chain,
     const VP8LBackwardRefs* const refs_src, VP8LBackwardRefs* const refs_dst);
-static VP8LBackwardRefs* GetBackwardReferences(
-    int width, int height, const uint32_t* const argb, int quality,
-    int lz77_types_to_try, int* const cache_bits,
-    const VP8LHashChain* const hash_chain, VP8LBackwardRefs* best,
-    VP8LBackwardRefs* worst) {
-  const int cache_bits_initial = *cache_bits;
-  double bit_cost_best = -1;
+static int GetBackwardReferences(int width, int height,
+                                 const uint32_t* const argb, int quality,
+                                 int lz77_types_to_try, int cache_bits_max,
+                                 int do_no_cache,
+                                 const VP8LHashChain* const hash_chain,
+                                 VP8LBackwardRefs* const refs,
+                                 int* const cache_bits_best) {
   VP8LHistogram* histo = NULL;
-  int lz77_type, lz77_type_best = 0;
+  int i, lz77_type;
+  // Index 0 is for a color cache, index 1 for no cache (if needed).
+  int lz77_types_best[2] = {0, 0};
+  float bit_costs_best[2] = {FLT_MAX, FLT_MAX};
   VP8LHashChain hash_chain_box;
+  VP8LBackwardRefs* const refs_tmp = &refs[do_no_cache ? 2 : 1];
+  int status = 0;
   memset(&hash_chain_box, 0, sizeof(hash_chain_box));
 
   histo = VP8LAllocateHistogram(MAX_COLOR_CACHE_BITS);
@@ -858,86 +932,134 @@
   for (lz77_type = 1; lz77_types_to_try;
        lz77_types_to_try &= ~lz77_type, lz77_type <<= 1) {
     int res = 0;
-    double bit_cost;
-    int cache_bits_tmp = cache_bits_initial;
+    float bit_cost = 0.f;
     if ((lz77_types_to_try & lz77_type) == 0) continue;
     switch (lz77_type) {
       case kLZ77RLE:
-        res = BackwardReferencesRle(width, height, argb, 0, worst);
+        res = BackwardReferencesRle(width, height, argb, 0, refs_tmp);
         break;
       case kLZ77Standard:
         // Compute LZ77 with no cache (0 bits), as the ideal LZ77 with a color
         // cache is not that different in practice.
-        res = BackwardReferencesLz77(width, height, argb, 0, hash_chain, worst);
+        res = BackwardReferencesLz77(width, height, argb, 0, hash_chain,
+                                     refs_tmp);
         break;
       case kLZ77Box:
         if (!VP8LHashChainInit(&hash_chain_box, width * height)) goto Error;
         res = BackwardReferencesLz77Box(width, height, argb, 0, hash_chain,
-                                        &hash_chain_box, worst);
+                                        &hash_chain_box, refs_tmp);
         break;
       default:
         assert(0);
     }
     if (!res) goto Error;
 
-    // Next, try with a color cache and update the references.
-    if (!CalculateBestCacheSize(argb, quality, worst, &cache_bits_tmp)) {
-      goto Error;
-    }
-    if (cache_bits_tmp > 0) {
-      if (!BackwardRefsWithLocalCache(argb, cache_bits_tmp, worst)) {
-        goto Error;
+    // Start with the no color cache case.
+    for (i = 1; i >= 0; --i) {
+      int cache_bits = (i == 1) ? 0 : cache_bits_max;
+
+      if (i == 1 && !do_no_cache) continue;
+
+      if (i == 0) {
+        // Try with a color cache.
+        if (!CalculateBestCacheSize(argb, quality, refs_tmp, &cache_bits)) {
+          goto Error;
+        }
+        if (cache_bits > 0) {
+          if (!BackwardRefsWithLocalCache(argb, cache_bits, refs_tmp)) {
+            goto Error;
+          }
+        }
+      }
+
+      if (i == 0 && do_no_cache && cache_bits == 0) {
+        // No need to re-compute bit_cost as it was computed at i == 1.
+      } else {
+        VP8LHistogramCreate(histo, refs_tmp, cache_bits);
+        bit_cost = VP8LHistogramEstimateBits(histo);
+      }
+
+      if (bit_cost < bit_costs_best[i]) {
+        if (i == 1) {
+          // Do not swap as the full cache analysis would have the wrong
+          // VP8LBackwardRefs to start with.
+          if (!BackwardRefsClone(refs_tmp, &refs[1])) goto Error;
+        } else {
+          BackwardRefsSwap(refs_tmp, &refs[0]);
+        }
+        bit_costs_best[i] = bit_cost;
+        lz77_types_best[i] = lz77_type;
+        if (i == 0) *cache_bits_best = cache_bits;
       }
     }
-
-    // Keep the best backward references.
-    VP8LHistogramCreate(histo, worst, cache_bits_tmp);
-    bit_cost = VP8LHistogramEstimateBits(histo);
-    if (lz77_type_best == 0 || bit_cost < bit_cost_best) {
-      VP8LBackwardRefs* const tmp = worst;
-      worst = best;
-      best = tmp;
-      bit_cost_best = bit_cost;
-      *cache_bits = cache_bits_tmp;
-      lz77_type_best = lz77_type;
-    }
   }
-  assert(lz77_type_best > 0);
+  assert(lz77_types_best[0] > 0);
+  assert(!do_no_cache || lz77_types_best[1] > 0);
 
   // Improve on simple LZ77 but only for high quality (TraceBackwards is
   // costly).
-  if ((lz77_type_best == kLZ77Standard || lz77_type_best == kLZ77Box) &&
-      quality >= 25) {
-    const VP8LHashChain* const hash_chain_tmp =
-        (lz77_type_best == kLZ77Standard) ? hash_chain : &hash_chain_box;
-    if (VP8LBackwardReferencesTraceBackwards(width, height, argb, *cache_bits,
-                                             hash_chain_tmp, best, worst)) {
-      double bit_cost_trace;
-      VP8LHistogramCreate(histo, worst, *cache_bits);
+  for (i = 1; i >= 0; --i) {
+    if (i == 1 && !do_no_cache) continue;
+    if ((lz77_types_best[i] == kLZ77Standard ||
+         lz77_types_best[i] == kLZ77Box) &&
+        quality >= 25) {
+      const VP8LHashChain* const hash_chain_tmp =
+          (lz77_types_best[i] == kLZ77Standard) ? hash_chain : &hash_chain_box;
+      const int cache_bits = (i == 1) ? 0 : *cache_bits_best;
+      float bit_cost_trace;
+      if (!VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
+                                                hash_chain_tmp, &refs[i],
+                                                refs_tmp)) {
+        goto Error;
+      }
+      VP8LHistogramCreate(histo, refs_tmp, cache_bits);
       bit_cost_trace = VP8LHistogramEstimateBits(histo);
-      if (bit_cost_trace < bit_cost_best) best = worst;
+      if (bit_cost_trace < bit_costs_best[i]) {
+        BackwardRefsSwap(refs_tmp, &refs[i]);
+      }
+    }
+
+    BackwardReferences2DLocality(width, &refs[i]);
+
+    if (i == 1 && lz77_types_best[0] == lz77_types_best[1] &&
+        *cache_bits_best == 0) {
+      // If the best cache size is 0 and we have the same best LZ77, just copy
+      // the data over and stop here.
+      if (!BackwardRefsClone(&refs[1], &refs[0])) goto Error;
+      break;
+    }
+  }
+  status = 1;
+
+ Error:
+  VP8LHashChainClear(&hash_chain_box);
+  VP8LFreeHistogram(histo);
+  return status;
+}
+
+int VP8LGetBackwardReferences(
+    int width, int height, const uint32_t* const argb, int quality,
+    int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
+    const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
+    int* const cache_bits_best, const WebPPicture* const pic, int percent_range,
+    int* const percent) {
+  if (low_effort) {
+    VP8LBackwardRefs* refs_best;
+    *cache_bits_best = cache_bits_max;
+    refs_best = GetBackwardReferencesLowEffort(
+        width, height, argb, cache_bits_best, hash_chain, refs);
+    if (refs_best == NULL) {
+      return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    }
+    // Set it in first position.
+    BackwardRefsSwap(refs_best, &refs[0]);
+  } else {
+    if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try,
+                               cache_bits_max, do_no_cache, hash_chain, refs,
+                               cache_bits_best)) {
+      return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     }
   }
 
-  BackwardReferences2DLocality(width, best);
-
-Error:
-  VP8LHashChainClear(&hash_chain_box);
-  VP8LFreeHistogram(histo);
-  return best;
-}
-
-VP8LBackwardRefs* VP8LGetBackwardReferences(
-    int width, int height, const uint32_t* const argb, int quality,
-    int low_effort, int lz77_types_to_try, int* const cache_bits,
-    const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs_tmp1,
-    VP8LBackwardRefs* const refs_tmp2) {
-  if (low_effort) {
-    return GetBackwardReferencesLowEffort(width, height, argb, cache_bits,
-                                          hash_chain, refs_tmp1);
-  } else {
-    return GetBackwardReferences(width, height, argb, quality,
-                                 lz77_types_to_try, cache_bits, hash_chain,
-                                 refs_tmp1, refs_tmp2);
-  }
+  return WebPReportProgress(pic, *percent + percent_range, percent);
 }
diff --git a/third_party/libwebp/src/enc/backward_references_enc.h b/third_party/libwebp/src/enc/backward_references_enc.h
index a99eac7..1689be2 100644
--- a/third_party/libwebp/src/enc/backward_references_enc.h
+++ b/third_party/libwebp/src/enc/backward_references_enc.h
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #endif
 #include "src/webp/types.h"
+#include "src/webp/encode.h"
 #include "src/webp/format_constants.h"
 
 #ifdef __cplusplus
@@ -137,10 +138,11 @@
 
 // Must be called first, to set size.
 int VP8LHashChainInit(VP8LHashChain* const p, int size);
-// Pre-compute the best matches for argb.
+// Pre-compute the best matches for argb. pic and percent are for progress.
 int VP8LHashChainFill(VP8LHashChain* const p, int quality,
                       const uint32_t* const argb, int xsize, int ysize,
-                      int low_effort);
+                      int low_effort, const WebPPicture* const pic,
+                      int percent_range, int* const percent);
 void VP8LHashChainClear(VP8LHashChain* const p);  // release memory
 
 static WEBP_INLINE int VP8LHashChainFindOffset(const VP8LHashChain* const p,
@@ -222,14 +224,22 @@
 // Evaluates best possible backward references for specified quality.
 // The input cache_bits to 'VP8LGetBackwardReferences' sets the maximum cache
 // bits to use (passing 0 implies disabling the local color cache).
-// The optimal cache bits is evaluated and set for the *cache_bits parameter.
-// The return value is the pointer to the best of the two backward refs viz,
-// refs[0] or refs[1].
-VP8LBackwardRefs* VP8LGetBackwardReferences(
+// The optimal cache bits is evaluated and set for the *cache_bits_best
+// parameter with the matching refs_best.
+// If do_no_cache == 0, refs is an array of 2 values and the best
+// VP8LBackwardRefs is put in the first element.
+// If do_no_cache != 0, refs is an array of 3 values and the best
+// VP8LBackwardRefs is put in the first element, the best value with no-cache in
+// the second element.
+// In both cases, the last element is used as temporary internally.
+// pic and percent are for progress.
+// Returns false in case of error (stored in pic->error_code).
+int VP8LGetBackwardReferences(
     int width, int height, const uint32_t* const argb, int quality,
-    int low_effort, int lz77_types_to_try, int* const cache_bits,
-    const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs_tmp1,
-    VP8LBackwardRefs* const refs_tmp2);
+    int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
+    const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
+    int* const cache_bits_best, const WebPPicture* const pic, int percent_range,
+    int* const percent);
 
 #ifdef __cplusplus
 }
diff --git a/third_party/libwebp/src/enc/config_enc.c b/third_party/libwebp/src/enc/config_enc.c
index 9d48289..3518b41 100644
--- a/third_party/libwebp/src/enc/config_enc.c
+++ b/third_party/libwebp/src/enc/config_enc.c
@@ -39,6 +39,8 @@
   config->partitions = 0;
   config->segments = 4;
   config->pass = 1;
+  config->qmin = 0;
+  config->qmax = 100;
   config->show_compressed = 0;
   config->preprocessing = 0;
   config->autofilter = 0;
@@ -106,6 +108,9 @@
   if (config->filter_type < 0 || config->filter_type > 1) return 0;
   if (config->autofilter < 0 || config->autofilter > 1) return 0;
   if (config->pass < 1 || config->pass > 10) return 0;
+  if (config->qmin < 0 || config->qmax > 100 || config->qmin > config->qmax) {
+    return 0;
+  }
   if (config->show_compressed < 0 || config->show_compressed > 1) return 0;
   if (config->preprocessing < 0 || config->preprocessing > 7) return 0;
   if (config->partitions < 0 || config->partitions > 3) return 0;
diff --git a/third_party/libwebp/src/enc/cost_enc.h b/third_party/libwebp/src/enc/cost_enc.h
index ba51ddd..cf594bc 100644
--- a/third_party/libwebp/src/enc/cost_enc.h
+++ b/third_party/libwebp/src/enc/cost_enc.h
@@ -84,4 +84,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_ENC_COST_ENC_H_ */
+#endif  // WEBP_ENC_COST_ENC_H_
diff --git a/third_party/libwebp/src/enc/frame_enc.c b/third_party/libwebp/src/enc/frame_enc.c
index 20bc99f..3c96774 100644
--- a/third_party/libwebp/src/enc/frame_enc.c
+++ b/third_party/libwebp/src/enc/frame_enc.c
@@ -37,10 +37,15 @@
 // we allow 2k of extra head-room in PARTITION0 limit.
 #define PARTITION0_SIZE_LIMIT ((VP8_MAX_PARTITION0_SIZE - 2048ULL) << 11)
 
+static float Clamp(float v, float min, float max) {
+  return (v < min) ? min : (v > max) ? max : v;
+}
+
 typedef struct {  // struct for organizing convergence in either size or PSNR
   int is_first;
   float dq;
   float q, last_q;
+  float qmin, qmax;
   double value, last_value;   // PSNR or size
   double target;
   int do_size_search;
@@ -53,7 +58,9 @@
 
   s->is_first = 1;
   s->dq = 10.f;
-  s->q = s->last_q = enc->config_->quality;
+  s->qmin = 1.f * enc->config_->qmin;
+  s->qmax = 1.f * enc->config_->qmax;
+  s->q = s->last_q = Clamp(enc->config_->quality, s->qmin, s->qmax);
   s->target = do_size_search ? (double)target_size
             : (target_PSNR > 0.) ? target_PSNR
             : 40.;   // default, just in case
@@ -62,10 +69,6 @@
   return do_size_search;
 }
 
-static float Clamp(float v, float min, float max) {
-  return (v < min) ? min : (v > max) ? max : v;
-}
-
 static float ComputeNextQ(PassStats* const s) {
   float dq;
   if (s->is_first) {
@@ -81,7 +84,7 @@
   s->dq = Clamp(dq, -30.f, 30.f);
   s->last_q = s->q;
   s->last_value = s->value;
-  s->q = Clamp(s->q + s->dq, 0.f, 100.f);
+  s->q = Clamp(s->q + s->dq, s->qmin, s->qmax);
   return s->q;
 }
 
@@ -692,7 +695,7 @@
   }
   if (!ok) {
     VP8EncFreeBitWriters(enc);  // malloc error occurred
-    WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
   }
   return ok;
 }
@@ -722,6 +725,7 @@
   } else {
     // Something bad happened -> need to do some memory cleanup.
     VP8EncFreeBitWriters(enc);
+    return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
   }
   return ok;
 }
@@ -757,6 +761,11 @@
     // *then* decide how to code the skip decision if there's one.
     if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) {
       CodeResiduals(it.bw_, &it, &info);
+      if (it.bw_->error_) {
+        // enc->pic_->error_code is set in PostLoopFinalize().
+        ok = 0;
+        break;
+      }
     } else {   // reset predictors after a skip
       ResetAfterSkip(&it);
     }
@@ -781,6 +790,7 @@
   // Roughly refresh the proba eight times per pass
   int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
   int num_pass_left = enc->config_->pass;
+  int remaining_progress = 40;  // percents
   const int do_search = enc->do_search_;
   VP8EncIterator it;
   VP8EncProba* const proba = &enc->proba_;
@@ -808,6 +818,9 @@
     uint64_t size_p0 = 0;
     uint64_t distortion = 0;
     int cnt = max_count;
+    // The final number of passes is not trivial to know in advance.
+    const int pass_progress = remaining_progress / (2 + num_pass_left);
+    remaining_progress -= pass_progress;
     VP8IteratorInit(enc, &it);
     SetLoopParams(enc, stats.q);
     if (is_last_pass) {
@@ -835,7 +848,7 @@
         StoreSideInfo(&it);
         VP8StoreFilterStats(&it);
         VP8IteratorExport(&it);
-        ok = VP8IteratorProgress(&it, 20);
+        ok = VP8IteratorProgress(&it, pass_progress);
       }
       VP8IteratorSaveBoundary(&it);
     } while (ok && VP8IteratorNext(&it));
@@ -854,9 +867,10 @@
     }
 
 #if (DEBUG_SEARCH > 0)
-    printf("#%2d metric:%.1lf -> %.1lf   last_q=%.2lf q=%.2lf dq=%.2lf\n",
+    printf("#%2d metric:%.1lf -> %.1lf   last_q=%.2lf q=%.2lf dq=%.2lf "
+           " range:[%.1f, %.1f]\n",
            num_pass_left, stats.last_value, stats.value,
-           stats.last_q, stats.q, stats.dq);
+           stats.last_q, stats.q, stats.dq, stats.qmin, stats.qmax);
 #endif
     if (enc->max_i4_header_bits_ > 0 && size_p0 > PARTITION0_SIZE_LIMIT) {
       ++num_pass_left;
@@ -880,7 +894,8 @@
     ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
                        (const uint8_t*)proba->coeffs_, 1);
   }
-  ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
+  ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + remaining_progress,
+                                &enc->percent_);
   return PostLoopFinalize(&it, ok);
 }
 
diff --git a/third_party/libwebp/src/enc/histogram_enc.c b/third_party/libwebp/src/enc/histogram_enc.c
index ce1a1bd..d11255d 100644
--- a/third_party/libwebp/src/enc/histogram_enc.c
+++ b/third_party/libwebp/src/enc/histogram_enc.c
@@ -13,19 +13,21 @@
 #include "src/webp/config.h"
 #endif
 
+#include <float.h>
 #if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #else
 #include <math.h>
 #endif
 
-#include "src/enc/backward_references_enc.h"
-#include "src/enc/histogram_enc.h"
 #include "src/dsp/lossless.h"
 #include "src/dsp/lossless_common.h"
+#include "src/enc/backward_references_enc.h"
+#include "src/enc/histogram_enc.h"
+#include "src/enc/vp8i_enc.h"
 #include "src/utils/utils.h"
 
-#define MAX_COST 1.e38
+#define MAX_BIT_COST FLT_MAX
 
 // Number of partitions for the three dominant (literal, red and blue) symbol
 // costs.
@@ -55,10 +57,12 @@
                           VP8LHistogram* const dst) {
   uint32_t* const dst_literal = dst->literal_;
   const int dst_cache_bits = dst->palette_code_bits_;
+  const int literal_size = VP8LHistogramNumCodes(dst_cache_bits);
   const int histo_size = VP8LGetHistogramSize(dst_cache_bits);
   assert(src->palette_code_bits_ == dst_cache_bits);
   memcpy(dst, src, histo_size);
   dst->literal_ = dst_literal;
+  memcpy(dst->literal_, src->literal_, literal_size * sizeof(*dst->literal_));
 }
 
 int VP8LGetHistogramSize(int cache_bits) {
@@ -95,9 +99,19 @@
   VP8LHistogramStoreRefs(refs, p);
 }
 
-void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits) {
+void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits,
+                       int init_arrays) {
   p->palette_code_bits_ = palette_code_bits;
-  HistogramClear(p);
+  if (init_arrays) {
+    HistogramClear(p);
+  } else {
+    p->trivial_symbol_ = 0;
+    p->bit_cost_ = 0.;
+    p->literal_cost_ = 0.;
+    p->red_cost_ = 0.;
+    p->blue_cost_ = 0.;
+    memset(p->is_used_, 0, sizeof(p->is_used_));
+  }
 }
 
 VP8LHistogram* VP8LAllocateHistogram(int cache_bits) {
@@ -108,37 +122,84 @@
   histo = (VP8LHistogram*)memory;
   // literal_ won't necessary be aligned.
   histo->literal_ = (uint32_t*)(memory + sizeof(VP8LHistogram));
-  VP8LHistogramInit(histo, cache_bits);
+  VP8LHistogramInit(histo, cache_bits, /*init_arrays=*/ 0);
   return histo;
 }
 
+// Resets the pointers of the histograms to point to the bit buffer in the set.
+static void HistogramSetResetPointers(VP8LHistogramSet* const set,
+                                      int cache_bits) {
+  int i;
+  const int histo_size = VP8LGetHistogramSize(cache_bits);
+  uint8_t* memory = (uint8_t*) (set->histograms);
+  memory += set->max_size * sizeof(*set->histograms);
+  for (i = 0; i < set->max_size; ++i) {
+    memory = (uint8_t*) WEBP_ALIGN(memory);
+    set->histograms[i] = (VP8LHistogram*) memory;
+    // literal_ won't necessary be aligned.
+    set->histograms[i]->literal_ = (uint32_t*)(memory + sizeof(VP8LHistogram));
+    memory += histo_size;
+  }
+}
+
+// Returns the total size of the VP8LHistogramSet.
+static size_t HistogramSetTotalSize(int size, int cache_bits) {
+  const int histo_size = VP8LGetHistogramSize(cache_bits);
+  return (sizeof(VP8LHistogramSet) + size * (sizeof(VP8LHistogram*) +
+          histo_size + WEBP_ALIGN_CST));
+}
+
 VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
   int i;
   VP8LHistogramSet* set;
-  const int histo_size = VP8LGetHistogramSize(cache_bits);
-  const size_t total_size =
-      sizeof(*set) + size * (sizeof(*set->histograms) +
-      histo_size + WEBP_ALIGN_CST);
+  const size_t total_size = HistogramSetTotalSize(size, cache_bits);
   uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
   if (memory == NULL) return NULL;
 
   set = (VP8LHistogramSet*)memory;
   memory += sizeof(*set);
   set->histograms = (VP8LHistogram**)memory;
-  memory += size * sizeof(*set->histograms);
   set->max_size = size;
   set->size = size;
+  HistogramSetResetPointers(set, cache_bits);
   for (i = 0; i < size; ++i) {
-    memory = (uint8_t*)WEBP_ALIGN(memory);
-    set->histograms[i] = (VP8LHistogram*)memory;
-    // literal_ won't necessary be aligned.
-    set->histograms[i]->literal_ = (uint32_t*)(memory + sizeof(VP8LHistogram));
-    VP8LHistogramInit(set->histograms[i], cache_bits);
-    memory += histo_size;
+    VP8LHistogramInit(set->histograms[i], cache_bits, /*init_arrays=*/ 0);
   }
   return set;
 }
 
+void VP8LHistogramSetClear(VP8LHistogramSet* const set) {
+  int i;
+  const int cache_bits = set->histograms[0]->palette_code_bits_;
+  const int size = set->max_size;
+  const size_t total_size = HistogramSetTotalSize(size, cache_bits);
+  uint8_t* memory = (uint8_t*)set;
+
+  memset(memory, 0, total_size);
+  memory += sizeof(*set);
+  set->histograms = (VP8LHistogram**)memory;
+  set->max_size = size;
+  set->size = size;
+  HistogramSetResetPointers(set, cache_bits);
+  for (i = 0; i < size; ++i) {
+    set->histograms[i]->palette_code_bits_ = cache_bits;
+  }
+}
+
+// Removes the histogram 'i' from 'set' by setting it to NULL.
+static void HistogramSetRemoveHistogram(VP8LHistogramSet* const set, int i,
+                                        int* const num_used) {
+  assert(set->histograms[i] != NULL);
+  set->histograms[i] = NULL;
+  --*num_used;
+  // If we remove the last valid one, shrink until the next valid one.
+  if (i == set->size - 1) {
+    while (set->size >= 1 && set->histograms[set->size - 1] == NULL) {
+      --set->size;
+    }
+  }
+}
+
 // -----------------------------------------------------------------------------
 
 void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
@@ -153,6 +214,7 @@
   } else if (PixOrCopyIsCacheIdx(v)) {
     const int literal_ix =
         NUM_LITERAL_CODES + NUM_LENGTH_CODES + PixOrCopyCacheIdx(v);
+    assert(histo->palette_code_bits_ != 0);
     ++histo->literal_[literal_ix];
   } else {
     int code, extra_bits;
@@ -172,8 +234,8 @@
 // -----------------------------------------------------------------------------
 // Entropy-related functions.
 
-static WEBP_INLINE double BitsEntropyRefine(const VP8LBitEntropy* entropy) {
-  double mix;
+static WEBP_INLINE float BitsEntropyRefine(const VP8LBitEntropy* entropy) {
+  float mix;
   if (entropy->nonzeros < 5) {
     if (entropy->nonzeros <= 1) {
       return 0;
@@ -182,66 +244,67 @@
     // Let's mix in a bit of entropy to favor good clustering when
     // distributions of these are combined.
     if (entropy->nonzeros == 2) {
-      return 0.99 * entropy->sum + 0.01 * entropy->entropy;
+      return 0.99f * entropy->sum + 0.01f * entropy->entropy;
     }
     // No matter what the entropy says, we cannot be better than min_limit
     // with Huffman coding. I am mixing a bit of entropy into the
     // min_limit since it produces much better (~0.5 %) compression results
     // perhaps because of better entropy clustering.
     if (entropy->nonzeros == 3) {
-      mix = 0.95;
+      mix = 0.95f;
     } else {
-      mix = 0.7;  // nonzeros == 4.
+      mix = 0.7f;  // nonzeros == 4.
     }
   } else {
-    mix = 0.627;
+    mix = 0.627f;
   }
 
   {
-    double min_limit = 2 * entropy->sum - entropy->max_val;
-    min_limit = mix * min_limit + (1.0 - mix) * entropy->entropy;
+    float min_limit = 2.f * entropy->sum - entropy->max_val;
+    min_limit = mix * min_limit + (1.f - mix) * entropy->entropy;
     return (entropy->entropy < min_limit) ? min_limit : entropy->entropy;
   }
 }
 
-double VP8LBitsEntropy(const uint32_t* const array, int n) {
+float VP8LBitsEntropy(const uint32_t* const array, int n) {
   VP8LBitEntropy entropy;
   VP8LBitsEntropyUnrefined(array, n, &entropy);
 
   return BitsEntropyRefine(&entropy);
 }
 
-static double InitialHuffmanCost(void) {
+static float InitialHuffmanCost(void) {
   // Small bias because Huffman code length is typically not stored in
   // full length.
   static const int kHuffmanCodeOfHuffmanCodeSize = CODE_LENGTH_CODES * 3;
-  static const double kSmallBias = 9.1;
+  static const float kSmallBias = 9.1f;
   return kHuffmanCodeOfHuffmanCodeSize - kSmallBias;
 }
 
 // Finalize the Huffman cost based on streak numbers and length type (<3 or >=3)
-static double FinalHuffmanCost(const VP8LStreaks* const stats) {
+static float FinalHuffmanCost(const VP8LStreaks* const stats) {
   // The constants in this function are experimental and got rounded from
   // their original values in 1/8 when switched to 1/1024.
-  double retval = InitialHuffmanCost();
+  float retval = InitialHuffmanCost();
   // Second coefficient: Many zeros in the histogram are covered efficiently
   // by a run-length encode. Originally 2/8.
-  retval += stats->counts[0] * 1.5625 + 0.234375 * stats->streaks[0][1];
+  retval += stats->counts[0] * 1.5625f + 0.234375f * stats->streaks[0][1];
   // Second coefficient: Constant values are encoded less efficiently, but still
   // RLE'ed. Originally 6/8.
-  retval += stats->counts[1] * 2.578125 + 0.703125 * stats->streaks[1][1];
+  retval += stats->counts[1] * 2.578125f + 0.703125f * stats->streaks[1][1];
   // 0s are usually encoded more efficiently than non-0s.
   // Originally 15/8.
-  retval += 1.796875 * stats->streaks[0][0];
+  retval += 1.796875f * stats->streaks[0][0];
   // Originally 26/8.
-  retval += 3.28125 * stats->streaks[1][0];
+  retval += 3.28125f * stats->streaks[1][0];
   return retval;
 }
 
 // Get the symbol entropy for the distribution 'population'.
 // Set 'trivial_sym', if there's only one symbol present in the distribution.
-static double PopulationCost(const uint32_t* const population, int length,
-                             uint32_t* const trivial_sym) {
+static float PopulationCost(const uint32_t* const population, int length,
+                            uint32_t* const trivial_sym,
+                            uint8_t* const is_used) {
   VP8LBitEntropy bit_entropy;
   VP8LStreaks stats;
   VP8LGetEntropyUnrefined(population, length, &bit_entropy, &stats);
@@ -249,15 +312,18 @@
     *trivial_sym = (bit_entropy.nonzeros == 1) ? bit_entropy.nonzero_code
                                                : VP8L_NON_TRIVIAL_SYM;
   }
+  // The histogram is used if there is at least one non-zero streak.
+  *is_used = (stats.streaks[1][0] != 0 || stats.streaks[1][1] != 0);
 
   return BitsEntropyRefine(&bit_entropy) + FinalHuffmanCost(&stats);
 }
 
 // trivial_at_end is 1 if the two histograms only have one element that is
 // non-zero: both the zero-th one, or both the last one.
-static WEBP_INLINE double GetCombinedEntropy(const uint32_t* const X,
-                                             const uint32_t* const Y,
-                                             int length, int trivial_at_end) {
+static WEBP_INLINE float GetCombinedEntropy(const uint32_t* const X,
+                                            const uint32_t* const Y, int length,
+                                            int is_X_used, int is_Y_used,
+                                            int trivial_at_end) {
   VP8LStreaks stats;
   if (trivial_at_end) {
     // This configuration is due to palettization that transforms an indexed
@@ -266,28 +332,43 @@
     // Only FinalHuffmanCost needs to be evaluated.
     memset(&stats, 0, sizeof(stats));
     // Deal with the non-zero value at index 0 or length-1.
-    stats.streaks[1][0] += 1;
+    stats.streaks[1][0] = 1;
     // Deal with the following/previous zero streak.
-    stats.counts[0] += 1;
-    stats.streaks[0][1] += length - 1;
+    stats.counts[0] = 1;
+    stats.streaks[0][1] = length - 1;
     return FinalHuffmanCost(&stats);
   } else {
     VP8LBitEntropy bit_entropy;
-    VP8LGetCombinedEntropyUnrefined(X, Y, length, &bit_entropy, &stats);
+    if (is_X_used) {
+      if (is_Y_used) {
+        VP8LGetCombinedEntropyUnrefined(X, Y, length, &bit_entropy, &stats);
+      } else {
+        VP8LGetEntropyUnrefined(X, length, &bit_entropy, &stats);
+      }
+    } else {
+      if (is_Y_used) {
+        VP8LGetEntropyUnrefined(Y, length, &bit_entropy, &stats);
+      } else {
+        memset(&stats, 0, sizeof(stats));
+        stats.counts[0] = 1;
+        stats.streaks[0][length > 3] = length;
+        VP8LBitEntropyInit(&bit_entropy);
+      }
+    }
 
     return BitsEntropyRefine(&bit_entropy) + FinalHuffmanCost(&stats);
   }
 }
 
 // Estimates the Entropy + Huffman + other block overhead size cost.
-double VP8LHistogramEstimateBits(const VP8LHistogram* const p) {
+float VP8LHistogramEstimateBits(VP8LHistogram* const p) {
   return
-      PopulationCost(
-          p->literal_, VP8LHistogramNumCodes(p->palette_code_bits_), NULL)
-      + PopulationCost(p->red_, NUM_LITERAL_CODES, NULL)
-      + PopulationCost(p->blue_, NUM_LITERAL_CODES, NULL)
-      + PopulationCost(p->alpha_, NUM_LITERAL_CODES, NULL)
-      + PopulationCost(p->distance_, NUM_DISTANCE_CODES, NULL)
+      PopulationCost(p->literal_, VP8LHistogramNumCodes(p->palette_code_bits_),
+                     NULL, &p->is_used_[0])
+      + PopulationCost(p->red_, NUM_LITERAL_CODES, NULL, &p->is_used_[1])
+      + PopulationCost(p->blue_, NUM_LITERAL_CODES, NULL, &p->is_used_[2])
+      + PopulationCost(p->alpha_, NUM_LITERAL_CODES, NULL, &p->is_used_[3])
+      + PopulationCost(p->distance_, NUM_DISTANCE_CODES, NULL, &p->is_used_[4])
       + VP8LExtraCost(p->literal_ + NUM_LITERAL_CODES, NUM_LENGTH_CODES)
       + VP8LExtraCost(p->distance_, NUM_DISTANCE_CODES);
 }
@@ -297,13 +378,13 @@
 
 static int GetCombinedHistogramEntropy(const VP8LHistogram* const a,
                                        const VP8LHistogram* const b,
-                                       double cost_threshold,
-                                       double* cost) {
+                                       float cost_threshold, float* cost) {
   const int palette_code_bits = a->palette_code_bits_;
   int trivial_at_end = 0;
   assert(a->palette_code_bits_ == b->palette_code_bits_);
   *cost += GetCombinedEntropy(a->literal_, b->literal_,
-                              VP8LHistogramNumCodes(palette_code_bits), 0);
+                              VP8LHistogramNumCodes(palette_code_bits),
+                              a->is_used_[0], b->is_used_[0], 0);
   *cost += VP8LExtraCostCombined(a->literal_ + NUM_LITERAL_CODES,
                                  b->literal_ + NUM_LITERAL_CODES,
                                  NUM_LENGTH_CODES);
@@ -323,19 +404,23 @@
   }
 
   *cost +=
-      GetCombinedEntropy(a->red_, b->red_, NUM_LITERAL_CODES, trivial_at_end);
+      GetCombinedEntropy(a->red_, b->red_, NUM_LITERAL_CODES, a->is_used_[1],
+                         b->is_used_[1], trivial_at_end);
   if (*cost > cost_threshold) return 0;
 
   *cost +=
-      GetCombinedEntropy(a->blue_, b->blue_, NUM_LITERAL_CODES, trivial_at_end);
-  if (*cost > cost_threshold) return 0;
-
-  *cost += GetCombinedEntropy(a->alpha_, b->alpha_, NUM_LITERAL_CODES,
-                              trivial_at_end);
+      GetCombinedEntropy(a->blue_, b->blue_, NUM_LITERAL_CODES, a->is_used_[2],
+                         b->is_used_[2], trivial_at_end);
   if (*cost > cost_threshold) return 0;
 
   *cost +=
-      GetCombinedEntropy(a->distance_, b->distance_, NUM_DISTANCE_CODES, 0);
+      GetCombinedEntropy(a->alpha_, b->alpha_, NUM_LITERAL_CODES,
+                         a->is_used_[3], b->is_used_[3], trivial_at_end);
+  if (*cost > cost_threshold) return 0;
+
+  *cost +=
+      GetCombinedEntropy(a->distance_, b->distance_, NUM_DISTANCE_CODES,
+                         a->is_used_[4], b->is_used_[4], 0);
   *cost +=
       VP8LExtraCostCombined(a->distance_, b->distance_, NUM_DISTANCE_CODES);
   if (*cost > cost_threshold) return 0;
@@ -358,12 +443,11 @@
 // Since the previous score passed is 'cost_threshold', we only need to compare
 // the partial cost against 'cost_threshold + C(a) + C(b)' to possibly bail-out
 // early.
-static double HistogramAddEval(const VP8LHistogram* const a,
-                               const VP8LHistogram* const b,
-                               VP8LHistogram* const out,
-                               double cost_threshold) {
-  double cost = 0;
-  const double sum_cost = a->bit_cost_ + b->bit_cost_;
+static float HistogramAddEval(const VP8LHistogram* const a,
+                              const VP8LHistogram* const b,
+                              VP8LHistogram* const out, float cost_threshold) {
+  float cost = 0;
+  const float sum_cost = a->bit_cost_ + b->bit_cost_;
   cost_threshold += sum_cost;
 
   if (GetCombinedHistogramEntropy(a, b, cost_threshold, &cost)) {
@@ -378,10 +462,12 @@
 // Same as HistogramAddEval(), except that the resulting histogram
 // is not stored. Only the cost C(a+b) - C(a) is evaluated. We omit
 // the term C(b) which is constant over all the evaluations.
-static double HistogramAddThresh(const VP8LHistogram* const a,
-                                 const VP8LHistogram* const b,
-                                 double cost_threshold) {
-  double cost = -a->bit_cost_;
+static float HistogramAddThresh(const VP8LHistogram* const a,
+                                const VP8LHistogram* const b,
+                                float cost_threshold) {
+  float cost;
+  assert(a != NULL && b != NULL);
+  cost = -a->bit_cost_;
   GetCombinedHistogramEntropy(a, b, cost_threshold, &cost);
   return cost;
 }
@@ -390,24 +476,22 @@
 
 // The structure to keep track of cost range for the three dominant entropy
 // symbols.
-// TODO(skal): Evaluate if float can be used here instead of double for
-// representing the entropy costs.
 typedef struct {
-  double literal_max_;
-  double literal_min_;
-  double red_max_;
-  double red_min_;
-  double blue_max_;
-  double blue_min_;
+  float literal_max_;
+  float literal_min_;
+  float red_max_;
+  float red_min_;
+  float blue_max_;
+  float blue_min_;
 } DominantCostRange;
 
 static void DominantCostRangeInit(DominantCostRange* const c) {
   c->literal_max_ = 0.;
-  c->literal_min_ = MAX_COST;
+  c->literal_min_ = MAX_BIT_COST;
   c->red_max_ = 0.;
-  c->red_min_ = MAX_COST;
+  c->red_min_ = MAX_BIT_COST;
   c->blue_max_ = 0.;
-  c->blue_min_ = MAX_COST;
+  c->blue_min_ = MAX_BIT_COST;
 }
 
 static void UpdateDominantCostRange(
@@ -422,17 +506,19 @@
 
 static void UpdateHistogramCost(VP8LHistogram* const h) {
   uint32_t alpha_sym, red_sym, blue_sym;
-  const double alpha_cost =
-      PopulationCost(h->alpha_, NUM_LITERAL_CODES, &alpha_sym);
-  const double distance_cost =
-      PopulationCost(h->distance_, NUM_DISTANCE_CODES, NULL) +
+  const float alpha_cost =
+      PopulationCost(h->alpha_, NUM_LITERAL_CODES, &alpha_sym, &h->is_used_[3]);
+  const float distance_cost =
+      PopulationCost(h->distance_, NUM_DISTANCE_CODES, NULL, &h->is_used_[4]) +
       VP8LExtraCost(h->distance_, NUM_DISTANCE_CODES);
   const int num_codes = VP8LHistogramNumCodes(h->palette_code_bits_);
-  h->literal_cost_ = PopulationCost(h->literal_, num_codes, NULL) +
-                     VP8LExtraCost(h->literal_ + NUM_LITERAL_CODES,
-                                   NUM_LENGTH_CODES);
-  h->red_cost_ = PopulationCost(h->red_, NUM_LITERAL_CODES, &red_sym);
-  h->blue_cost_ = PopulationCost(h->blue_, NUM_LITERAL_CODES, &blue_sym);
+  h->literal_cost_ =
+      PopulationCost(h->literal_, num_codes, NULL, &h->is_used_[0]) +
+          VP8LExtraCost(h->literal_ + NUM_LITERAL_CODES, NUM_LENGTH_CODES);
+  h->red_cost_ =
+      PopulationCost(h->red_, NUM_LITERAL_CODES, &red_sym, &h->is_used_[1]);
+  h->blue_cost_ =
+      PopulationCost(h->blue_, NUM_LITERAL_CODES, &blue_sym, &h->is_used_[2]);
   h->bit_cost_ = h->literal_cost_ + h->red_cost_ + h->blue_cost_ +
                  alpha_cost + distance_cost;
   if ((alpha_sym | red_sym | blue_sym) == VP8L_NON_TRIVIAL_SYM) {
@@ -443,10 +529,10 @@
   }
 }
 
-static int GetBinIdForEntropy(double min, double max, double val) {
-  const double range = max - min;
+static int GetBinIdForEntropy(float min, float max, float val) {
+  const float range = max - min;
   if (range > 0.) {
-    const double delta = val - min;
+    const float delta = val - min;
     return (int)((NUM_PARTITIONS - 1e-6) * delta / range);
   } else {
     return 0;
@@ -477,6 +563,7 @@
   VP8LHistogram** const histograms = image_histo->histograms;
   VP8LRefsCursor c = VP8LRefsCursorInit(backward_refs);
   assert(histo_bits > 0);
+  VP8LHistogramSetClear(image_histo);
   while (VP8LRefsCursorOk(&c)) {
     const PixOrCopy* const v = c.cur_pos;
     const int ix = (y >> histo_bits) * histo_xsize + (x >> histo_bits);
@@ -491,17 +578,37 @@
 }
 
 // Copies the histograms and computes its bit_cost.
-static void HistogramCopyAndAnalyze(
-    VP8LHistogramSet* const orig_histo, VP8LHistogramSet* const image_histo) {
-  int i;
-  const int histo_size = orig_histo->size;
+static const uint16_t kInvalidHistogramSymbol = (uint16_t)(-1);
+static void HistogramCopyAndAnalyze(VP8LHistogramSet* const orig_histo,
+                                    VP8LHistogramSet* const image_histo,
+                                    int* const num_used,
+                                    uint16_t* const histogram_symbols) {
+  int i, cluster_id;
+  int num_used_orig = *num_used;
   VP8LHistogram** const orig_histograms = orig_histo->histograms;
   VP8LHistogram** const histograms = image_histo->histograms;
-  for (i = 0; i < histo_size; ++i) {
+  assert(image_histo->max_size == orig_histo->max_size);
+  for (cluster_id = 0, i = 0; i < orig_histo->max_size; ++i) {
     VP8LHistogram* const histo = orig_histograms[i];
     UpdateHistogramCost(histo);
-    // Copy histograms from orig_histo[] to image_histo[].
-    HistogramCopy(histo, histograms[i]);
+
+    // Skip the histogram if it is completely empty, which can happen for tiles
+    // with no information (when they are skipped because of LZ77).
+    if (!histo->is_used_[0] && !histo->is_used_[1] && !histo->is_used_[2]
+        && !histo->is_used_[3] && !histo->is_used_[4]) {
+      // The first histogram is always used. If an histogram is empty, we set
+      // its id to be the same as the previous one: this will improve
+      // compressibility for later LZ77.
+      assert(i > 0);
+      HistogramSetRemoveHistogram(image_histo, i, num_used);
+      HistogramSetRemoveHistogram(orig_histo, i, &num_used_orig);
+      histogram_symbols[i] = kInvalidHistogramSymbol;
+    } else {
+      // Copy histograms from orig_histo[] to image_histo[].
+      HistogramCopy(histo, histograms[i]);
+      histogram_symbols[i] = cluster_id++;
+      assert(cluster_id <= image_histo->max_size);
+    }
   }
 }
 
@@ -518,29 +625,29 @@
 
   // Analyze the dominant (literal, red and blue) entropy costs.
   for (i = 0; i < histo_size; ++i) {
+    if (histograms[i] == NULL) continue;
     UpdateDominantCostRange(histograms[i], &cost_range);
   }
 
   // bin-hash histograms on three of the dominant (literal, red and blue)
   // symbol costs and store the resulting bin_id for each histogram.
   for (i = 0; i < histo_size; ++i) {
+    // bin_map[i] is not set to a special value as its use will later be guarded
+    // by another (histograms[i] == NULL).
+    if (histograms[i] == NULL) continue;
     bin_map[i] = GetHistoBinIndex(histograms[i], &cost_range, low_effort);
   }
 }
 
-// Compact image_histo[] by merging some histograms with same bin_id together if
-// it's advantageous.
-static void HistogramCombineEntropyBin(VP8LHistogramSet* const image_histo,
-                                       VP8LHistogram* cur_combo,
-                                       const uint16_t* const bin_map,
-                                       int bin_map_size, int num_bins,
-                                       double combine_cost_factor,
-                                       int low_effort) {
+// Merges some histograms with same bin_id together if it's advantageous.
+// Sets the remaining histograms to NULL.
+static void HistogramCombineEntropyBin(
+    VP8LHistogramSet* const image_histo, int* num_used,
+    const uint16_t* const clusters, uint16_t* const cluster_mappings,
+    VP8LHistogram* cur_combo, const uint16_t* const bin_map, int num_bins,
+    float combine_cost_factor, int low_effort) {
   VP8LHistogram** const histograms = image_histo->histograms;
   int idx;
-  // Work in-place: processed histograms are put at the beginning of
-  // image_histo[]. At the end, we just have to truncate the array.
-  int size = 0;
   struct {
     int16_t first;    // position of the histogram that accumulates all
                       // histograms with the same bin_id
@@ -553,23 +660,25 @@
     bin_info[idx].num_combine_failures = 0;
   }
 
-  for (idx = 0; idx < bin_map_size; ++idx) {
-    const int bin_id = bin_map[idx];
-    const int first = bin_info[bin_id].first;
-    assert(size <= idx);
+  // By default, a cluster matches itself.
+  for (idx = 0; idx < *num_used; ++idx) cluster_mappings[idx] = idx;
+  for (idx = 0; idx < image_histo->size; ++idx) {
+    int bin_id, first;
+    if (histograms[idx] == NULL) continue;
+    bin_id = bin_map[idx];
+    first = bin_info[bin_id].first;
     if (first == -1) {
-      // just move histogram #idx to its final position
-      histograms[size] = histograms[idx];
-      bin_info[bin_id].first = size++;
+      bin_info[bin_id].first = idx;
     } else if (low_effort) {
       HistogramAdd(histograms[idx], histograms[first], histograms[first]);
+      HistogramSetRemoveHistogram(image_histo, idx, num_used);
+      cluster_mappings[clusters[idx]] = clusters[first];
     } else {
       // try to merge #idx into #first (both share the same bin_id)
-      const double bit_cost = histograms[idx]->bit_cost_;
-      const double bit_cost_thresh = -bit_cost * combine_cost_factor;
-      const double curr_cost_diff =
-          HistogramAddEval(histograms[first], histograms[idx],
-                           cur_combo, bit_cost_thresh);
+      const float bit_cost = histograms[idx]->bit_cost_;
+      const float bit_cost_thresh = -bit_cost * combine_cost_factor;
+      const float curr_cost_diff = HistogramAddEval(
+          histograms[first], histograms[idx], cur_combo, bit_cost_thresh);
       if (curr_cost_diff < bit_cost_thresh) {
         // Try to merge two histograms only if the combo is a trivial one or
         // the two candidate histograms are already non-trivial.
@@ -585,19 +694,18 @@
             bin_info[bin_id].num_combine_failures >= max_combine_failures) {
           // move the (better) merged histogram to its final slot
           HistogramSwap(&cur_combo, &histograms[first]);
+          HistogramSetRemoveHistogram(image_histo, idx, num_used);
+          cluster_mappings[clusters[idx]] = clusters[first];
         } else {
-          histograms[size++] = histograms[idx];
           ++bin_info[bin_id].num_combine_failures;
         }
-      } else {
-        histograms[size++] = histograms[idx];
       }
     }
   }
-  image_histo->size = size;
   if (low_effort) {
     // for low_effort case, update the final cost when everything is merged
-    for (idx = 0; idx < size; ++idx) {
+    for (idx = 0; idx < image_histo->size; ++idx) {
+      if (histograms[idx] == NULL) continue;
       UpdateHistogramCost(histograms[idx]);
     }
   }
@@ -618,8 +726,8 @@
 typedef struct {
   int idx1;
   int idx2;
-  double cost_diff;
-  double cost_combo;
+  float cost_diff;
+  float cost_combo;
 } HistogramPair;
 
 typedef struct {
@@ -628,16 +736,9 @@
   int max_size;
 } HistoQueue;
 
-static int HistoQueueInit(HistoQueue* const histo_queue, const int max_index) {
+static int HistoQueueInit(HistoQueue* const histo_queue, const int max_size) {
   histo_queue->size = 0;
-  // max_index^2 for the queue size is safe. If you look at
-  // HistogramCombineGreedy, and imagine that UpdateQueueFront always pushes
-  // data to the queue, you insert at most:
-  // - max_index*(max_index-1)/2 (the first two for loops)
-  // - max_index - 1 in the last for loop at the first iteration of the while
-  //   loop, max_index - 2 at the second iteration ... therefore
-  //   max_index*(max_index-1)/2 overall too
-  histo_queue->max_size = max_index * max_index;
+  histo_queue->max_size = max_size;
   // We allocate max_size + 1 because the last element at index "size" is
   // used as temporary data (and it could be up to max_size).
   histo_queue->queue = (HistogramPair*)WebPSafeMalloc(
@@ -678,17 +779,29 @@
   }
 }
 
+// Update the cost diff and combo of a pair of histograms. This needs to be
+// called when the the histograms have been merged with a third one.
+static void HistoQueueUpdatePair(const VP8LHistogram* const h1,
+                                 const VP8LHistogram* const h2, float threshold,
+                                 HistogramPair* const pair) {
+  const float sum_cost = h1->bit_cost_ + h2->bit_cost_;
+  pair->cost_combo = 0.;
+  GetCombinedHistogramEntropy(h1, h2, sum_cost + threshold, &pair->cost_combo);
+  pair->cost_diff = pair->cost_combo - sum_cost;
+}
+
 // Create a pair from indices "idx1" and "idx2" provided its cost
 // is inferior to "threshold", a negative entropy.
 // It returns the cost of the pair, or 0. if it superior to threshold.
-static double HistoQueuePush(HistoQueue* const histo_queue,
-                             VP8LHistogram** const histograms, int idx1,
-                             int idx2, double threshold) {
+static float HistoQueuePush(HistoQueue* const histo_queue,
+                            VP8LHistogram** const histograms, int idx1,
+                            int idx2, float threshold) {
   const VP8LHistogram* h1;
   const VP8LHistogram* h2;
   HistogramPair pair;
-  double sum_cost;
 
+  // Stop here if the queue is full.
+  if (histo_queue->size == histo_queue->max_size) return 0.;
   assert(threshold <= 0.);
   if (idx1 > idx2) {
     const int tmp = idx2;
@@ -699,16 +812,12 @@
   pair.idx2 = idx2;
   h1 = histograms[idx1];
   h2 = histograms[idx2];
-  sum_cost = h1->bit_cost_ + h2->bit_cost_;
-  pair.cost_combo = 0.;
-  GetCombinedHistogramEntropy(h1, h2, sum_cost + threshold, &pair.cost_combo);
-  pair.cost_diff = pair.cost_combo - sum_cost;
+
+  HistoQueueUpdatePair(h1, h2, threshold, &pair);
 
   // Do not even consider the pair if it does not improve the entropy.
   if (pair.cost_diff >= threshold) return 0.;
 
-  // We cannot add more elements than the capacity.
-  assert(histo_queue->size < histo_queue->max_size);
   histo_queue->queue[histo_queue->size++] = pair;
   HistoQueueUpdateHead(histo_queue, &histo_queue->queue[histo_queue->size - 1]);
 
@@ -719,42 +828,43 @@
 
 // Combines histograms by continuously choosing the one with the highest cost
 // reduction.
-static int HistogramCombineGreedy(VP8LHistogramSet* const image_histo) {
+static int HistogramCombineGreedy(VP8LHistogramSet* const image_histo,
+                                  int* const num_used) {
   int ok = 0;
-  int image_histo_size = image_histo->size;
+  const int image_histo_size = image_histo->size;
   int i, j;
   VP8LHistogram** const histograms = image_histo->histograms;
-  // Indexes of remaining histograms.
-  int* const clusters =
-      (int*)WebPSafeMalloc(image_histo_size, sizeof(*clusters));
   // Priority queue of histogram pairs.
   HistoQueue histo_queue;
 
-  if (!HistoQueueInit(&histo_queue, image_histo_size) || clusters == NULL) {
+  // image_histo_size^2 for the queue size is safe. If you look at
+  // HistogramCombineGreedy, and imagine that UpdateQueueFront always pushes
+  // data to the queue, you insert at most:
+  // - image_histo_size*(image_histo_size-1)/2 (the first two for loops)
+  // - image_histo_size - 1 in the last for loop at the first iteration of
+  //   the while loop, image_histo_size - 2 at the second iteration ...
+  //   therefore image_histo_size*(image_histo_size-1)/2 overall too
+  if (!HistoQueueInit(&histo_queue, image_histo_size * image_histo_size)) {
     goto End;
   }
 
   for (i = 0; i < image_histo_size; ++i) {
-    // Initialize clusters indexes.
-    clusters[i] = i;
+    if (image_histo->histograms[i] == NULL) continue;
     for (j = i + 1; j < image_histo_size; ++j) {
-      // Initialize positions array.
+      // Initialize queue.
+      if (image_histo->histograms[j] == NULL) continue;
       HistoQueuePush(&histo_queue, histograms, i, j, 0.);
     }
   }
 
-  while (image_histo_size > 1 && histo_queue.size > 0) {
+  while (histo_queue.size > 0) {
     const int idx1 = histo_queue.queue[0].idx1;
     const int idx2 = histo_queue.queue[0].idx2;
     HistogramAdd(histograms[idx2], histograms[idx1], histograms[idx1]);
     histograms[idx1]->bit_cost_ = histo_queue.queue[0].cost_combo;
+
     // Remove merged histogram.
-    for (i = 0; i + 1 < image_histo_size; ++i) {
-      if (clusters[i] >= idx2) {
-        clusters[i] = clusters[i + 1];
-      }
-    }
-    --image_histo_size;
+    HistogramSetRemoveHistogram(image_histo, idx2, num_used);
 
     // Remove pairs intersecting the just combined best pair.
     for (i = 0; i < histo_queue.size;) {
@@ -769,24 +879,15 @@
     }
 
     // Push new pairs formed with combined histogram to the queue.
-    for (i = 0; i < image_histo_size; ++i) {
-      if (clusters[i] != idx1) {
-        HistoQueuePush(&histo_queue, histograms, idx1, clusters[i], 0.);
-      }
-    }
-  }
-  // Move remaining histograms to the beginning of the array.
-  for (i = 0; i < image_histo_size; ++i) {
-    if (i != clusters[i]) {  // swap the two histograms
-      HistogramSwap(&histograms[i], &histograms[clusters[i]]);
+    for (i = 0; i < image_histo->size; ++i) {
+      if (i == idx1 || image_histo->histograms[i] == NULL) continue;
+      HistoQueuePush(&histo_queue, image_histo->histograms, idx1, i, 0.);
     }
   }
 
-  image_histo->size = image_histo_size;
   ok = 1;
 
  End:
-  WebPSafeFree(clusters);
   HistoQueueClear(&histo_queue);
   return ok;
 }
@@ -794,47 +895,68 @@
 // Perform histogram aggregation using a stochastic approach.
 // 'do_greedy' is set to 1 if a greedy approach needs to be performed
 // afterwards, 0 otherwise.
+static int PairComparison(const void* idx1, const void* idx2) {
+  // To be used with bsearch: <0 when *idx1<*idx2, >0 if >, 0 when ==.
+  return (*(int*) idx1 - *(int*) idx2);
+}
 static int HistogramCombineStochastic(VP8LHistogramSet* const image_histo,
-                                      int min_cluster_size,
+                                      int* const num_used, int min_cluster_size,
                                       int* const do_greedy) {
-  int iter;
+  int j, iter;
   uint32_t seed = 1;
   int tries_with_no_success = 0;
-  int image_histo_size = image_histo->size;
-  const int outer_iters = image_histo_size;
+  const int outer_iters = *num_used;
   const int num_tries_no_success = outer_iters / 2;
   VP8LHistogram** const histograms = image_histo->histograms;
-  // Priority queue of histogram pairs. Its size of "kCostHeapSizeSqrt"^2
+  // Priority queue of histogram pairs. Its size of 'kHistoQueueSize'
   // impacts the quality of the compression and the speed: the smaller the
   // faster but the worse for the compression.
   HistoQueue histo_queue;
-  const int kHistoQueueSizeSqrt = 3;
+  const int kHistoQueueSize = 9;
   int ok = 0;
+  // mapping from an index in image_histo with no NULL histogram to the full
+  // blown image_histo.
+  int* mappings;
 
-  if (!HistoQueueInit(&histo_queue, kHistoQueueSizeSqrt)) {
-    goto End;
+  if (*num_used < min_cluster_size) {
+    *do_greedy = 1;
+    return 1;
   }
-  // Collapse similar histograms in 'image_histo'.
-  ++min_cluster_size;
-  for (iter = 0; iter < outer_iters && image_histo_size >= min_cluster_size &&
-                 ++tries_with_no_success < num_tries_no_success;
-       ++iter) {
-    double best_cost =
-        (histo_queue.size == 0) ? 0. : histo_queue.queue[0].cost_diff;
-    int best_idx1 = -1, best_idx2 = 1;
-    int j;
-    const uint32_t rand_range = (image_histo_size - 1) * image_histo_size;
-    // image_histo_size / 2 was chosen empirically. Less means faster but worse
-    // compression.
-    const int num_tries = image_histo_size / 2;
 
-    for (j = 0; j < num_tries; ++j) {
-      double curr_cost;
+  mappings = (int*) WebPSafeMalloc(*num_used, sizeof(*mappings));
+  if (mappings == NULL) return 0;
+  if (!HistoQueueInit(&histo_queue, kHistoQueueSize)) goto End;
+  // Fill the initial mapping.
+  for (j = 0, iter = 0; iter < image_histo->size; ++iter) {
+    if (histograms[iter] == NULL) continue;
+    mappings[j++] = iter;
+  }
+  assert(j == *num_used);
+
+  // Collapse similar histograms in 'image_histo'.
+  for (iter = 0;
+       iter < outer_iters && *num_used >= min_cluster_size &&
+           ++tries_with_no_success < num_tries_no_success;
+       ++iter) {
+    int* mapping_index;
+    float best_cost =
+        (histo_queue.size == 0) ? 0.f : histo_queue.queue[0].cost_diff;
+    int best_idx1 = -1, best_idx2 = 1;
+    const uint32_t rand_range = (*num_used - 1) * (*num_used);
+    // (*num_used) / 2 was chosen empirically. Less means faster but worse
+    // compression.
+    const int num_tries = (*num_used) / 2;
+
+    // Pick random samples.
+    for (j = 0; *num_used >= 2 && j < num_tries; ++j) {
+      float curr_cost;
       // Choose two different histograms at random and try to combine them.
       const uint32_t tmp = MyRand(&seed) % rand_range;
-      const uint32_t idx1 = tmp / (image_histo_size - 1);
-      uint32_t idx2 = tmp % (image_histo_size - 1);
+      uint32_t idx1 = tmp / (*num_used - 1);
+      uint32_t idx2 = tmp % (*num_used - 1);
       if (idx2 >= idx1) ++idx2;
+      idx1 = mappings[idx1];
+      idx2 = mappings[idx2];
 
       // Calculate cost reduction on combination.
       curr_cost =
@@ -847,18 +969,21 @@
     }
     if (histo_queue.size == 0) continue;
 
-    // Merge the two best histograms.
+    // Get the best histograms.
     best_idx1 = histo_queue.queue[0].idx1;
     best_idx2 = histo_queue.queue[0].idx2;
     assert(best_idx1 < best_idx2);
-    HistogramAddEval(histograms[best_idx1], histograms[best_idx2],
-                     histograms[best_idx1], 0);
-    // Swap the best_idx2 histogram with the last one (which is now unused).
-    --image_histo_size;
-    if (best_idx2 != image_histo_size) {
-      HistogramSwap(&histograms[image_histo_size], &histograms[best_idx2]);
-    }
-    histograms[image_histo_size] = NULL;
+    // Pop best_idx2 from mappings.
+    mapping_index = (int*) bsearch(&best_idx2, mappings, *num_used,
+                                   sizeof(best_idx2), &PairComparison);
+    assert(mapping_index != NULL);
+    memmove(mapping_index, mapping_index + 1, sizeof(*mapping_index) *
+        ((*num_used) - (mapping_index - mappings) - 1));
+    // Merge the histograms and remove best_idx2 from the queue.
+    HistogramAdd(histograms[best_idx2], histograms[best_idx1],
+                 histograms[best_idx1]);
+    histograms[best_idx1]->bit_cost_ = histo_queue.queue[0].cost_combo;
+    HistogramSetRemoveHistogram(image_histo, best_idx2, num_used);
     // Parse the queue and update each pair that deals with best_idx1,
     // best_idx2 or image_histo_size.
     for (j = 0; j < histo_queue.size;) {
@@ -881,12 +1006,6 @@
         p->idx2 = best_idx1;
         do_eval = 1;
       }
-      if (p->idx2 == image_histo_size) {
-        // No need to re-evaluate here as it does not involve a pair
-        // containing best_idx1 or best_idx2.
-        p->idx2 = best_idx2;
-      }
-      assert(p->idx2 < image_histo_size);
       // Make sure the index order is respected.
       if (p->idx1 > p->idx2) {
         const int tmp = p->idx2;
@@ -895,8 +1014,7 @@
       }
       if (do_eval) {
         // Re-evaluate the cost of an updated pair.
-        GetCombinedHistogramEntropy(histograms[p->idx1], histograms[p->idx2], 0,
-                                    &p->cost_diff);
+        HistoQueueUpdatePair(histograms[p->idx1], histograms[p->idx2], 0., p);
         if (p->cost_diff >= 0.) {
           HistoQueuePopPair(&histo_queue, p);
           continue;
@@ -905,15 +1023,14 @@
       HistoQueueUpdateHead(&histo_queue, p);
       ++j;
     }
-
     tries_with_no_success = 0;
   }
-  image_histo->size = image_histo_size;
-  *do_greedy = (image_histo->size <= min_cluster_size);
+  *do_greedy = (*num_used <= min_cluster_size);
   ok = 1;
 
-End:
+ End:
   HistoQueueClear(&histo_queue);
+  WebPSafeFree(mappings);
   return ok;
 }
 
@@ -921,23 +1038,29 @@
 // Histogram refinement
 
 // Find the best 'out' histogram for each of the 'in' histograms.
+// At call-time, 'out' contains the histograms of the clusters.
 // Note: we assume that out[]->bit_cost_ is already up-to-date.
 static void HistogramRemap(const VP8LHistogramSet* const in,
-                           const VP8LHistogramSet* const out,
+                           VP8LHistogramSet* const out,
                            uint16_t* const symbols) {
   int i;
   VP8LHistogram** const in_histo = in->histograms;
   VP8LHistogram** const out_histo = out->histograms;
-  const int in_size = in->size;
+  const int in_size = out->max_size;
   const int out_size = out->size;
   if (out_size > 1) {
     for (i = 0; i < in_size; ++i) {
       int best_out = 0;
-      double best_bits = MAX_COST;
+      float best_bits = MAX_BIT_COST;
       int k;
+      if (in_histo[i] == NULL) {
+        // Arbitrarily set to the previous value if unused to help future LZ77.
+        symbols[i] = symbols[i - 1];
+        continue;
+      }
       for (k = 0; k < out_size; ++k) {
-        const double cur_bits =
-            HistogramAddThresh(out_histo[k], in_histo[i], best_bits);
+        float cur_bits;
+        cur_bits = HistogramAddThresh(out_histo[k], in_histo[i], best_bits);
         if (k == 0 || cur_bits < best_bits) {
           best_bits = cur_bits;
           best_out = k;
@@ -953,37 +1076,104 @@
   }
 
   // Recompute each out based on raw and symbols.
-  for (i = 0; i < out_size; ++i) {
-    HistogramClear(out_histo[i]);
-  }
+  VP8LHistogramSetClear(out);
+  out->size = out_size;
 
   for (i = 0; i < in_size; ++i) {
-    const int idx = symbols[i];
+    int idx;
+    if (in_histo[i] == NULL) continue;
+    idx = symbols[i];
     HistogramAdd(in_histo[i], out_histo[idx], out_histo[idx]);
   }
 }
 
-static double GetCombineCostFactor(int histo_size, int quality) {
-  double combine_cost_factor = 0.16;
+static float GetCombineCostFactor(int histo_size, int quality) {
+  float combine_cost_factor = 0.16f;
   if (quality < 90) {
-    if (histo_size > 256) combine_cost_factor /= 2.;
-    if (histo_size > 512) combine_cost_factor /= 2.;
-    if (histo_size > 1024) combine_cost_factor /= 2.;
-    if (quality <= 50) combine_cost_factor /= 2.;
+    if (histo_size > 256) combine_cost_factor /= 2.f;
+    if (histo_size > 512) combine_cost_factor /= 2.f;
+    if (histo_size > 1024) combine_cost_factor /= 2.f;
+    if (quality <= 50) combine_cost_factor /= 2.f;
   }
   return combine_cost_factor;
 }
 
+// Given a HistogramSet 'set', the mapping of clusters 'cluster_mapping' and the
+// current assignment of the cells in 'symbols', merge the clusters and
+// assign the smallest possible clusters values.
+static void OptimizeHistogramSymbols(const VP8LHistogramSet* const set,
+                                     uint16_t* const cluster_mappings,
+                                     int num_clusters,
+                                     uint16_t* const cluster_mappings_tmp,
+                                     uint16_t* const symbols) {
+  int i, cluster_max;
+  int do_continue = 1;
+  // First, assign the lowest cluster to each pixel.
+  while (do_continue) {
+    do_continue = 0;
+    for (i = 0; i < num_clusters; ++i) {
+      int k;
+      k = cluster_mappings[i];
+      while (k != cluster_mappings[k]) {
+        cluster_mappings[k] = cluster_mappings[cluster_mappings[k]];
+        k = cluster_mappings[k];
+      }
+      if (k != cluster_mappings[i]) {
+        do_continue = 1;
+        cluster_mappings[i] = k;
+      }
+    }
+  }
+  // Create a mapping from a cluster id to its minimal version.
+  cluster_max = 0;
+  memset(cluster_mappings_tmp, 0,
+         set->max_size * sizeof(*cluster_mappings_tmp));
+  assert(cluster_mappings[0] == 0);
+  // Re-map the ids.
+  for (i = 0; i < set->max_size; ++i) {
+    int cluster;
+    if (symbols[i] == kInvalidHistogramSymbol) continue;
+    cluster = cluster_mappings[symbols[i]];
+    assert(symbols[i] < num_clusters);
+    if (cluster > 0 && cluster_mappings_tmp[cluster] == 0) {
+      ++cluster_max;
+      cluster_mappings_tmp[cluster] = cluster_max;
+    }
+    symbols[i] = cluster_mappings_tmp[cluster];
+  }
+
+  // Make sure all cluster values are used.
+  cluster_max = 0;
+  for (i = 0; i < set->max_size; ++i) {
+    if (symbols[i] == kInvalidHistogramSymbol) continue;
+    if (symbols[i] <= cluster_max) continue;
+    ++cluster_max;
+    assert(symbols[i] == cluster_max);
+  }
+}
+
+static void RemoveEmptyHistograms(VP8LHistogramSet* const image_histo) {
+  uint32_t size;
+  int i;
+  for (i = 0, size = 0; i < image_histo->size; ++i) {
+    if (image_histo->histograms[i] == NULL) continue;
+    image_histo->histograms[size++] = image_histo->histograms[i];
+  }
+  image_histo->size = size;
+}
+
 int VP8LGetHistoImageSymbols(int xsize, int ysize,
-                             const VP8LBackwardRefs* const refs,
-                             int quality, int low_effort,
-                             int histo_bits, int cache_bits,
+                             const VP8LBackwardRefs* const refs, int quality,
+                             int low_effort, int histogram_bits, int cache_bits,
                              VP8LHistogramSet* const image_histo,
                              VP8LHistogram* const tmp_histo,
-                             uint16_t* const histogram_symbols) {
-  int ok = 0;
-  const int histo_xsize = histo_bits ? VP8LSubSampleSize(xsize, histo_bits) : 1;
-  const int histo_ysize = histo_bits ? VP8LSubSampleSize(ysize, histo_bits) : 1;
+                             uint16_t* const histogram_symbols,
+                             const WebPPicture* const pic, int percent_range,
+                             int* const percent) {
+  const int histo_xsize =
+      histogram_bits ? VP8LSubSampleSize(xsize, histogram_bits) : 1;
+  const int histo_ysize =
+      histogram_bits ? VP8LSubSampleSize(ysize, histogram_bits) : 1;
   const int image_histo_raw_size = histo_xsize * histo_ysize;
   VP8LHistogramSet* const orig_histo =
       VP8LAllocateHistogramSet(image_histo_raw_size, cache_bits);
@@ -991,28 +1181,39 @@
   // histograms of small sizes (as bin_map will be very sparse) and
   // maximum quality q==100 (to preserve the compression gains at that level).
   const int entropy_combine_num_bins = low_effort ? NUM_PARTITIONS : BIN_SIZE;
-  const int entropy_combine =
-      (orig_histo->size > entropy_combine_num_bins * 2) && (quality < 100);
-
-  if (orig_histo == NULL) goto Error;
+  int entropy_combine;
+  uint16_t* const map_tmp =
+      WebPSafeMalloc(2 * image_histo_raw_size, sizeof(map_tmp));
+  uint16_t* const cluster_mappings = map_tmp + image_histo_raw_size;
+  int num_used = image_histo_raw_size;
+  if (orig_histo == NULL || map_tmp == NULL) {
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    goto Error;
+  }
 
   // Construct the histograms from backward references.
-  HistogramBuild(xsize, histo_bits, refs, orig_histo);
+  HistogramBuild(xsize, histogram_bits, refs, orig_histo);
   // Copies the histograms and computes its bit_cost.
-  HistogramCopyAndAnalyze(orig_histo, image_histo);
+  // histogram_symbols is optimized
+  HistogramCopyAndAnalyze(orig_histo, image_histo, &num_used,
+                          histogram_symbols);
+
+  entropy_combine =
+      (num_used > entropy_combine_num_bins * 2) && (quality < 100);
 
   if (entropy_combine) {
-    const int bin_map_size = orig_histo->size;
-    // Reuse histogram_symbols storage. By definition, it's guaranteed to be ok.
-    uint16_t* const bin_map = histogram_symbols;
-    const double combine_cost_factor =
+    uint16_t* const bin_map = map_tmp;
+    const float combine_cost_factor =
         GetCombineCostFactor(image_histo_raw_size, quality);
+    const uint32_t num_clusters = num_used;
 
-    HistogramAnalyzeEntropyBin(orig_histo, bin_map, low_effort);
+    HistogramAnalyzeEntropyBin(image_histo, bin_map, low_effort);
     // Collapse histograms with similar entropy.
-    HistogramCombineEntropyBin(image_histo, tmp_histo, bin_map, bin_map_size,
-                               entropy_combine_num_bins, combine_cost_factor,
-                               low_effort);
+    HistogramCombineEntropyBin(
+        image_histo, &num_used, histogram_symbols, cluster_mappings, tmp_histo,
+        bin_map, entropy_combine_num_bins, combine_cost_factor, low_effort);
+    OptimizeHistogramSymbols(image_histo, cluster_mappings, num_clusters,
+                             map_tmp, histogram_symbols);
   }
 
   // Don't combine the histograms using stochastic and greedy heuristics for
@@ -1022,21 +1223,30 @@
     // cubic ramp between 1 and MAX_HISTO_GREEDY:
     const int threshold_size = (int)(1 + (x * x * x) * (MAX_HISTO_GREEDY - 1));
     int do_greedy;
-    if (!HistogramCombineStochastic(image_histo, threshold_size, &do_greedy)) {
+    if (!HistogramCombineStochastic(image_histo, &num_used, threshold_size,
+                                    &do_greedy)) {
+      WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
       goto Error;
     }
-    if (do_greedy && !HistogramCombineGreedy(image_histo)) {
-      goto Error;
+    if (do_greedy) {
+      RemoveEmptyHistograms(image_histo);
+      if (!HistogramCombineGreedy(image_histo, &num_used)) {
+        WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+        goto Error;
+      }
     }
   }
 
-  // TODO(vrabaud): Optimize HistogramRemap for low-effort compression mode.
   // Find the optimal map from original histograms to the final ones.
+  RemoveEmptyHistograms(image_histo);
   HistogramRemap(orig_histo, image_histo, histogram_symbols);
 
-  ok = 1;
+  if (!WebPReportProgress(pic, *percent + percent_range, percent)) {
+    goto Error;
+  }
 
  Error:
   VP8LFreeHistogramSet(orig_histo);
-  return ok;
+  WebPSafeFree(map_tmp);
+  return (pic->error_code == VP8_ENC_OK);
 }
diff --git a/third_party/libwebp/src/enc/histogram_enc.h b/third_party/libwebp/src/enc/histogram_enc.h
index 0f9f48d..914e605 100644
--- a/third_party/libwebp/src/enc/histogram_enc.h
+++ b/third_party/libwebp/src/enc/histogram_enc.h
@@ -44,10 +44,11 @@
   int palette_code_bits_;
   uint32_t trivial_symbol_;  // True, if histograms for Red, Blue & Alpha
                              // literal symbols are single valued.
-  double bit_cost_;          // cached value of bit cost.
-  double literal_cost_;      // Cached values of dominant entropy costs:
-  double red_cost_;          // literal, red & blue.
-  double blue_cost_;
+  float bit_cost_;           // cached value of bit cost.
+  float literal_cost_;       // Cached values of dominant entropy costs:
+  float red_cost_;           // literal, red & blue.
+  float blue_cost_;
+  uint8_t is_used_[5];       // 5 for literal, red, blue, alpha, distance
 } VP8LHistogram;
 
 // Collection of histograms with fixed capacity, allocated as one
@@ -67,11 +68,13 @@
                          const VP8LBackwardRefs* const refs,
                          int palette_code_bits);
 
-// Return the size of the histogram for a given palette_code_bits.
-int VP8LGetHistogramSize(int palette_code_bits);
+// Return the size of the histogram for a given cache_bits.
+int VP8LGetHistogramSize(int cache_bits);
 
 // Set the palette_code_bits and reset the stats.
-void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits);
+// If init_arrays is true, the arrays are also filled with 0's.
+void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits,
+                       int init_arrays);
 
 // Collect all the references into a histogram (without reset)
 void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
@@ -87,6 +90,9 @@
 // using 'cache_bits'. Return NULL in case of memory error.
 VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits);
 
+// Set the histograms in set to 0.
+void VP8LHistogramSetClear(VP8LHistogramSet* const set);
+
 // Allocate and initialize histogram object with specified 'cache_bits'.
 // Returns NULL in case of memory error.
 // Special case of VP8LAllocateHistogramSet, with size equals 1.
@@ -103,21 +109,23 @@
       ((palette_code_bits > 0) ? (1 << palette_code_bits) : 0);
 }
 
-// Builds the histogram image.
+// Builds the histogram image. pic and percent are for progress.
+// Returns false in case of error (stored in pic->error_code).
 int VP8LGetHistoImageSymbols(int xsize, int ysize,
-                             const VP8LBackwardRefs* const refs,
-                             int quality, int low_effort,
-                             int histogram_bits, int cache_bits,
-                             VP8LHistogramSet* const image_in,
+                             const VP8LBackwardRefs* const refs, int quality,
+                             int low_effort, int histogram_bits, int cache_bits,
+                             VP8LHistogramSet* const image_histo,
                              VP8LHistogram* const tmp_histo,
-                             uint16_t* const histogram_symbols);
+                             uint16_t* const histogram_symbols,
+                             const WebPPicture* const pic, int percent_range,
+                             int* const percent);
 
 // Returns the entropy for the symbols in the input array.
-double VP8LBitsEntropy(const uint32_t* const array, int n);
+float VP8LBitsEntropy(const uint32_t* const array, int n);
 
 // Estimate how many bits the combined entropy of literals and distance
 // approximately maps to.
-double VP8LHistogramEstimateBits(const VP8LHistogram* const p);
+float VP8LHistogramEstimateBits(VP8LHistogram* const p);
 
 #ifdef __cplusplus
 }
diff --git a/third_party/libwebp/src/enc/iterator_enc.c b/third_party/libwebp/src/enc/iterator_enc.c
index 1df9cb0..4d6b618 100644
--- a/third_party/libwebp/src/enc/iterator_enc.c
+++ b/third_party/libwebp/src/enc/iterator_enc.c
@@ -132,7 +132,7 @@
   for (; i < total_len; ++i) dst[i] = dst[len - 1];
 }
 
-void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32) {
+void VP8IteratorImport(VP8EncIterator* const it, uint8_t* const tmp_32) {
   const VP8Encoder* const enc = it->enc_;
   const int x = it->x_, y = it->y_;
   const WebPPicture* const pic = enc->pic_;
diff --git a/third_party/libwebp/src/enc/picture_csp_enc.c b/third_party/libwebp/src/enc/picture_csp_enc.c
index 00a8f25..c623d89 100644
--- a/third_party/libwebp/src/enc/picture_csp_enc.c
+++ b/third_party/libwebp/src/enc/picture_csp_enc.c
@@ -22,12 +22,19 @@
 
 #include <stdlib.h>
 
+#include "sharpyuv/sharpyuv.h"
+#include "sharpyuv/sharpyuv_csp.h"
 #include "src/enc/vp8i_enc.h"
 #include "src/utils/random_utils.h"
 #include "src/utils/utils.h"
 #include "src/dsp/dsp.h"
 #include "src/dsp/lossless.h"
 #include "src/dsp/yuv.h"
+#include "src/dsp/cpu.h"
+
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h>
+#endif
 
 // Uncomment to disable gamma-compression during RGB->U/V averaging
 #define USE_GAMMA_COMPRESSION
@@ -68,16 +75,16 @@
 // Checking for the presence of non-opaque alpha.
 int WebPPictureHasTransparency(const WebPPicture* picture) {
   if (picture == NULL) return 0;
-  if (!picture->use_argb) {
-    return CheckNonOpaque(picture->a, picture->width, picture->height,
-                          1, picture->a_stride);
-  } else {
-    const int alpha_offset = ALPHA_OFFSET;
-    return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset,
-                          picture->width, picture->height,
-                          4, picture->argb_stride * sizeof(*picture->argb));
+  if (picture->use_argb) {
+    if (picture->argb != NULL) {
+      return CheckNonOpaque((const uint8_t*)picture->argb + ALPHA_OFFSET,
+                            picture->width, picture->height,
+                            4, picture->argb_stride * sizeof(*picture->argb));
+    }
+    return 0;
   }
-  return 0;
+  return CheckNonOpaque(picture->a, picture->width, picture->height,
+                        1, picture->a_stride);
 }
 
 //------------------------------------------------------------------------------
@@ -85,29 +92,31 @@
 
 #if defined(USE_GAMMA_COMPRESSION)
 
-// gamma-compensates loss of resolution during chroma subsampling
-#define kGamma 0.80      // for now we use a different gamma value than kGammaF
-#define kGammaFix 12     // fixed-point precision for linear values
-#define kGammaScale ((1 << kGammaFix) - 1)
-#define kGammaTabFix 7   // fixed-point fractional bits precision
-#define kGammaTabScale (1 << kGammaTabFix)
-#define kGammaTabRounder (kGammaTabScale >> 1)
-#define kGammaTabSize (1 << (kGammaFix - kGammaTabFix))
+// Gamma correction compensates loss of resolution during chroma subsampling.
+#define GAMMA_FIX 12      // fixed-point precision for linear values
+#define GAMMA_TAB_FIX 7   // fixed-point fractional bits precision
+#define GAMMA_TAB_SIZE (1 << (GAMMA_FIX - GAMMA_TAB_FIX))
+static const double kGamma = 0.80;
+static const int kGammaScale = ((1 << GAMMA_FIX) - 1);
+static const int kGammaTabScale = (1 << GAMMA_TAB_FIX);
+static const int kGammaTabRounder = (1 << GAMMA_TAB_FIX >> 1);
 
-static int kLinearToGammaTab[kGammaTabSize + 1];
+static int kLinearToGammaTab[GAMMA_TAB_SIZE + 1];
 static uint16_t kGammaToLinearTab[256];
 static volatile int kGammaTablesOk = 0;
+static void InitGammaTables(void);
+extern VP8CPUInfo VP8GetCPUInfo;
 
-static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTables(void) {
+WEBP_DSP_INIT_FUNC(InitGammaTables) {
   if (!kGammaTablesOk) {
     int v;
-    const double scale = (double)(1 << kGammaTabFix) / kGammaScale;
+    const double scale = (double)(1 << GAMMA_TAB_FIX) / kGammaScale;
     const double norm = 1. / 255.;
     for (v = 0; v <= 255; ++v) {
       kGammaToLinearTab[v] =
           (uint16_t)(pow(norm * v, kGamma) * kGammaScale + .5);
     }
-    for (v = 0; v <= kGammaTabSize; ++v) {
+    for (v = 0; v <= GAMMA_TAB_SIZE; ++v) {
       kLinearToGammaTab[v] = (int)(255. * pow(scale * v, 1. / kGamma) + .5);
     }
     kGammaTablesOk = 1;
@@ -119,12 +128,12 @@
 }
 
 static WEBP_INLINE int Interpolate(int v) {
-  const int tab_pos = v >> (kGammaTabFix + 2);    // integer part
+  const int tab_pos = v >> (GAMMA_TAB_FIX + 2);    // integer part
   const int x = v & ((kGammaTabScale << 2) - 1);  // fractional part
   const int v0 = kLinearToGammaTab[tab_pos];
   const int v1 = kLinearToGammaTab[tab_pos + 1];
   const int y = v1 * x + v0 * ((kGammaTabScale << 2) - x);   // interpolate
-  assert(tab_pos + 1 < kGammaTabSize + 1);
+  assert(tab_pos + 1 < GAMMA_TAB_SIZE + 1);
   return y;
 }
 
@@ -132,7 +141,7 @@
 // U/V value, suitable for RGBToU/V calls.
 static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
   const int y = Interpolate(base_value << shift);   // final uplifted value
-  return (y + kGammaTabRounder) >> kGammaTabFix;    // descale
+  return (y + kGammaTabRounder) >> GAMMA_TAB_FIX;    // descale
 }
 
 #else
@@ -166,414 +175,26 @@
 //------------------------------------------------------------------------------
 // Sharp RGB->YUV conversion
 
-static const int kNumIterations = 4;
 static const int kMinDimensionIterativeConversion = 4;
 
-// We could use SFIX=0 and only uint8_t for fixed_y_t, but it produces some
-// banding sometimes. Better use extra precision.
-#define SFIX 2                // fixed-point precision of RGB and Y/W
-typedef int16_t fixed_t;      // signed type with extra SFIX precision for UV
-typedef uint16_t fixed_y_t;   // unsigned type with extra SFIX precision for W
-
-#define SHALF (1 << SFIX >> 1)
-#define MAX_Y_T ((256 << SFIX) - 1)
-#define SROUNDER (1 << (YUV_FIX + SFIX - 1))
-
-#if defined(USE_GAMMA_COMPRESSION)
-
-// We use tables of different size and precision for the Rec709 / BT2020
-// transfer function.
-#define kGammaF (1./0.45)
-static uint32_t kLinearToGammaTabS[kGammaTabSize + 2];
-#define GAMMA_TO_LINEAR_BITS 14
-static uint32_t kGammaToLinearTabS[MAX_Y_T + 1];   // size scales with Y_FIX
-static volatile int kGammaTablesSOk = 0;
-
-static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTablesS(void) {
-  assert(2 * GAMMA_TO_LINEAR_BITS < 32);  // we use uint32_t intermediate values
-  if (!kGammaTablesSOk) {
-    int v;
-    const double norm = 1. / MAX_Y_T;
-    const double scale = 1. / kGammaTabSize;
-    const double a = 0.09929682680944;
-    const double thresh = 0.018053968510807;
-    const double final_scale = 1 << GAMMA_TO_LINEAR_BITS;
-    for (v = 0; v <= MAX_Y_T; ++v) {
-      const double g = norm * v;
-      double value;
-      if (g <= thresh * 4.5) {
-        value = g / 4.5;
-      } else {
-        const double a_rec = 1. / (1. + a);
-        value = pow(a_rec * (g + a), kGammaF);
-      }
-      kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5);
-    }
-    for (v = 0; v <= kGammaTabSize; ++v) {
-      const double g = scale * v;
-      double value;
-      if (g <= thresh) {
-        value = 4.5 * g;
-      } else {
-        value = (1. + a) * pow(g, 1. / kGammaF) - a;
-      }
-      // we already incorporate the 1/2 rounding constant here
-      kLinearToGammaTabS[v] =
-          (uint32_t)(MAX_Y_T * value) + (1 << GAMMA_TO_LINEAR_BITS >> 1);
-    }
-    // to prevent small rounding errors to cause read-overflow:
-    kLinearToGammaTabS[kGammaTabSize + 1] = kLinearToGammaTabS[kGammaTabSize];
-    kGammaTablesSOk = 1;
-  }
-}
-
-// return value has a fixed-point precision of GAMMA_TO_LINEAR_BITS
-static WEBP_INLINE uint32_t GammaToLinearS(int v) {
-  return kGammaToLinearTabS[v];
-}
-
-static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) {
-  // 'value' is in GAMMA_TO_LINEAR_BITS fractional precision
-  const uint32_t v = value * kGammaTabSize;
-  const uint32_t tab_pos = v >> GAMMA_TO_LINEAR_BITS;
-  // fractional part, in GAMMA_TO_LINEAR_BITS fixed-point precision
-  const uint32_t x = v - (tab_pos << GAMMA_TO_LINEAR_BITS);  // fractional part
-  // v0 / v1 are in GAMMA_TO_LINEAR_BITS fixed-point precision (range [0..1])
-  const uint32_t v0 = kLinearToGammaTabS[tab_pos + 0];
-  const uint32_t v1 = kLinearToGammaTabS[tab_pos + 1];
-  // Final interpolation. Note that rounding is already included.
-  const uint32_t v2 = (v1 - v0) * x;    // note: v1 >= v0.
-  const uint32_t result = v0 + (v2 >> GAMMA_TO_LINEAR_BITS);
-  return result;
-}
-
-#else
-
-static void InitGammaTablesS(void) {}
-static WEBP_INLINE uint32_t GammaToLinearS(int v) {
-  return (v << GAMMA_TO_LINEAR_BITS) / MAX_Y_T;
-}
-static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) {
-  return (MAX_Y_T * value) >> GAMMA_TO_LINEAR_BITS;
-}
-
-#endif    // USE_GAMMA_COMPRESSION
-
-//------------------------------------------------------------------------------
-
-static uint8_t clip_8b(fixed_t v) {
-  return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
-}
-
-static fixed_y_t clip_y(int y) {
-  return (!(y & ~MAX_Y_T)) ? (fixed_y_t)y : (y < 0) ? 0 : MAX_Y_T;
-}
-
-//------------------------------------------------------------------------------
-
-static int RGBToGray(int r, int g, int b) {
-  const int luma = 13933 * r + 46871 * g + 4732 * b + YUV_HALF;
-  return (luma >> YUV_FIX);
-}
-
-static uint32_t ScaleDown(int a, int b, int c, int d) {
-  const uint32_t A = GammaToLinearS(a);
-  const uint32_t B = GammaToLinearS(b);
-  const uint32_t C = GammaToLinearS(c);
-  const uint32_t D = GammaToLinearS(d);
-  return LinearToGammaS((A + B + C + D + 2) >> 2);
-}
-
-static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w) {
-  int i;
-  for (i = 0; i < w; ++i) {
-    const uint32_t R = GammaToLinearS(src[0 * w + i]);
-    const uint32_t G = GammaToLinearS(src[1 * w + i]);
-    const uint32_t B = GammaToLinearS(src[2 * w + i]);
-    const uint32_t Y = RGBToGray(R, G, B);
-    dst[i] = (fixed_y_t)LinearToGammaS(Y);
-  }
-}
-
-static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
-                         fixed_t* dst, int uv_w) {
-  int i;
-  for (i = 0; i < uv_w; ++i) {
-    const int r = ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1],
-                            src2[0 * uv_w + 0], src2[0 * uv_w + 1]);
-    const int g = ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1],
-                            src2[2 * uv_w + 0], src2[2 * uv_w + 1]);
-    const int b = ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1],
-                            src2[4 * uv_w + 0], src2[4 * uv_w + 1]);
-    const int W = RGBToGray(r, g, b);
-    dst[0 * uv_w] = (fixed_t)(r - W);
-    dst[1 * uv_w] = (fixed_t)(g - W);
-    dst[2 * uv_w] = (fixed_t)(b - W);
-    dst  += 1;
-    src1 += 2;
-    src2 += 2;
-  }
-}
-
-static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
-  int i;
-  for (i = 0; i < w; ++i) {
-    y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
-  }
-}
-
-//------------------------------------------------------------------------------
-
-static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0) {
-  const int v0 = (A * 3 + B + 2) >> 2;
-  return clip_y(v0 + W0);
-}
-
-//------------------------------------------------------------------------------
-
-static WEBP_INLINE fixed_y_t UpLift(uint8_t a) {  // 8bit -> SFIX
-  return ((fixed_y_t)a << SFIX) | SHALF;
-}
-
-static void ImportOneRow(const uint8_t* const r_ptr,
-                         const uint8_t* const g_ptr,
-                         const uint8_t* const b_ptr,
-                         int step,
-                         int pic_width,
-                         fixed_y_t* const dst) {
-  int i;
-  const int w = (pic_width + 1) & ~1;
-  for (i = 0; i < pic_width; ++i) {
-    const int off = i * step;
-    dst[i + 0 * w] = UpLift(r_ptr[off]);
-    dst[i + 1 * w] = UpLift(g_ptr[off]);
-    dst[i + 2 * w] = UpLift(b_ptr[off]);
-  }
-  if (pic_width & 1) {  // replicate rightmost pixel
-    dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
-    dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
-    dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
-  }
-}
-
-static void InterpolateTwoRows(const fixed_y_t* const best_y,
-                               const fixed_t* prev_uv,
-                               const fixed_t* cur_uv,
-                               const fixed_t* next_uv,
-                               int w,
-                               fixed_y_t* out1,
-                               fixed_y_t* out2) {
-  const int uv_w = w >> 1;
-  const int len = (w - 1) >> 1;   // length to filter
-  int k = 3;
-  while (k-- > 0) {   // process each R/G/B segments in turn
-    // special boundary case for i==0
-    out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0]);
-    out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w]);
-
-    WebPSharpYUVFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1);
-    WebPSharpYUVFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1);
-
-    // special boundary case for i == w - 1 when w is even
-    if (!(w & 1)) {
-      out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
-                            best_y[w - 1 + 0]);
-      out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
-                            best_y[w - 1 + w]);
-    }
-    out1 += w;
-    out2 += w;
-    prev_uv += uv_w;
-    cur_uv  += uv_w;
-    next_uv += uv_w;
-  }
-}
-
-static WEBP_INLINE uint8_t ConvertRGBToY(int r, int g, int b) {
-  const int luma = 16839 * r + 33059 * g + 6420 * b + SROUNDER;
-  return clip_8b(16 + (luma >> (YUV_FIX + SFIX)));
-}
-
-static WEBP_INLINE uint8_t ConvertRGBToU(int r, int g, int b) {
-  const int u =  -9719 * r - 19081 * g + 28800 * b + SROUNDER;
-  return clip_8b(128 + (u >> (YUV_FIX + SFIX)));
-}
-
-static WEBP_INLINE uint8_t ConvertRGBToV(int r, int g, int b) {
-  const int v = +28800 * r - 24116 * g -  4684 * b + SROUNDER;
-  return clip_8b(128 + (v >> (YUV_FIX + SFIX)));
-}
-
-static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
-                            WebPPicture* const picture) {
-  int i, j;
-  uint8_t* dst_y = picture->y;
-  uint8_t* dst_u = picture->u;
-  uint8_t* dst_v = picture->v;
-  const fixed_t* const best_uv_base = best_uv;
-  const int w = (picture->width + 1) & ~1;
-  const int h = (picture->height + 1) & ~1;
-  const int uv_w = w >> 1;
-  const int uv_h = h >> 1;
-  for (best_uv = best_uv_base, j = 0; j < picture->height; ++j) {
-    for (i = 0; i < picture->width; ++i) {
-      const int off = (i >> 1);
-      const int W = best_y[i];
-      const int r = best_uv[off + 0 * uv_w] + W;
-      const int g = best_uv[off + 1 * uv_w] + W;
-      const int b = best_uv[off + 2 * uv_w] + W;
-      dst_y[i] = ConvertRGBToY(r, g, b);
-    }
-    best_y += w;
-    best_uv += (j & 1) * 3 * uv_w;
-    dst_y += picture->y_stride;
-  }
-  for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
-    for (i = 0; i < uv_w; ++i) {
-      const int off = i;
-      const int r = best_uv[off + 0 * uv_w];
-      const int g = best_uv[off + 1 * uv_w];
-      const int b = best_uv[off + 2 * uv_w];
-      dst_u[i] = ConvertRGBToU(r, g, b);
-      dst_v[i] = ConvertRGBToV(r, g, b);
-    }
-    best_uv += 3 * uv_w;
-    dst_u += picture->uv_stride;
-    dst_v += picture->uv_stride;
-  }
-  return 1;
-}
-
 //------------------------------------------------------------------------------
 // Main function
 
-#define SAFE_ALLOC(W, H, T) ((T*)WebPSafeMalloc((W) * (H), sizeof(T)))
-
 static int PreprocessARGB(const uint8_t* r_ptr,
                           const uint8_t* g_ptr,
                           const uint8_t* b_ptr,
                           int step, int rgb_stride,
                           WebPPicture* const picture) {
-  // we expand the right/bottom border if needed
-  const int w = (picture->width + 1) & ~1;
-  const int h = (picture->height + 1) & ~1;
-  const int uv_w = w >> 1;
-  const int uv_h = h >> 1;
-  uint64_t prev_diff_y_sum = ~0;
-  int j, iter;
-
-  // TODO(skal): allocate one big memory chunk. But for now, it's easier
-  // for valgrind debugging to have several chunks.
-  fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t);   // scratch
-  fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
-  fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
-  fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
-  fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
-  fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
-  fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
-  fixed_y_t* best_y = best_y_base;
-  fixed_y_t* target_y = target_y_base;
-  fixed_t* best_uv = best_uv_base;
-  fixed_t* target_uv = target_uv_base;
-  const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
-  int ok;
-
-  if (best_y_base == NULL || best_uv_base == NULL ||
-      target_y_base == NULL || target_uv_base == NULL ||
-      best_rgb_y == NULL || best_rgb_uv == NULL ||
-      tmp_buffer == NULL) {
-    ok = WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
-    goto End;
+  const int ok = SharpYuvConvert(
+      r_ptr, g_ptr, b_ptr, step, rgb_stride, /*rgb_bit_depth=*/8,
+      picture->y, picture->y_stride, picture->u, picture->uv_stride, picture->v,
+      picture->uv_stride, /*yuv_bit_depth=*/8, picture->width,
+      picture->height, SharpYuvGetConversionMatrix(kSharpYuvMatrixWebp));
+  if (!ok) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
   }
-  assert(picture->width >= kMinDimensionIterativeConversion);
-  assert(picture->height >= kMinDimensionIterativeConversion);
-
-  WebPInitConvertARGBToYUV();
-
-  // Import RGB samples to W/RGB representation.
-  for (j = 0; j < picture->height; j += 2) {
-    const int is_last_row = (j == picture->height - 1);
-    fixed_y_t* const src1 = tmp_buffer + 0 * w;
-    fixed_y_t* const src2 = tmp_buffer + 3 * w;
-
-    // prepare two rows of input
-    ImportOneRow(r_ptr, g_ptr, b_ptr, step, picture->width, src1);
-    if (!is_last_row) {
-      ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
-                   step, picture->width, src2);
-    } else {
-      memcpy(src2, src1, 3 * w * sizeof(*src2));
-    }
-    StoreGray(src1, best_y + 0, w);
-    StoreGray(src2, best_y + w, w);
-
-    UpdateW(src1, target_y, w);
-    UpdateW(src2, target_y + w, w);
-    UpdateChroma(src1, src2, target_uv, uv_w);
-    memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
-    best_y += 2 * w;
-    best_uv += 3 * uv_w;
-    target_y += 2 * w;
-    target_uv += 3 * uv_w;
-    r_ptr += 2 * rgb_stride;
-    g_ptr += 2 * rgb_stride;
-    b_ptr += 2 * rgb_stride;
-  }
-
-  // Iterate and resolve clipping conflicts.
-  for (iter = 0; iter < kNumIterations; ++iter) {
-    const fixed_t* cur_uv = best_uv_base;
-    const fixed_t* prev_uv = best_uv_base;
-    uint64_t diff_y_sum = 0;
-
-    best_y = best_y_base;
-    best_uv = best_uv_base;
-    target_y = target_y_base;
-    target_uv = target_uv_base;
-    for (j = 0; j < h; j += 2) {
-      fixed_y_t* const src1 = tmp_buffer + 0 * w;
-      fixed_y_t* const src2 = tmp_buffer + 3 * w;
-      {
-        const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
-        InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w, src1, src2);
-        prev_uv = cur_uv;
-        cur_uv = next_uv;
-      }
-
-      UpdateW(src1, best_rgb_y + 0 * w, w);
-      UpdateW(src2, best_rgb_y + 1 * w, w);
-      UpdateChroma(src1, src2, best_rgb_uv, uv_w);
-
-      // update two rows of Y and one row of RGB
-      diff_y_sum += WebPSharpYUVUpdateY(target_y, best_rgb_y, best_y, 2 * w);
-      WebPSharpYUVUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
-
-      best_y += 2 * w;
-      best_uv += 3 * uv_w;
-      target_y += 2 * w;
-      target_uv += 3 * uv_w;
-    }
-    // test exit condition
-    if (iter > 0) {
-      if (diff_y_sum < diff_y_threshold) break;
-      if (diff_y_sum > prev_diff_y_sum) break;
-    }
-    prev_diff_y_sum = diff_y_sum;
-  }
-  // final reconstruction
-  ok = ConvertWRGBToYUV(best_y_base, best_uv_base, picture);
-
- End:
-  WebPSafeFree(best_y_base);
-  WebPSafeFree(best_uv_base);
-  WebPSafeFree(target_y_base);
-  WebPSafeFree(target_uv_base);
-  WebPSafeFree(best_rgb_y);
-  WebPSafeFree(best_rgb_uv);
-  WebPSafeFree(tmp_buffer);
   return ok;
 }
-#undef SAFE_ALLOC
 
 //------------------------------------------------------------------------------
 // "Fast" regular RGB->YUV
@@ -598,8 +219,8 @@
 // and constant are adjusted very tightly to fit 32b arithmetic.
 // In particular, they use the fact that the operands for 'v / a' are actually
 // derived as v = (a0.p0 + a1.p1 + a2.p2 + a3.p3) and a = a0 + a1 + a2 + a3
-// with ai in [0..255] and pi in [0..1<<kGammaFix). The constraint to avoid
-// overflow is: kGammaFix + kAlphaFix <= 31.
+// with ai in [0..255] and pi in [0..1<<GAMMA_FIX). The constraint to avoid
+// overflow is: GAMMA_FIX + kAlphaFix <= 31.
 static const uint32_t kInvAlpha[4 * 0xff + 1] = {
   0,  /* alpha = 0 */
   524288, 262144, 174762, 131072, 104857, 87381, 74898, 65536,
@@ -825,11 +446,20 @@
     dst[0] = SUM4(r_ptr + j, step);
     dst[1] = SUM4(g_ptr + j, step);
     dst[2] = SUM4(b_ptr + j, step);
+    // MemorySanitizer may raise false positives with data that passes through
+    // RGBA32PackedToPlanar_16b_SSE41() due to incorrect modeling of shuffles.
+    // See https://crbug.com/webp/573.
+#ifdef WEBP_MSAN
+    dst[3] = 0;
+#endif
   }
   if (width & 1) {
     dst[0] = SUM2(r_ptr + j);
     dst[1] = SUM2(g_ptr + j);
     dst[2] = SUM2(b_ptr + j);
+#ifdef WEBP_MSAN
+    dst[3] = 0;
+#endif
   }
 }
 
@@ -846,6 +476,8 @@
   }
 }
 
+extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
+
 static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
                               const uint8_t* g_ptr,
                               const uint8_t* b_ptr,
@@ -870,18 +502,18 @@
     use_iterative_conversion = 0;
   }
 
-  if (!WebPPictureAllocYUVA(picture, width, height)) {
+  if (!WebPPictureAllocYUVA(picture)) {
     return 0;
   }
   if (has_alpha) {
     assert(step == 4);
 #if defined(USE_GAMMA_COMPRESSION) && defined(USE_INVERSE_ALPHA_TABLE)
-    assert(kAlphaFix + kGammaFix <= 31);
+    assert(kAlphaFix + GAMMA_FIX <= 31);
 #endif
   }
 
   if (use_iterative_conversion) {
-    InitGammaTablesS();
+    SharpYuvInit(VP8GetCPUInfo);
     if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) {
       return 0;
     }
@@ -910,7 +542,9 @@
     WebPInitConvertARGBToYUV();
     InitGammaTables();
 
-    if (tmp_rgb == NULL) return 0;  // malloc error
+    if (tmp_rgb == NULL) {
+      return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    }
 
     // Downsample Y/U/V planes, two rows at a time
     for (y = 0; y < (height >> 1); ++y) {
@@ -1051,7 +685,7 @@
     return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
   }
   // Allocate a new argb buffer (discarding the previous one).
-  if (!WebPPictureAllocARGB(picture, picture->width, picture->height)) return 0;
+  if (!WebPPictureAllocARGB(picture)) return 0;
   picture->use_argb = 1;
 
   // Convert
@@ -1061,7 +695,7 @@
     const int height = picture->height;
     const int argb_stride = 4 * picture->argb_stride;
     uint8_t* dst = (uint8_t*)picture->argb;
-    const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
+    const uint8_t* cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
     WebPUpsampleLinePairFunc upsample =
         WebPGetLinePairConverter(ALPHA_OFFSET > 0);
 
@@ -1113,6 +747,8 @@
   const int width = picture->width;
   const int height = picture->height;
 
+  if (abs(rgb_stride) < (import_alpha ? 4 : 3) * width) return 0;
+
   if (!picture->use_argb) {
     const uint8_t* a_ptr = import_alpha ? rgb + 3 : NULL;
     return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
@@ -1170,24 +806,24 @@
 #if !defined(WEBP_REDUCE_CSP)
 
 int WebPPictureImportBGR(WebPPicture* picture,
-                         const uint8_t* rgb, int rgb_stride) {
-  return (picture != NULL && rgb != NULL)
-             ? Import(picture, rgb, rgb_stride, 3, 1, 0)
+                         const uint8_t* bgr, int bgr_stride) {
+  return (picture != NULL && bgr != NULL)
+             ? Import(picture, bgr, bgr_stride, 3, 1, 0)
              : 0;
 }
 
 int WebPPictureImportBGRA(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return (picture != NULL && rgba != NULL)
-             ? Import(picture, rgba, rgba_stride, 4, 1, 1)
+                          const uint8_t* bgra, int bgra_stride) {
+  return (picture != NULL && bgra != NULL)
+             ? Import(picture, bgra, bgra_stride, 4, 1, 1)
              : 0;
 }
 
 
 int WebPPictureImportBGRX(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return (picture != NULL && rgba != NULL)
-             ? Import(picture, rgba, rgba_stride, 4, 1, 0)
+                          const uint8_t* bgrx, int bgrx_stride) {
+  return (picture != NULL && bgrx != NULL)
+             ? Import(picture, bgrx, bgrx_stride, 4, 1, 0)
              : 0;
 }
 
@@ -1208,9 +844,9 @@
 }
 
 int WebPPictureImportRGBX(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return (picture != NULL && rgba != NULL)
-             ? Import(picture, rgba, rgba_stride, 4, 0, 0)
+                          const uint8_t* rgbx, int rgbx_stride) {
+  return (picture != NULL && rgbx != NULL)
+             ? Import(picture, rgbx, rgbx_stride, 4, 0, 0)
              : 0;
 }
 
diff --git a/third_party/libwebp/src/enc/picture_enc.c b/third_party/libwebp/src/enc/picture_enc.c
index 81ce345..7a939e7 100644
--- a/third_party/libwebp/src/enc/picture_enc.c
+++ b/third_party/libwebp/src/enc/picture_enc.c
@@ -51,6 +51,22 @@
 
 //------------------------------------------------------------------------------
 
+int WebPValidatePicture(const WebPPicture* const picture) {
+  if (picture == NULL) return 0;
+  if (picture->width <= 0 || picture->height <= 0) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+  }
+  if (picture->width <= 0 || picture->width / 4 > INT_MAX / 4 ||
+      picture->height <= 0 || picture->height / 4 > INT_MAX / 4) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+  }
+  if (picture->colorspace != WEBP_YUV420 &&
+      picture->colorspace != WEBP_YUV420A) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
+  }
+  return 1;
+}
+
 static void WebPPictureResetBufferARGB(WebPPicture* const picture) {
   picture->memory_argb_ = NULL;
   picture->argb = NULL;
@@ -69,18 +85,17 @@
   WebPPictureResetBufferYUVA(picture);
 }
 
-int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height) {
+int WebPPictureAllocARGB(WebPPicture* const picture) {
   void* memory;
+  const int width = picture->width;
+  const int height = picture->height;
   const uint64_t argb_size = (uint64_t)width * height;
 
-  assert(picture != NULL);
+  if (!WebPValidatePicture(picture)) return 0;
 
   WebPSafeFree(picture->memory_argb_);
   WebPPictureResetBufferARGB(picture);
 
-  if (width <= 0 || height <= 0) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
-  }
   // allocate a new buffer.
   memory = WebPSafeMalloc(argb_size + WEBP_ALIGN_CST, sizeof(*picture->argb));
   if (memory == NULL) {
@@ -92,10 +107,10 @@
   return 1;
 }
 
-int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height) {
-  const WebPEncCSP uv_csp =
-      (WebPEncCSP)((int)picture->colorspace & WEBP_CSP_UV_MASK);
+int WebPPictureAllocYUVA(WebPPicture* const picture) {
   const int has_alpha = (int)picture->colorspace & WEBP_CSP_ALPHA_BIT;
+  const int width = picture->width;
+  const int height = picture->height;
   const int y_stride = width;
   const int uv_width = (int)(((int64_t)width + 1) >> 1);
   const int uv_height = (int)(((int64_t)height + 1) >> 1);
@@ -104,15 +119,11 @@
   uint64_t y_size, uv_size, a_size, total_size;
   uint8_t* mem;
 
-  assert(picture != NULL);
+  if (!WebPValidatePicture(picture)) return 0;
 
   WebPSafeFree(picture->memory_);
   WebPPictureResetBufferYUVA(picture);
 
-  if (uv_csp != WEBP_YUV420) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
-  }
-
   // alpha
   a_width = has_alpha ? width : 0;
   a_stride = a_width;
@@ -158,15 +169,12 @@
 
 int WebPPictureAlloc(WebPPicture* picture) {
   if (picture != NULL) {
-    const int width = picture->width;
-    const int height = picture->height;
-
     WebPPictureFree(picture);   // erase previous buffer
 
     if (!picture->use_argb) {
-      return WebPPictureAllocYUVA(picture, width, height);
+      return WebPPictureAllocYUVA(picture);
     } else {
-      return WebPPictureAllocARGB(picture, width, height);
+      return WebPPictureAllocARGB(picture);
     }
   }
   return 1;
diff --git a/third_party/libwebp/src/enc/picture_rescale_enc.c b/third_party/libwebp/src/enc/picture_rescale_enc.c
index 58a6ae7..ea90d82 100644
--- a/third_party/libwebp/src/enc/picture_rescale_enc.c
+++ b/third_party/libwebp/src/enc/picture_rescale_enc.c
@@ -13,14 +13,15 @@
 
 #include "src/webp/encode.h"
 
-#if !defined(WEBP_REDUCE_SIZE)
-
 #include <assert.h>
 #include <stdlib.h>
 
 #include "src/enc/vp8i_enc.h"
+
+#if !defined(WEBP_REDUCE_SIZE)
 #include "src/utils/rescaler_utils.h"
 #include "src/utils/utils.h"
+#endif  // !defined(WEBP_REDUCE_SIZE)
 
 #define HALVE(x) (((x) + 1) >> 1)
 
@@ -56,6 +57,7 @@
   return 1;
 }
 
+#if !defined(WEBP_REDUCE_SIZE)
 int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
   if (src == NULL || dst == NULL) return 0;
   if (src == dst) return 1;
@@ -81,6 +83,7 @@
   }
   return 1;
 }
+#endif  // !defined(WEBP_REDUCE_SIZE)
 
 int WebPPictureIsView(const WebPPicture* picture) {
   if (picture == NULL) return 0;
@@ -120,6 +123,7 @@
   return 1;
 }
 
+#if !defined(WEBP_REDUCE_SIZE)
 //------------------------------------------------------------------------------
 // Picture cropping
 
@@ -133,7 +137,9 @@
   PictureGrabSpecs(pic, &tmp);
   tmp.width = width;
   tmp.height = height;
-  if (!WebPPictureAlloc(&tmp)) return 0;
+  if (!WebPPictureAlloc(&tmp)) {
+    return WebPEncodingSetError(pic, tmp.error_code);
+  }
 
   if (!pic->use_argb) {
     const int y_offset = top * pic->y_stride + left;
@@ -164,22 +170,25 @@
 //------------------------------------------------------------------------------
 // Simple picture rescaler
 
-static void RescalePlane(const uint8_t* src,
-                         int src_width, int src_height, int src_stride,
-                         uint8_t* dst,
-                         int dst_width, int dst_height, int dst_stride,
-                         rescaler_t* const work,
-                         int num_channels) {
+static int RescalePlane(const uint8_t* src,
+                        int src_width, int src_height, int src_stride,
+                        uint8_t* dst,
+                        int dst_width, int dst_height, int dst_stride,
+                        rescaler_t* const work,
+                        int num_channels) {
   WebPRescaler rescaler;
   int y = 0;
-  WebPRescalerInit(&rescaler, src_width, src_height,
-                   dst, dst_width, dst_height, dst_stride,
-                   num_channels, work);
+  if (!WebPRescalerInit(&rescaler, src_width, src_height,
+                        dst, dst_width, dst_height, dst_stride,
+                        num_channels, work)) {
+    return 0;
+  }
   while (y < src_height) {
     y += WebPRescalerImport(&rescaler, src_height - y,
                             src + y * src_stride, src_stride);
     WebPRescalerExport(&rescaler);
   }
+  return 1;
 }
 
 static void AlphaMultiplyARGB(WebPPicture* const pic, int inverse) {
@@ -195,73 +204,76 @@
   }
 }
 
-int WebPPictureRescale(WebPPicture* pic, int width, int height) {
+int WebPPictureRescale(WebPPicture* picture, int width, int height) {
   WebPPicture tmp;
   int prev_width, prev_height;
   rescaler_t* work;
 
-  if (pic == NULL) return 0;
-  prev_width = pic->width;
-  prev_height = pic->height;
+  if (picture == NULL) return 0;
+  prev_width = picture->width;
+  prev_height = picture->height;
   if (!WebPRescalerGetScaledDimensions(
           prev_width, prev_height, &width, &height)) {
-    return 0;
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
   }
 
-  PictureGrabSpecs(pic, &tmp);
+  PictureGrabSpecs(picture, &tmp);
   tmp.width = width;
   tmp.height = height;
-  if (!WebPPictureAlloc(&tmp)) return 0;
+  if (!WebPPictureAlloc(&tmp)) {
+    return WebPEncodingSetError(picture, tmp.error_code);
+  }
 
-  if (!pic->use_argb) {
+  if (!picture->use_argb) {
     work = (rescaler_t*)WebPSafeMalloc(2ULL * width, sizeof(*work));
     if (work == NULL) {
       WebPPictureFree(&tmp);
-      return 0;
+      return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     }
     // If present, we need to rescale alpha first (for AlphaMultiplyY).
-    if (pic->a != NULL) {
+    if (picture->a != NULL) {
       WebPInitAlphaProcessing();
-      RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
-                   tmp.a, width, height, tmp.a_stride, work, 1);
+      if (!RescalePlane(picture->a, prev_width, prev_height, picture->a_stride,
+                        tmp.a, width, height, tmp.a_stride, work, 1)) {
+        return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+      }
     }
 
     // We take transparency into account on the luma plane only. That's not
     // totally exact blending, but still is a good approximation.
-    AlphaMultiplyY(pic, 0);
-    RescalePlane(pic->y, prev_width, prev_height, pic->y_stride,
-                 tmp.y, width, height, tmp.y_stride, work, 1);
+    AlphaMultiplyY(picture, 0);
+    if (!RescalePlane(picture->y, prev_width, prev_height, picture->y_stride,
+                      tmp.y, width, height, tmp.y_stride, work, 1) ||
+        !RescalePlane(picture->u, HALVE(prev_width), HALVE(prev_height),
+                      picture->uv_stride, tmp.u, HALVE(width), HALVE(height),
+                      tmp.uv_stride, work, 1) ||
+        !RescalePlane(picture->v, HALVE(prev_width), HALVE(prev_height),
+                      picture->uv_stride, tmp.v, HALVE(width), HALVE(height),
+                      tmp.uv_stride, work, 1)) {
+      return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+    }
     AlphaMultiplyY(&tmp, 1);
-
-    RescalePlane(pic->u,
-                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
-                 tmp.u,
-                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
-    RescalePlane(pic->v,
-                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
-                 tmp.v,
-                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
   } else {
     work = (rescaler_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
     if (work == NULL) {
       WebPPictureFree(&tmp);
-      return 0;
+      return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     }
     // In order to correctly interpolate colors, we need to apply the alpha
     // weighting first (black-matting), scale the RGB values, and remove
     // the premultiplication afterward (while preserving the alpha channel).
     WebPInitAlphaProcessing();
-    AlphaMultiplyARGB(pic, 0);
-    RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height,
-                 pic->argb_stride * 4,
-                 (uint8_t*)tmp.argb, width, height,
-                 tmp.argb_stride * 4,
-                 work, 4);
+    AlphaMultiplyARGB(picture, 0);
+    if (!RescalePlane((const uint8_t*)picture->argb, prev_width, prev_height,
+                      picture->argb_stride * 4, (uint8_t*)tmp.argb, width,
+                      height, tmp.argb_stride * 4, work, 4)) {
+      return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+    }
     AlphaMultiplyARGB(&tmp, 1);
   }
-  WebPPictureFree(pic);
+  WebPPictureFree(picture);
   WebPSafeFree(work);
-  *pic = tmp;
+  *picture = tmp;
   return 1;
 }
 
@@ -273,23 +285,6 @@
   return 0;
 }
 
-int WebPPictureIsView(const WebPPicture* picture) {
-  (void)picture;
-  return 0;
-}
-
-int WebPPictureView(const WebPPicture* src,
-                    int left, int top, int width, int height,
-                    WebPPicture* dst) {
-  (void)src;
-  (void)left;
-  (void)top;
-  (void)width;
-  (void)height;
-  (void)dst;
-  return 0;
-}
-
 int WebPPictureCrop(WebPPicture* pic,
                     int left, int top, int width, int height) {
   (void)pic;
diff --git a/third_party/libwebp/src/enc/picture_tools_enc.c b/third_party/libwebp/src/enc/picture_tools_enc.c
index 01dc6ca..894cb5f 100644
--- a/third_party/libwebp/src/enc/picture_tools_enc.c
+++ b/third_party/libwebp/src/enc/picture_tools_enc.c
@@ -21,10 +21,6 @@
 #include "src/enc/vp8i_enc.h"
 #include "src/dsp/yuv.h"
 
-static WEBP_INLINE uint32_t MakeARGB32(int r, int g, int b) {
-  return (0xff000000u | (r << 16) | (g << 8) | b);
-}
-
 //------------------------------------------------------------------------------
 // Helper: clean up fully transparent area to help compressibility.
 
@@ -92,6 +88,19 @@
   return (count == 0);
 }
 
+void WebPReplaceTransparentPixels(WebPPicture* const pic, uint32_t color) {
+  if (pic != NULL && pic->use_argb) {
+    int y = pic->height;
+    uint32_t* argb = pic->argb;
+    color &= 0xffffffu;   // force alpha=0
+    WebPInitAlphaProcessing();
+    while (y-- > 0) {
+      WebPAlphaReplace(argb, pic->width, color);
+      argb += pic->argb_stride;
+    }
+  }
+}
+
 void WebPCleanupTransparentArea(WebPPicture* pic) {
   int x, y, w, h;
   if (pic == NULL) return;
@@ -174,24 +183,6 @@
 #undef SIZE
 #undef SIZE2
 
-void WebPCleanupTransparentAreaLossless(WebPPicture* const pic) {
-  int x, y, w, h;
-  uint32_t* argb;
-  assert(pic != NULL && pic->use_argb);
-  w = pic->width;
-  h = pic->height;
-  argb = pic->argb;
-
-  for (y = 0; y < h; ++y) {
-    for (x = 0; x < w; ++x) {
-      if ((argb[x] & 0xff000000) == 0) {
-        argb[x] = 0x00000000;
-      }
-    }
-    argb += pic->argb_stride;
-  }
-}
-
 //------------------------------------------------------------------------------
 // Blend color and remove transparency info
 
@@ -200,58 +191,68 @@
 #define BLEND_10BIT(V0, V1, ALPHA) \
     ((((V0) * (1020 - (ALPHA)) + (V1) * (ALPHA)) * 0x101 + 1024) >> 18)
 
-void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) {
+static WEBP_INLINE uint32_t MakeARGB32(int r, int g, int b) {
+  return (0xff000000u | (r << 16) | (g << 8) | b);
+}
+
+void WebPBlendAlpha(WebPPicture* picture, uint32_t background_rgb) {
   const int red = (background_rgb >> 16) & 0xff;
   const int green = (background_rgb >> 8) & 0xff;
   const int blue = (background_rgb >> 0) & 0xff;
   int x, y;
-  if (pic == NULL) return;
-  if (!pic->use_argb) {
-    const int uv_width = (pic->width >> 1);  // omit last pixel during u/v loop
+  if (picture == NULL) return;
+  if (!picture->use_argb) {
+    // omit last pixel during u/v loop
+    const int uv_width = (picture->width >> 1);
     const int Y0 = VP8RGBToY(red, green, blue, YUV_HALF);
     // VP8RGBToU/V expects the u/v values summed over four pixels
     const int U0 = VP8RGBToU(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF);
     const int V0 = VP8RGBToV(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF);
-    const int has_alpha = pic->colorspace & WEBP_CSP_ALPHA_BIT;
-    if (!has_alpha || pic->a == NULL) return;    // nothing to do
-    for (y = 0; y < pic->height; ++y) {
+    const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT;
+    uint8_t* y_ptr = picture->y;
+    uint8_t* u_ptr = picture->u;
+    uint8_t* v_ptr = picture->v;
+    uint8_t* a_ptr = picture->a;
+    if (!has_alpha || a_ptr == NULL) return;    // nothing to do
+    for (y = 0; y < picture->height; ++y) {
       // Luma blending
-      uint8_t* const y_ptr = pic->y + y * pic->y_stride;
-      uint8_t* const a_ptr = pic->a + y * pic->a_stride;
-      for (x = 0; x < pic->width; ++x) {
-        const int alpha = a_ptr[x];
+      for (x = 0; x < picture->width; ++x) {
+        const uint8_t alpha = a_ptr[x];
         if (alpha < 0xff) {
-          y_ptr[x] = BLEND(Y0, y_ptr[x], a_ptr[x]);
+          y_ptr[x] = BLEND(Y0, y_ptr[x], alpha);
         }
       }
       // Chroma blending every even line
       if ((y & 1) == 0) {
-        uint8_t* const u = pic->u + (y >> 1) * pic->uv_stride;
-        uint8_t* const v = pic->v + (y >> 1) * pic->uv_stride;
         uint8_t* const a_ptr2 =
-            (y + 1 == pic->height) ? a_ptr : a_ptr + pic->a_stride;
+            (y + 1 == picture->height) ? a_ptr : a_ptr + picture->a_stride;
         for (x = 0; x < uv_width; ++x) {
           // Average four alpha values into a single blending weight.
           // TODO(skal): might lead to visible contouring. Can we do better?
-          const int alpha =
+          const uint32_t alpha =
               a_ptr[2 * x + 0] + a_ptr[2 * x + 1] +
               a_ptr2[2 * x + 0] + a_ptr2[2 * x + 1];
-          u[x] = BLEND_10BIT(U0, u[x], alpha);
-          v[x] = BLEND_10BIT(V0, v[x], alpha);
+          u_ptr[x] = BLEND_10BIT(U0, u_ptr[x], alpha);
+          v_ptr[x] = BLEND_10BIT(V0, v_ptr[x], alpha);
         }
-        if (pic->width & 1) {   // rightmost pixel
-          const int alpha = 2 * (a_ptr[2 * x + 0] + a_ptr2[2 * x + 0]);
-          u[x] = BLEND_10BIT(U0, u[x], alpha);
-          v[x] = BLEND_10BIT(V0, v[x], alpha);
+        if (picture->width & 1) {  // rightmost pixel
+          const uint32_t alpha = 2 * (a_ptr[2 * x + 0] + a_ptr2[2 * x + 0]);
+          u_ptr[x] = BLEND_10BIT(U0, u_ptr[x], alpha);
+          v_ptr[x] = BLEND_10BIT(V0, v_ptr[x], alpha);
         }
+      } else {
+        u_ptr += picture->uv_stride;
+        v_ptr += picture->uv_stride;
       }
-      memset(a_ptr, 0xff, pic->width);
+      memset(a_ptr, 0xff, picture->width);  // reset alpha value to opaque
+      a_ptr += picture->a_stride;
+      y_ptr += picture->y_stride;
     }
   } else {
-    uint32_t* argb = pic->argb;
+    uint32_t* argb = picture->argb;
     const uint32_t background = MakeARGB32(red, green, blue);
-    for (y = 0; y < pic->height; ++y) {
-      for (x = 0; x < pic->width; ++x) {
+    for (y = 0; y < picture->height; ++y) {
+      for (x = 0; x < picture->width; ++x) {
         const int alpha = (argb[x] >> 24) & 0xff;
         if (alpha != 0xff) {
           if (alpha > 0) {
@@ -267,7 +268,7 @@
           }
         }
       }
-      argb += pic->argb_stride;
+      argb += picture->argb_stride;
     }
   }
 }
diff --git a/third_party/libwebp/src/enc/predictor_enc.c b/third_party/libwebp/src/enc/predictor_enc.c
index df9f666..04a2a98 100644
--- a/third_party/libwebp/src/enc/predictor_enc.c
+++ b/third_party/libwebp/src/enc/predictor_enc.c
@@ -23,6 +23,7 @@
 
 #include "src/dsp/lossless.h"
 #include "src/dsp/lossless_common.h"
+#include "src/enc/vp8i_enc.h"
 #include "src/enc/vp8li_enc.h"
 
 #define MAX_DIFF_COST (1e30f)
@@ -38,10 +39,10 @@
 // Methods to calculate Entropy (Shannon).
 
 static float PredictionCostSpatial(const int counts[256], int weight_0,
-                                   double exp_val) {
+                                   float exp_val) {
   const int significant_symbols = 256 >> 4;
-  const double exp_decay_factor = 0.6;
-  double bits = weight_0 * counts[0];
+  const float exp_decay_factor = 0.6f;
+  float bits = (float)weight_0 * counts[0];
   int i;
   for (i = 1; i < significant_symbols; ++i) {
     bits += exp_val * (counts[i] + counts[256 - i]);
@@ -53,9 +54,9 @@
 static float PredictionCostSpatialHistogram(const int accumulated[4][256],
                                             const int tile[4][256]) {
   int i;
-  double retval = 0;
+  float retval = 0.f;
   for (i = 0; i < 4; ++i) {
-    const double kExpValue = 0.94;
+    const float kExpValue = 0.94f;
     retval += PredictionCostSpatial(tile[i], 1, kExpValue);
     retval += VP8LCombinedShannonEntropy(tile[i], accumulated[i]);
   }
@@ -184,12 +185,15 @@
   }
 }
 
+static WEBP_INLINE uint8_t NearLosslessDiff(uint8_t a, uint8_t b) {
+  return (uint8_t)((((int)(a) - (int)(b))) & 0xff);
+}
+
 // Quantize every component of the difference between the actual pixel value and
 // its prediction to a multiple of a quantization (a power of 2, not larger than
 // max_quantization which is a power of 2, smaller than max_diff). Take care if
 // value and predict have undergone subtract green, which means that red and
 // blue are represented as offsets from green.
-#define NEAR_LOSSLESS_DIFF(a, b) (uint8_t)((((int)(a) - (int)(b))) & 0xff)
 static uint32_t NearLossless(uint32_t value, uint32_t predict,
                              int max_quantization, int max_diff,
                              int used_subtract_green) {
@@ -206,7 +210,7 @@
   }
   if ((value >> 24) == 0 || (value >> 24) == 0xff) {
     // Preserve transparency of fully transparent or fully opaque pixels.
-    a = NEAR_LOSSLESS_DIFF(value >> 24, predict >> 24);
+    a = NearLosslessDiff((value >> 24) & 0xff, (predict >> 24) & 0xff);
   } else {
     a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization);
   }
@@ -219,16 +223,15 @@
     // The amount by which green has been adjusted during quantization. It is
     // subtracted from red and blue for compensation, to avoid accumulating two
     // quantization errors in them.
-    green_diff = NEAR_LOSSLESS_DIFF(new_green, value >> 8);
+    green_diff = NearLosslessDiff(new_green, (value >> 8) & 0xff);
   }
-  r = NearLosslessComponent(NEAR_LOSSLESS_DIFF(value >> 16, green_diff),
+  r = NearLosslessComponent(NearLosslessDiff((value >> 16) & 0xff, green_diff),
                             (predict >> 16) & 0xff, 0xff - new_green,
                             quantization);
-  b = NearLosslessComponent(NEAR_LOSSLESS_DIFF(value, green_diff),
+  b = NearLosslessComponent(NearLosslessDiff(value & 0xff, green_diff),
                             predict & 0xff, 0xff - new_green, quantization);
   return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
 }
-#undef NEAR_LOSSLESS_DIFF
 #endif  // (WEBP_NEAR_LOSSLESS == 1)
 
 // Stores the difference between the pixel and its prediction in "out".
@@ -254,7 +257,7 @@
       } else if (x == 0) {
         predict = upper_row[x];  // Top.
       } else {
-        predict = pred_func(current_row[x - 1], upper_row + x);
+        predict = pred_func(&current_row[x - 1], upper_row + x);
       }
 #if (WEBP_NEAR_LOSSLESS == 1)
       if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
@@ -477,12 +480,15 @@
 // with respect to predictions. If near_lossless_quality < 100, applies
 // near lossless processing, shaving off more bits of residuals for lower
 // qualities.
-void VP8LResidualImage(int width, int height, int bits, int low_effort,
-                       uint32_t* const argb, uint32_t* const argb_scratch,
-                       uint32_t* const image, int near_lossless_quality,
-                       int exact, int used_subtract_green) {
+int VP8LResidualImage(int width, int height, int bits, int low_effort,
+                      uint32_t* const argb, uint32_t* const argb_scratch,
+                      uint32_t* const image, int near_lossless_quality,
+                      int exact, int used_subtract_green,
+                      const WebPPicture* const pic, int percent_range,
+                      int* const percent) {
   const int tiles_per_row = VP8LSubSampleSize(width, bits);
   const int tiles_per_col = VP8LSubSampleSize(height, bits);
+  int percent_start = *percent;
   int tile_y;
   int histo[4][256];
   const int max_quantization = 1 << VP8LNearLosslessBits(near_lossless_quality);
@@ -496,17 +502,24 @@
     for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
       int tile_x;
       for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
-        const int pred = GetBestPredictorForTile(width, height, tile_x, tile_y,
-            bits, histo, argb_scratch, argb, max_quantization, exact,
-            used_subtract_green, image);
+        const int pred = GetBestPredictorForTile(
+            width, height, tile_x, tile_y, bits, histo, argb_scratch, argb,
+            max_quantization, exact, used_subtract_green, image);
         image[tile_y * tiles_per_row + tile_x] = ARGB_BLACK | (pred << 8);
       }
+
+      if (!WebPReportProgress(
+              pic, percent_start + percent_range * tile_y / tiles_per_col,
+              percent)) {
+        return 0;
+      }
     }
   }
 
   CopyImageWithPrediction(width, height, bits, image, argb_scratch, argb,
                           low_effort, max_quantization, exact,
                           used_subtract_green);
+  return WebPReportProgress(pic, percent_start + percent_range, percent);
 }
 
 //------------------------------------------------------------------------------
@@ -537,7 +550,7 @@
                                       const int counts[256]) {
   // Favor low entropy, locally and globally.
   // Favor small absolute values for PredictionCostSpatial
-  static const double kExpValue = 2.4;
+  static const float kExpValue = 2.4f;
   return VP8LCombinedShannonEntropy(counts, accumulated) +
          PredictionCostSpatial(counts, 3, kExpValue);
 }
@@ -592,7 +605,7 @@
       }
     }
   }
-  best_tx->green_to_red_ = green_to_red_best;
+  best_tx->green_to_red_ = (green_to_red_best & 0xff);
 }
 
 static float GetPredictionCostCrossColorBlue(
@@ -671,8 +684,8 @@
       break;  // out of iter-loop.
     }
   }
-  best_tx->green_to_blue_ = green_to_blue_best;
-  best_tx->red_to_blue_ = red_to_blue_best;
+  best_tx->green_to_blue_ = green_to_blue_best & 0xff;
+  best_tx->red_to_blue_ = red_to_blue_best & 0xff;
 }
 #undef kGreenRedToBlueMaxIters
 #undef kGreenRedToBlueNumAxis
@@ -719,11 +732,14 @@
   }
 }
 
-void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
-                             uint32_t* const argb, uint32_t* image) {
+int VP8LColorSpaceTransform(int width, int height, int bits, int quality,
+                            uint32_t* const argb, uint32_t* image,
+                            const WebPPicture* const pic, int percent_range,
+                            int* const percent) {
   const int max_tile_size = 1 << bits;
   const int tile_xsize = VP8LSubSampleSize(width, bits);
   const int tile_ysize = VP8LSubSampleSize(height, bits);
+  int percent_start = *percent;
   int accumulated_red_histo[256] = { 0 };
   int accumulated_blue_histo[256] = { 0 };
   int tile_x, tile_y;
@@ -773,5 +789,11 @@
         }
       }
     }
+    if (!WebPReportProgress(
+            pic, percent_start + percent_range * tile_y / tile_ysize,
+            percent)) {
+      return 0;
+    }
   }
+  return 1;
 }
diff --git a/third_party/libwebp/src/enc/quant_enc.c b/third_party/libwebp/src/enc/quant_enc.c
index 0ba889b..ad731a8 100644
--- a/third_party/libwebp/src/enc/quant_enc.c
+++ b/third_party/libwebp/src/enc/quant_enc.c
@@ -23,6 +23,7 @@
 
 #include <stdlib.h>  // for abs()
 
+#include "src/dsp/quant.h"
 #include "src/enc/vp8i_enc.h"
 #include "src/enc/cost_enc.h"
 
@@ -40,7 +41,7 @@
 
 // number of non-zero coeffs below which we consider the block very flat
 // (and apply a penalty to complex predictions)
-#define FLATNESS_LIMIT_I16 10      // I16 mode
+#define FLATNESS_LIMIT_I16 0       // I16 mode (special case)
 #define FLATNESS_LIMIT_I4  3       // I4 mode
 #define FLATNESS_LIMIT_UV  2       // UV mode
 #define FLATNESS_PENALTY   140     // roughly ~1bit per block
@@ -540,7 +541,8 @@
   rd->score = MAX_COST;
 }
 
-static void CopyScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
+static void CopyScore(VP8ModeScore* WEBP_RESTRICT const dst,
+                      const VP8ModeScore* WEBP_RESTRICT const src) {
   dst->D  = src->D;
   dst->SD = src->SD;
   dst->R  = src->R;
@@ -549,7 +551,8 @@
   dst->score = src->score;
 }
 
-static void AddScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
+static void AddScore(VP8ModeScore* WEBP_RESTRICT const dst,
+                     const VP8ModeScore* WEBP_RESTRICT const src) {
   dst->D  += src->D;
   dst->SD += src->SD;
   dst->R  += src->R;
@@ -592,15 +595,18 @@
   return rate * lambda + RD_DISTO_MULT * distortion;
 }
 
-static int TrellisQuantizeBlock(const VP8Encoder* const enc,
+// Coefficient type.
+enum { TYPE_I16_AC = 0, TYPE_I16_DC = 1, TYPE_CHROMA_A = 2, TYPE_I4_AC = 3 };
+
+static int TrellisQuantizeBlock(const VP8Encoder* WEBP_RESTRICT const enc,
                                 int16_t in[16], int16_t out[16],
                                 int ctx0, int coeff_type,
-                                const VP8Matrix* const mtx,
+                                const VP8Matrix* WEBP_RESTRICT const mtx,
                                 int lambda) {
   const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
   CostArrayPtr const costs =
       (CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
-  const int first = (coeff_type == 0) ? 1 : 0;
+  const int first = (coeff_type == TYPE_I16_AC) ? 1 : 0;
   Node nodes[16][NUM_NODES];
   ScoreState score_states[2][NUM_NODES];
   ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
@@ -664,16 +670,17 @@
     // test all alternate level values around level0.
     for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
       Node* const cur = &NODE(n, m);
-      int level = level0 + m;
+      const int level = level0 + m;
       const int ctx = (level > 2) ? 2 : level;
       const int band = VP8EncBands[n + 1];
       score_t base_score;
-      score_t best_cur_score = MAX_COST;
-      int best_prev = 0;   // default, in case
+      score_t best_cur_score;
+      int best_prev;
+      score_t cost, score;
 
-      ss_cur[m].score = MAX_COST;
       ss_cur[m].costs = costs[n + 1][ctx];
       if (level < 0 || level > thresh_level) {
+        ss_cur[m].score = MAX_COST;
         // Node is dead.
         continue;
       }
@@ -689,18 +696,24 @@
       }
 
       // Inspect all possible non-dead predecessors. Retain only the best one.
-      for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
+      // The base_score is added to all scores so it is only added for the final
+      // value after the loop.
+      cost = VP8LevelCost(ss_prev[-MIN_DELTA].costs, level);
+      best_cur_score =
+          ss_prev[-MIN_DELTA].score + RDScoreTrellis(lambda, cost, 0);
+      best_prev = -MIN_DELTA;
+      for (p = -MIN_DELTA + 1; p <= MAX_DELTA; ++p) {
         // Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
         // eliminated since their score can't be better than the current best.
-        const score_t cost = VP8LevelCost(ss_prev[p].costs, level);
+        cost = VP8LevelCost(ss_prev[p].costs, level);
         // Examine node assuming it's a non-terminal one.
-        const score_t score =
-            base_score + ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
+        score = ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
         if (score < best_cur_score) {
           best_cur_score = score;
           best_prev = p;
         }
       }
+      best_cur_score += base_score;
       // Store best finding in current node.
       cur->sign = sign;
       cur->level = level;
@@ -708,11 +721,11 @@
       ss_cur[m].score = best_cur_score;
 
       // Now, record best terminal node (and thus best entry in the graph).
-      if (level != 0) {
+      if (level != 0 && best_cur_score < best_score) {
         const score_t last_pos_cost =
             (n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
         const score_t last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
-        const score_t score = best_cur_score + last_pos_score;
+        score = best_cur_score + last_pos_score;
         if (score < best_score) {
           best_score = score;
           best_path[0] = n;                     // best eob position
@@ -724,10 +737,16 @@
   }
 
   // Fresh start
-  memset(in + first, 0, (16 - first) * sizeof(*in));
-  memset(out + first, 0, (16 - first) * sizeof(*out));
+  // Beware! We must preserve in[0]/out[0] value for TYPE_I16_AC case.
+  if (coeff_type == TYPE_I16_AC) {
+    memset(in + 1, 0, 15 * sizeof(*in));
+    memset(out + 1, 0, 15 * sizeof(*out));
+  } else {
+    memset(in, 0, 16 * sizeof(*in));
+    memset(out, 0, 16 * sizeof(*out));
+  }
   if (best_path[0] == -1) {
-    return 0;   // skip!
+    return 0;  // skip!
   }
 
   {
@@ -758,9 +777,9 @@
 // all at once. Output is the reconstructed block in *yuv_out, and the
 // quantized levels in *levels.
 
-static int ReconstructIntra16(VP8EncIterator* const it,
-                              VP8ModeScore* const rd,
-                              uint8_t* const yuv_out,
+static int ReconstructIntra16(VP8EncIterator* WEBP_RESTRICT const it,
+                              VP8ModeScore* WEBP_RESTRICT const rd,
+                              uint8_t* WEBP_RESTRICT const yuv_out,
                               int mode) {
   const VP8Encoder* const enc = it->enc_;
   const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
@@ -782,9 +801,9 @@
     for (y = 0, n = 0; y < 4; ++y) {
       for (x = 0; x < 4; ++x, ++n) {
         const int ctx = it->top_nz_[x] + it->left_nz_[y];
-        const int non_zero =
-            TrellisQuantizeBlock(enc, tmp[n], rd->y_ac_levels[n], ctx, 0,
-                                 &dqm->y1_, dqm->lambda_trellis_i16_);
+        const int non_zero = TrellisQuantizeBlock(
+            enc, tmp[n], rd->y_ac_levels[n], ctx, TYPE_I16_AC, &dqm->y1_,
+            dqm->lambda_trellis_i16_);
         it->top_nz_[x] = it->left_nz_[y] = non_zero;
         rd->y_ac_levels[n][0] = 0;
         nz |= non_zero << n;
@@ -810,10 +829,10 @@
   return nz;
 }
 
-static int ReconstructIntra4(VP8EncIterator* const it,
+static int ReconstructIntra4(VP8EncIterator* WEBP_RESTRICT const it,
                              int16_t levels[16],
-                             const uint8_t* const src,
-                             uint8_t* const yuv_out,
+                             const uint8_t* WEBP_RESTRICT const src,
+                             uint8_t* WEBP_RESTRICT const yuv_out,
                              int mode) {
   const VP8Encoder* const enc = it->enc_;
   const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
@@ -825,7 +844,7 @@
   if (DO_TRELLIS_I4 && it->do_trellis_) {
     const int x = it->i4_ & 3, y = it->i4_ >> 2;
     const int ctx = it->top_nz_[x] + it->left_nz_[y];
-    nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, 3, &dqm->y1_,
+    nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, TYPE_I4_AC, &dqm->y1_,
                               dqm->lambda_trellis_i4_);
   } else {
     nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
@@ -846,7 +865,8 @@
 
 // Quantize as usual, but also compute and return the quantization error.
 // Error is already divided by DSHIFT.
-static int QuantizeSingle(int16_t* const v, const VP8Matrix* const mtx) {
+static int QuantizeSingle(int16_t* WEBP_RESTRICT const v,
+                          const VP8Matrix* WEBP_RESTRICT const mtx) {
   int V = *v;
   const int sign = (V < 0);
   if (sign) V = -V;
@@ -860,9 +880,10 @@
   return (sign ? -V : V) >> DSCALE;
 }
 
-static void CorrectDCValues(const VP8EncIterator* const it,
-                            const VP8Matrix* const mtx,
-                            int16_t tmp[][16], VP8ModeScore* const rd) {
+static void CorrectDCValues(const VP8EncIterator* WEBP_RESTRICT const it,
+                            const VP8Matrix* WEBP_RESTRICT const mtx,
+                            int16_t tmp[][16],
+                            VP8ModeScore* WEBP_RESTRICT const rd) {
   //         | top[0] | top[1]
   // --------+--------+---------
   // left[0] | tmp[0]   tmp[1]  <->   err0 err1
@@ -893,8 +914,8 @@
   }
 }
 
-static void StoreDiffusionErrors(VP8EncIterator* const it,
-                                 const VP8ModeScore* const rd) {
+static void StoreDiffusionErrors(VP8EncIterator* WEBP_RESTRICT const it,
+                                 const VP8ModeScore* WEBP_RESTRICT const rd) {
   int ch;
   for (ch = 0; ch <= 1; ++ch) {
     int8_t* const top = it->top_derr_[it->x_][ch];
@@ -913,8 +934,9 @@
 
 //------------------------------------------------------------------------------
 
-static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
-                         uint8_t* const yuv_out, int mode) {
+static int ReconstructUV(VP8EncIterator* WEBP_RESTRICT const it,
+                         VP8ModeScore* WEBP_RESTRICT const rd,
+                         uint8_t* WEBP_RESTRICT const yuv_out, int mode) {
   const VP8Encoder* const enc = it->enc_;
   const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode];
   const uint8_t* const src = it->yuv_in_ + U_OFF_ENC;
@@ -934,9 +956,9 @@
       for (y = 0; y < 2; ++y) {
         for (x = 0; x < 2; ++x, ++n) {
           const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-          const int non_zero =
-              TrellisQuantizeBlock(enc, tmp[n], rd->uv_levels[n], ctx, 2,
-                                   &dqm->uv_, dqm->lambda_trellis_uv_);
+          const int non_zero = TrellisQuantizeBlock(
+              enc, tmp[n], rd->uv_levels[n], ctx, TYPE_CHROMA_A, &dqm->uv_,
+              dqm->lambda_trellis_uv_);
           it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
           nz |= non_zero << n;
         }
@@ -985,20 +1007,8 @@
   SwapPtr(&it->yuv_out_, &it->yuv_out2_);
 }
 
-static score_t IsFlat(const int16_t* levels, int num_blocks, score_t thresh) {
-  score_t score = 0;
-  while (num_blocks-- > 0) {      // TODO(skal): refine positional scoring?
-    int i;
-    for (i = 1; i < 16; ++i) {    // omit DC, we're only interested in AC
-      score += (levels[i] != 0);
-      if (score > thresh) return 0;
-    }
-    levels += 16;
-  }
-  return 1;
-}
-
-static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
+static void PickBestIntra16(VP8EncIterator* WEBP_RESTRICT const it,
+                            VP8ModeScore* WEBP_RESTRICT rd) {
   const int kNumBlocks = 16;
   VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
   const int lambda = dqm->lambda_i16_;
@@ -1008,6 +1018,7 @@
   VP8ModeScore* rd_cur = &rd_tmp;
   VP8ModeScore* rd_best = rd;
   int mode;
+  int is_flat = IsFlatSource16(it->yuv_in_ + Y_OFF_ENC);
 
   rd->mode_i16 = -1;
   for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
@@ -1023,10 +1034,14 @@
         tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
     rd_cur->H = VP8FixedCostsI16[mode];
     rd_cur->R = VP8GetCostLuma16(it, rd_cur);
-    if (mode > 0 &&
-        IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) {
-      // penalty to avoid flat area to be mispredicted by complex mode
-      rd_cur->R += FLATNESS_PENALTY * kNumBlocks;
+    if (is_flat) {
+      // refine the first impression (which was in pixel space)
+      is_flat = IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16);
+      if (is_flat) {
+        // Block is very flat. We put emphasis on the distortion being very low!
+        rd_cur->D *= 2;
+        rd_cur->SD *= 2;
+      }
     }
 
     // Since we always examine Intra16 first, we can overwrite *rd directly.
@@ -1053,7 +1068,7 @@
 //------------------------------------------------------------------------------
 
 // return the cost array corresponding to the surrounding prediction modes.
-static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
+static const uint16_t* GetCostModeI4(VP8EncIterator* WEBP_RESTRICT const it,
                                      const uint8_t modes[16]) {
   const int preds_w = it->enc_->preds_w_;
   const int x = (it->i4_ & 3), y = it->i4_ >> 2;
@@ -1062,7 +1077,8 @@
   return VP8FixedCostsI4[top][left];
 }
 
-static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
+static int PickBestIntra4(VP8EncIterator* WEBP_RESTRICT const it,
+                          VP8ModeScore* WEBP_RESTRICT const rd) {
   const VP8Encoder* const enc = it->enc_;
   const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
   const int lambda = dqm->lambda_i4_;
@@ -1107,7 +1123,8 @@
                   : 0;
       rd_tmp.H = mode_costs[mode];
 
-      // Add flatness penalty
+      // Add flatness penalty, to avoid flat area to be mispredicted
+      // by a complex mode.
       if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
         rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
       } else {
@@ -1157,7 +1174,8 @@
 
 //------------------------------------------------------------------------------
 
-static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
+static void PickBestUV(VP8EncIterator* WEBP_RESTRICT const it,
+                       VP8ModeScore* WEBP_RESTRICT const rd) {
   const int kNumBlocks = 8;
   const VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
   const int lambda = dqm->lambda_uv_;
@@ -1209,7 +1227,8 @@
 //------------------------------------------------------------------------------
 // Final reconstruction and quantization.
 
-static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) {
+static void SimpleQuantize(VP8EncIterator* WEBP_RESTRICT const it,
+                           VP8ModeScore* WEBP_RESTRICT const rd) {
   const VP8Encoder* const enc = it->enc_;
   const int is_i16 = (it->mb_->type_ == 1);
   int nz = 0;
@@ -1234,9 +1253,9 @@
 }
 
 // Refine intra16/intra4 sub-modes based on distortion only (not rate).
-static void RefineUsingDistortion(VP8EncIterator* const it,
+static void RefineUsingDistortion(VP8EncIterator* WEBP_RESTRICT const it,
                                   int try_both_modes, int refine_uv_mode,
-                                  VP8ModeScore* const rd) {
+                                  VP8ModeScore* WEBP_RESTRICT const rd) {
   score_t best_score = MAX_COST;
   int nz = 0;
   int mode;
@@ -1262,11 +1281,19 @@
       if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) {
         continue;
       }
+
       if (score < best_score) {
         best_mode = mode;
         best_score = score;
       }
     }
+    if (it->x_ == 0 || it->y_ == 0) {
+      // avoid starting a checkerboard resonance from the border. See bug #432.
+      if (IsFlatSource16(src)) {
+        best_mode = (it->x_ == 0) ? 0 : 2;
+        try_both_modes = 0;  // stick to i16
+      }
+    }
     VP8SetIntra16Mode(it, best_mode);
     // we'll reconstruct later, if i16 mode actually gets selected
   }
@@ -1342,7 +1369,8 @@
 //------------------------------------------------------------------------------
 // Entry point
 
-int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
+int VP8Decimate(VP8EncIterator* WEBP_RESTRICT const it,
+                VP8ModeScore* WEBP_RESTRICT const rd,
                 VP8RDLevel rd_opt) {
   int is_skipped;
   const int method = it->enc_->method_;
diff --git a/third_party/libwebp/src/enc/syntax_enc.c b/third_party/libwebp/src/enc/syntax_enc.c
index a9e5a6c..9b8f524 100644
--- a/third_party/libwebp/src/enc/syntax_enc.c
+++ b/third_party/libwebp/src/enc/syntax_enc.c
@@ -258,7 +258,10 @@
     buf[3 * p + 1] = (part_size >>  8) & 0xff;
     buf[3 * p + 2] = (part_size >> 16) & 0xff;
   }
-  return p ? pic->writer(buf, 3 * p, pic) : 1;
+  if (p && !pic->writer(buf, 3 * p, pic)) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
+  }
+  return 1;
 }
 
 //------------------------------------------------------------------------------
@@ -349,7 +352,7 @@
                                        (enc->alpha_data_size_ & 1);
     riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
   }
-  // Sanity check.
+  // RIFF size should fit in 32-bits.
   if (riff_size > 0xfffffffeU) {
     return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
   }
@@ -381,6 +384,7 @@
 
   enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size);
   ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_);
+  if (!ok) WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
   return ok;
 }
 
diff --git a/third_party/libwebp/src/enc/vp8i_enc.h b/third_party/libwebp/src/enc/vp8i_enc.h
index 64dbfa4..04b1a9c 100644
--- a/third_party/libwebp/src/enc/vp8i_enc.h
+++ b/third_party/libwebp/src/enc/vp8i_enc.h
@@ -33,8 +33,8 @@
 
 // version numbers
 #define ENC_MAJ_VERSION 1
-#define ENC_MIN_VERSION 0
-#define ENC_REV_VERSION 0
+#define ENC_MIN_VERSION 3
+#define ENC_REV_VERSION 1
 
 enum { MAX_LF_LEVELS = 64,       // Maximum loop filter level
        MAX_VARIABLE_LEVEL = 67,  // last (inclusive) level with variable cost
@@ -251,7 +251,7 @@
   int           percent0_;         // saved initial progress percent
 
   DError        left_derr_;        // left error diffusion (u/v)
-  DError       *top_derr_;         // top diffusion error - NULL if disabled
+  DError*       top_derr_;         // top diffusion error - NULL if disabled
 
   uint8_t* y_left_;    // left luma samples (addressable from index -1 to 15).
   uint8_t* u_left_;    // left u samples (addressable from index -1 to 7)
@@ -280,7 +280,7 @@
 // Import uncompressed samples from source.
 // If tmp_32 is not NULL, import boundary samples too.
 // tmp_32 is a 32-bytes scratch buffer that must be aligned in memory.
-void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32);
+void VP8IteratorImport(VP8EncIterator* const it, uint8_t* const tmp_32);
 // export decimated samples
 void VP8IteratorExport(const VP8EncIterator* const it);
 // go to next macroblock. Returns false if not finished.
@@ -288,8 +288,7 @@
 // save the yuv_out_ boundary values to top_/left_ arrays for next iterations.
 void VP8IteratorSaveBoundary(VP8EncIterator* const it);
 // Report progression based on macroblock rows. Return 0 for user-abort request.
-int VP8IteratorProgress(const VP8EncIterator* const it,
-                        int final_delta_percent);
+int VP8IteratorProgress(const VP8EncIterator* const it, int delta);
 // Intra4x4 iterations
 void VP8IteratorStartI4(VP8EncIterator* const it);
 // returns true if not done.
@@ -473,7 +472,8 @@
 // Sets up segment's quantization values, base_quant_ and filter strengths.
 void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
 // Pick best modes and fills the levels. Returns true if skipped.
-int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
+int VP8Decimate(VP8EncIterator* WEBP_RESTRICT const it,
+                VP8ModeScore* WEBP_RESTRICT const rd,
                 VP8RDLevel rd_opt);
 
   // in alpha.c
@@ -493,23 +493,28 @@
 
   // misc utils for picture_*.c:
 
+// Returns true if 'picture' is non-NULL and dimensions/colorspace are within
+// their valid ranges. If returning false, the 'error_code' in 'picture' is
+// updated.
+int WebPValidatePicture(const WebPPicture* const picture);
+
 // Remove reference to the ARGB/YUVA buffer (doesn't free anything).
 void WebPPictureResetBuffers(WebPPicture* const picture);
 
-// Allocates ARGB buffer of given dimension (previous one is always free'd).
-// Preserves the YUV(A) buffer. Returns false in case of error (invalid param,
-// out-of-memory).
-int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height);
+// Allocates ARGB buffer according to set width/height (previous one is
+// always free'd). Preserves the YUV(A) buffer. Returns false in case of error
+// (invalid param, out-of-memory).
+int WebPPictureAllocARGB(WebPPicture* const picture);
 
-// Allocates YUVA buffer of given dimension (previous one is always free'd).
-// Uses picture->csp to determine whether an alpha buffer is needed.
+// Allocates YUVA buffer according to set width/height (previous one is always
+// free'd). Uses picture->csp to determine whether an alpha buffer is needed.
 // Preserves the ARGB buffer.
 // Returns false in case of error (invalid param, out-of-memory).
-int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height);
+int WebPPictureAllocYUVA(WebPPicture* const picture);
 
-// Clean-up the RGB samples under fully transparent area, to help lossless
-// compressibility (no guarantee, though). Assumes that pic->use_argb is true.
-void WebPCleanupTransparentAreaLossless(WebPPicture* const pic);
+// Replace samples that are fully transparent by 'color' to help compressibility
+// (no guarantee, though). Assumes pic->use_argb is true.
+void WebPReplaceTransparentPixels(WebPPicture* const pic, uint32_t color);
 
 //------------------------------------------------------------------------------
 
@@ -517,4 +522,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_ENC_VP8I_ENC_H_ */
+#endif  // WEBP_ENC_VP8I_ENC_H_
diff --git a/third_party/libwebp/src/enc/vp8l_enc.c b/third_party/libwebp/src/enc/vp8l_enc.c
index 27cd218..872619e 100644
--- a/third_party/libwebp/src/enc/vp8l_enc.c
+++ b/third_party/libwebp/src/enc/vp8l_enc.c
@@ -20,15 +20,16 @@
 #include "starboard/client_porting/poem/string_poem.h"
 #endif
 
+#include "src/dsp/lossless.h"
+#include "src/dsp/lossless_common.h"
 #include "src/enc/backward_references_enc.h"
 #include "src/enc/histogram_enc.h"
 #include "src/enc/vp8i_enc.h"
 #include "src/enc/vp8li_enc.h"
-#include "src/dsp/lossless.h"
-#include "src/dsp/lossless_common.h"
 #include "src/utils/bit_writer_utils.h"
 #include "src/utils/huffman_encode_utils.h"
 #include "src/utils/utils.h"
+#include "src/webp/encode.h"
 #include "src/webp/format_constants.h"
 
 // Maximum number of histogram images (sub-blocks).
@@ -70,25 +71,22 @@
   *col2 = tmp;
 }
 
-static void GreedyMinimizeDeltas(uint32_t palette[], int num_colors) {
-  // Find greedily always the closest color of the predicted color to minimize
-  // deltas in the palette. This reduces storage needs since the
-  // palette is stored with delta encoding.
-  uint32_t predict = 0x00000000;
-  int i, k;
-  for (i = 0; i < num_colors; ++i) {
-    int best_ix = i;
-    uint32_t best_score = ~0U;
-    for (k = i; k < num_colors; ++k) {
-      const uint32_t cur_score = PaletteColorDistance(palette[k], predict);
-      if (best_score > cur_score) {
-        best_score = cur_score;
-        best_ix = k;
-      }
+static WEBP_INLINE int SearchColorNoIdx(const uint32_t sorted[], uint32_t color,
+                                        int num_colors) {
+  int low = 0, hi = num_colors;
+  if (sorted[low] == color) return low;  // loop invariant: sorted[low] != color
+  while (1) {
+    const int mid = (low + hi) >> 1;
+    if (sorted[mid] == color) {
+      return mid;
+    } else if (sorted[mid] < color) {
+      low = mid;
+    } else {
+      hi = mid;
     }
-    SwapColor(&palette[best_ix], &palette[i]);
-    predict = palette[i];
   }
+  assert(0);
+  return 0;
 }
 
 // The palette has been sorted by alpha. This function checks if the other
@@ -97,7 +95,8 @@
 // no benefit to re-organize them greedily. A monotonic development
 // would be spotted in green-only situations (like lossy alpha) or gray-scale
 // images.
-static int PaletteHasNonMonotonousDeltas(uint32_t palette[], int num_colors) {
+static int PaletteHasNonMonotonousDeltas(const uint32_t* const palette,
+                                         int num_colors) {
   uint32_t predict = 0x000000;
   int i;
   uint8_t sign_found = 0x00;
@@ -120,28 +119,217 @@
   return (sign_found & (sign_found << 1)) != 0;  // two consequent signs.
 }
 
-// -----------------------------------------------------------------------------
-// Palette
+static void PaletteSortMinimizeDeltas(const uint32_t* const palette_sorted,
+                                      int num_colors, uint32_t* const palette) {
+  uint32_t predict = 0x00000000;
+  int i, k;
+  memcpy(palette, palette_sorted, num_colors * sizeof(*palette));
+  if (!PaletteHasNonMonotonousDeltas(palette_sorted, num_colors)) return;
+  // Find greedily always the closest color of the predicted color to minimize
+  // deltas in the palette. This reduces storage needs since the
+  // palette is stored with delta encoding.
+  for (i = 0; i < num_colors; ++i) {
+    int best_ix = i;
+    uint32_t best_score = ~0U;
+    for (k = i; k < num_colors; ++k) {
+      const uint32_t cur_score = PaletteColorDistance(palette[k], predict);
+      if (best_score > cur_score) {
+        best_score = cur_score;
+        best_ix = k;
+      }
+    }
+    SwapColor(&palette[best_ix], &palette[i]);
+    predict = palette[i];
+  }
+}
 
-// If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
-// creates a palette and returns true, else returns false.
-static int AnalyzeAndCreatePalette(const WebPPicture* const pic,
-                                   int low_effort,
-                                   uint32_t palette[MAX_PALETTE_SIZE],
-                                   int* const palette_size) {
-  const int num_colors = WebPGetColorPalette(pic, palette);
-  if (num_colors > MAX_PALETTE_SIZE) {
-    *palette_size = 0;
+// Sort palette in increasing order and prepare an inverse mapping array.
+static void PrepareMapToPalette(const uint32_t palette[], uint32_t num_colors,
+                                uint32_t sorted[], uint32_t idx_map[]) {
+  uint32_t i;
+  memcpy(sorted, palette, num_colors * sizeof(*sorted));
+  qsort(sorted, num_colors, sizeof(*sorted), PaletteCompareColorsForQsort);
+  for (i = 0; i < num_colors; ++i) {
+    idx_map[SearchColorNoIdx(sorted, palette[i], num_colors)] = i;
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Modified Zeng method from "A Survey on Palette Reordering
+// Methods for Improving the Compression of Color-Indexed Images" by Armando J.
+// Pinho and Antonio J. R. Neves.
+
+// Finds the biggest cooccurrence in the matrix.
+static void CoOccurrenceFindMax(const uint32_t* const cooccurrence,
+                                uint32_t num_colors, uint8_t* const c1,
+                                uint8_t* const c2) {
+  // Find the index that is most frequently located adjacent to other
+  // (different) indexes.
+  uint32_t best_sum = 0u;
+  uint32_t i, j, best_cooccurrence;
+  *c1 = 0u;
+  for (i = 0; i < num_colors; ++i) {
+    uint32_t sum = 0;
+    for (j = 0; j < num_colors; ++j) sum += cooccurrence[i * num_colors + j];
+    if (sum > best_sum) {
+      best_sum = sum;
+      *c1 = i;
+    }
+  }
+  // Find the index that is most frequently found adjacent to *c1.
+  *c2 = 0u;
+  best_cooccurrence = 0u;
+  for (i = 0; i < num_colors; ++i) {
+    if (cooccurrence[*c1 * num_colors + i] > best_cooccurrence) {
+      best_cooccurrence = cooccurrence[*c1 * num_colors + i];
+      *c2 = i;
+    }
+  }
+  assert(*c1 != *c2);
+}
+
+// Builds the cooccurrence matrix
+static int CoOccurrenceBuild(const WebPPicture* const pic,
+                             const uint32_t* const palette, uint32_t num_colors,
+                             uint32_t* cooccurrence) {
+  uint32_t *lines, *line_top, *line_current, *line_tmp;
+  int x, y;
+  const uint32_t* src = pic->argb;
+  uint32_t prev_pix = ~src[0];
+  uint32_t prev_idx = 0u;
+  uint32_t idx_map[MAX_PALETTE_SIZE] = {0};
+  uint32_t palette_sorted[MAX_PALETTE_SIZE];
+  lines = (uint32_t*)WebPSafeMalloc(2 * pic->width, sizeof(*lines));
+  if (lines == NULL) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  line_top = &lines[0];
+  line_current = &lines[pic->width];
+  PrepareMapToPalette(palette, num_colors, palette_sorted, idx_map);
+  for (y = 0; y < pic->height; ++y) {
+    for (x = 0; x < pic->width; ++x) {
+      const uint32_t pix = src[x];
+      if (pix != prev_pix) {
+        prev_idx = idx_map[SearchColorNoIdx(palette_sorted, pix, num_colors)];
+        prev_pix = pix;
+      }
+      line_current[x] = prev_idx;
+      // 4-connectivity is what works best as mentioned in "On the relation
+      // between Memon's and the modified Zeng's palette reordering methods".
+      if (x > 0 && prev_idx != line_current[x - 1]) {
+        const uint32_t left_idx = line_current[x - 1];
+        ++cooccurrence[prev_idx * num_colors + left_idx];
+        ++cooccurrence[left_idx * num_colors + prev_idx];
+      }
+      if (y > 0 && prev_idx != line_top[x]) {
+        const uint32_t top_idx = line_top[x];
+        ++cooccurrence[prev_idx * num_colors + top_idx];
+        ++cooccurrence[top_idx * num_colors + prev_idx];
+      }
+    }
+    line_tmp = line_top;
+    line_top = line_current;
+    line_current = line_tmp;
+    src += pic->argb_stride;
+  }
+  WebPSafeFree(lines);
+  return 1;
+}
+
+struct Sum {
+  uint8_t index;
+  uint32_t sum;
+};
+
+// Implements the modified Zeng method from "A Survey on Palette Reordering
+// Methods for Improving the Compression of Color-Indexed Images" by Armando J.
+// Pinho and Antonio J. R. Neves.
+static int PaletteSortModifiedZeng(
+    const WebPPicture* const pic, const uint32_t* const palette_sorted,
+    uint32_t num_colors, uint32_t* const palette) {
+  uint32_t i, j, ind;
+  uint8_t remapping[MAX_PALETTE_SIZE];
+  uint32_t* cooccurrence;
+  struct Sum sums[MAX_PALETTE_SIZE];
+  uint32_t first, last;
+  uint32_t num_sums;
+  // TODO(vrabaud) check whether one color images should use palette or not.
+  if (num_colors <= 1) return 1;
+  // Build the co-occurrence matrix.
+  cooccurrence =
+      (uint32_t*)WebPSafeCalloc(num_colors * num_colors, sizeof(*cooccurrence));
+  if (cooccurrence == NULL) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  if (!CoOccurrenceBuild(pic, palette_sorted, num_colors, cooccurrence)) {
+    WebPSafeFree(cooccurrence);
     return 0;
   }
-  *palette_size = num_colors;
-  qsort(palette, num_colors, sizeof(*palette), PaletteCompareColorsForQsort);
-  if (!low_effort && PaletteHasNonMonotonousDeltas(palette, num_colors)) {
-    GreedyMinimizeDeltas(palette, num_colors);
+
+  // Initialize the mapping list with the two best indices.
+  CoOccurrenceFindMax(cooccurrence, num_colors, &remapping[0], &remapping[1]);
+
+  // We need to append and prepend to the list of remapping. To this end, we
+  // actually define the next start/end of the list as indices in a vector (with
+  // a wrap around when the end is reached).
+  first = 0;
+  last = 1;
+  num_sums = num_colors - 2;  // -2 because we know the first two values
+  if (num_sums > 0) {
+    // Initialize the sums with the first two remappings and find the best one
+    struct Sum* best_sum = &sums[0];
+    best_sum->index = 0u;
+    best_sum->sum = 0u;
+    for (i = 0, j = 0; i < num_colors; ++i) {
+      if (i == remapping[0] || i == remapping[1]) continue;
+      sums[j].index = i;
+      sums[j].sum = cooccurrence[i * num_colors + remapping[0]] +
+                    cooccurrence[i * num_colors + remapping[1]];
+      if (sums[j].sum > best_sum->sum) best_sum = &sums[j];
+      ++j;
+    }
+
+    while (num_sums > 0) {
+      const uint8_t best_index = best_sum->index;
+      // Compute delta to know if we need to prepend or append the best index.
+      int32_t delta = 0;
+      const int32_t n = num_colors - num_sums;
+      for (ind = first, j = 0; (ind + j) % num_colors != last + 1; ++j) {
+        const uint16_t l_j = remapping[(ind + j) % num_colors];
+        delta += (n - 1 - 2 * (int32_t)j) *
+                 (int32_t)cooccurrence[best_index * num_colors + l_j];
+      }
+      if (delta > 0) {
+        first = (first == 0) ? num_colors - 1 : first - 1;
+        remapping[first] = best_index;
+      } else {
+        ++last;
+        remapping[last] = best_index;
+      }
+      // Remove best_sum from sums.
+      *best_sum = sums[num_sums - 1];
+      --num_sums;
+      // Update all the sums and find the best one.
+      best_sum = &sums[0];
+      for (i = 0; i < num_sums; ++i) {
+        sums[i].sum += cooccurrence[best_index * num_colors + sums[i].index];
+        if (sums[i].sum > best_sum->sum) best_sum = &sums[i];
+      }
+    }
+  }
+  assert((last + 1) % num_colors == first);
+  WebPSafeFree(cooccurrence);
+
+  // Re-map the palette.
+  for (i = 0; i < num_colors; ++i) {
+    palette[i] = palette_sorted[remapping[(first + i) % num_colors]];
   }
   return 1;
 }
 
+// -----------------------------------------------------------------------------
+// Palette
+
 // These five modes are evaluated and their respective entropy is computed.
 typedef enum {
   kDirect = 0,
@@ -149,10 +337,18 @@
   kSubGreen = 2,
   kSpatialSubGreen = 3,
   kPalette = 4,
-  kNumEntropyIx = 5
+  kPaletteAndSpatial = 5,
+  kNumEntropyIx = 6
 } EntropyIx;
 
 typedef enum {
+  kSortedDefault = 0,
+  kMinimizeDelta = 1,
+  kModifiedZeng = 2,
+  kUnusedPalette = 3,
+} PaletteSorting;
+
+typedef enum {
   kHistoAlpha = 0,
   kHistoAlphaPred,
   kHistoGreen,
@@ -169,10 +365,11 @@
   kHistoTotal  // Must be last.
 } HistoIx;
 
-static void AddSingleSubGreen(int p, uint32_t* const r, uint32_t* const b) {
-  const int green = p >> 8;  // The upper bits are masked away later.
-  ++r[((p >> 16) - green) & 0xff];
-  ++b[((p >>  0) - green) & 0xff];
+static void AddSingleSubGreen(uint32_t p,
+                              uint32_t* const r, uint32_t* const b) {
+  const int green = (int)p >> 8;  // The upper bits are masked away later.
+  ++r[(((int)p >> 16) - green) & 0xff];
+  ++b[(((int)p >>  0) - green) & 0xff];
 }
 
 static void AddSingle(uint32_t p,
@@ -246,8 +443,8 @@
       curr_row += argb_stride;
     }
     {
-      double entropy_comp[kHistoTotal];
-      double entropy[kNumEntropyIx];
+      float entropy_comp[kHistoTotal];
+      float entropy[kNumEntropyIx];
       int k;
       int last_mode_to_analyze = use_palette ? kPalette : kSpatialSubGreen;
       int j;
@@ -359,14 +556,21 @@
 }
 
 // Set of parameters to be used in each iteration of the cruncher.
-#define CRUNCH_CONFIGS_LZ77_MAX 2
+#define CRUNCH_SUBCONFIGS_MAX 2
+typedef struct {
+  int lz77_;
+  int do_no_cache_;
+} CrunchSubConfig;
 typedef struct {
   int entropy_idx_;
-  int lz77s_types_to_try_[CRUNCH_CONFIGS_LZ77_MAX];
-  int lz77s_types_to_try_size_;
+  PaletteSorting palette_sorting_type_;
+  CrunchSubConfig sub_configs_[CRUNCH_SUBCONFIGS_MAX];
+  int sub_configs_size_;
 } CrunchConfig;
 
-#define CRUNCH_CONFIGS_MAX kNumEntropyIx
+// +2 because we add a palette sorting configuration for kPalette and
+// kPaletteAndSpatial.
+#define CRUNCH_CONFIGS_MAX (kNumEntropyIx + 2)
 
 static int EncoderAnalyze(VP8LEncoder* const enc,
                           CrunchConfig crunch_configs[CRUNCH_CONFIGS_MAX],
@@ -381,11 +585,20 @@
   int i;
   int use_palette;
   int n_lz77s;
+  // If set to 0, analyze the cache with the computed cache value. If 1, also
+  // analyze with no-cache.
+  int do_no_cache = 0;
   assert(pic != NULL && pic->argb != NULL);
 
-  use_palette =
-      AnalyzeAndCreatePalette(pic, low_effort,
-                              enc->palette_, &enc->palette_size_);
+  // Check whether a palette is possible.
+  enc->palette_size_ = WebPGetColorPalette(pic, enc->palette_sorted_);
+  use_palette = (enc->palette_size_ <= MAX_PALETTE_SIZE);
+  if (!use_palette) {
+    enc->palette_size_ = 0;
+  } else {
+    qsort(enc->palette_sorted_, enc->palette_size_,
+          sizeof(*enc->palette_sorted_), PaletteCompareColorsForQsort);
+  }
 
   // Empirical bit sizes.
   enc->histo_bits_ = GetHistoBits(method, use_palette,
@@ -395,6 +608,8 @@
   if (low_effort) {
     // AnalyzeEntropy is somewhat slow.
     crunch_configs[0].entropy_idx_ = use_palette ? kPalette : kSpatialSubGreen;
+    crunch_configs[0].palette_sorting_type_ =
+        use_palette ? kSortedDefault : kUnusedPalette;
     n_lz77s = 1;
     *crunch_configs_size = 1;
   } else {
@@ -407,29 +622,59 @@
       return 0;
     }
     if (method == 6 && config->quality == 100) {
+      do_no_cache = 1;
       // Go brute force on all transforms.
       *crunch_configs_size = 0;
       for (i = 0; i < kNumEntropyIx; ++i) {
-        if (i != kPalette || use_palette) {
+        // We can only apply kPalette or kPaletteAndSpatial if we can indeed use
+        // a palette.
+        if ((i != kPalette && i != kPaletteAndSpatial) || use_palette) {
           assert(*crunch_configs_size < CRUNCH_CONFIGS_MAX);
-          crunch_configs[(*crunch_configs_size)++].entropy_idx_ = i;
+          crunch_configs[(*crunch_configs_size)].entropy_idx_ = i;
+          if (use_palette && (i == kPalette || i == kPaletteAndSpatial)) {
+            crunch_configs[(*crunch_configs_size)].palette_sorting_type_ =
+                kMinimizeDelta;
+            ++*crunch_configs_size;
+            // Also add modified Zeng's method.
+            crunch_configs[(*crunch_configs_size)].entropy_idx_ = i;
+            crunch_configs[(*crunch_configs_size)].palette_sorting_type_ =
+                kModifiedZeng;
+          } else {
+            crunch_configs[(*crunch_configs_size)].palette_sorting_type_ =
+                kUnusedPalette;
+          }
+          ++*crunch_configs_size;
         }
       }
     } else {
       // Only choose the guessed best transform.
       *crunch_configs_size = 1;
       crunch_configs[0].entropy_idx_ = min_entropy_ix;
+      crunch_configs[0].palette_sorting_type_ =
+          use_palette ? kMinimizeDelta : kUnusedPalette;
+      if (config->quality >= 75 && method == 5) {
+        // Test with and without color cache.
+        do_no_cache = 1;
+        // If we have a palette, also check in combination with spatial.
+        if (min_entropy_ix == kPalette) {
+          *crunch_configs_size = 2;
+          crunch_configs[1].entropy_idx_ = kPaletteAndSpatial;
+          crunch_configs[1].palette_sorting_type_ = kMinimizeDelta;
+        }
+      }
     }
   }
   // Fill in the different LZ77s.
-  assert(n_lz77s <= CRUNCH_CONFIGS_LZ77_MAX);
+  assert(n_lz77s <= CRUNCH_SUBCONFIGS_MAX);
   for (i = 0; i < *crunch_configs_size; ++i) {
     int j;
     for (j = 0; j < n_lz77s; ++j) {
-      crunch_configs[i].lz77s_types_to_try_[j] =
+      assert(j < CRUNCH_SUBCONFIGS_MAX);
+      crunch_configs[i].sub_configs_[j].lz77_ =
           (j == 0) ? kLZ77Standard | kLZ77RLE : kLZ77Box;
+      crunch_configs[i].sub_configs_[j].do_no_cache_ = do_no_cache;
     }
-    crunch_configs[i].lz77s_types_to_try_size_ = n_lz77s;
+    crunch_configs[i].sub_configs_size_ = n_lz77s;
   }
   return 1;
 }
@@ -445,7 +690,7 @@
   int i;
   if (!VP8LHashChainInit(&enc->hash_chain_, pix_cnt)) return 0;
 
-  for (i = 0; i < 3; ++i) VP8LBackwardRefsInit(&enc->refs_[i], refs_block_size);
+  for (i = 0; i < 4; ++i) VP8LBackwardRefsInit(&enc->refs_[i], refs_block_size);
 
   return 1;
 }
@@ -467,6 +712,7 @@
   for (i = 0; i < histogram_image_size; ++i) {
     const VP8LHistogram* const histo = histogram_image->histograms[i];
     HuffmanTreeCode* const codes = &huffman_codes[5 * i];
+    assert(histo != NULL);
     for (k = 0; k < 5; ++k) {
       const int num_symbols =
           (k == 0) ? VP8LHistogramNumCodes(histo->palette_code_bits_) :
@@ -712,11 +958,11 @@
   VP8LPutBits(bw, (bits << depth) | symbol, depth + n_bits);
 }
 
-static WebPEncodingError StoreImageToBitMask(
+static int StoreImageToBitMask(
     VP8LBitWriter* const bw, int width, int histo_bits,
     const VP8LBackwardRefs* const refs,
     const uint16_t* histogram_symbols,
-    const HuffmanTreeCode* const huffman_codes) {
+    const HuffmanTreeCode* const huffman_codes, const WebPPicture* const pic) {
   const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
   const int tile_mask = (histo_bits == 0) ? 0 : -(1 << histo_bits);
   // x and y trace the position in the image.
@@ -769,51 +1015,55 @@
     }
     VP8LRefsCursorNext(&c);
   }
-  return bw->error_ ? VP8_ENC_ERROR_OUT_OF_MEMORY : VP8_ENC_OK;
+  if (bw->error_) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  return 1;
 }
 
-// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
-static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
-                                              const uint32_t* const argb,
-                                              VP8LHashChain* const hash_chain,
-                                              VP8LBackwardRefs* const refs_tmp1,
-                                              VP8LBackwardRefs* const refs_tmp2,
-                                              int width, int height,
-                                              int quality, int low_effort) {
+// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31.
+// pic and percent are for progress.
+static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
+                                const uint32_t* const argb,
+                                VP8LHashChain* const hash_chain,
+                                VP8LBackwardRefs* const refs_array, int width,
+                                int height, int quality, int low_effort,
+                                const WebPPicture* const pic, int percent_range,
+                                int* const percent) {
   int i;
   int max_tokens = 0;
-  WebPEncodingError err = VP8_ENC_OK;
   VP8LBackwardRefs* refs;
   HuffmanTreeToken* tokens = NULL;
-  HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
-  const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
+  HuffmanTreeCode huffman_codes[5] = {{0, NULL, NULL}};
+  const uint16_t histogram_symbols[1] = {0};  // only one tree, one symbol
   int cache_bits = 0;
   VP8LHistogramSet* histogram_image = NULL;
   HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
-        3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
+      3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
   if (huff_tree == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
   // Calculate backward references from ARGB image.
-  if (!VP8LHashChainFill(hash_chain, quality, argb, width, height,
-                         low_effort)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  if (!VP8LHashChainFill(hash_chain, quality, argb, width, height, low_effort,
+                         pic, percent_range / 2, percent)) {
     goto Error;
   }
-  refs = VP8LGetBackwardReferences(width, height, argb, quality, 0,
-                                   kLZ77Standard | kLZ77RLE, &cache_bits,
-                                   hash_chain, refs_tmp1, refs_tmp2);
-  if (refs == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  if (!VP8LGetBackwardReferences(width, height, argb, quality, /*low_effort=*/0,
+                                 kLZ77Standard | kLZ77RLE, cache_bits,
+                                 /*do_no_cache=*/0, hash_chain, refs_array,
+                                 &cache_bits, pic,
+                                 percent_range - percent_range / 2, percent)) {
     goto Error;
   }
+  refs = &refs_array[0];
   histogram_image = VP8LAllocateHistogramSet(1, cache_bits);
   if (histogram_image == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
+  VP8LHistogramSetClear(histogram_image);
 
   // Build histogram image and symbols from backward references.
   VP8LHistogramStoreRefs(refs, histogram_image->histograms[0]);
@@ -821,7 +1071,7 @@
   // Create Huffman bit lengths and codes for each histogram image.
   assert(histogram_image->size == 1);
   if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
@@ -838,7 +1088,7 @@
 
   tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
   if (tokens == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
@@ -850,27 +1100,32 @@
   }
 
   // Store actual literals.
-  err = StoreImageToBitMask(bw, width, 0, refs, histogram_symbols,
-                            huffman_codes);
+  if (!StoreImageToBitMask(bw, width, 0, refs, histogram_symbols, huffman_codes,
+                           pic)) {
+    goto Error;
+  }
 
  Error:
   WebPSafeFree(tokens);
   WebPSafeFree(huff_tree);
   VP8LFreeHistogramSet(histogram_image);
   WebPSafeFree(huffman_codes[0].codes);
-  return err;
+  return (pic->error_code == VP8_ENC_OK);
 }
 
-static WebPEncodingError EncodeImageInternal(
+// pic and percent are for progress.
+static int EncodeImageInternal(
     VP8LBitWriter* const bw, const uint32_t* const argb,
-    VP8LHashChain* const hash_chain, VP8LBackwardRefs refs_array[3], int width,
+    VP8LHashChain* const hash_chain, VP8LBackwardRefs refs_array[4], int width,
     int height, int quality, int low_effort, int use_cache,
     const CrunchConfig* const config, int* cache_bits, int histogram_bits,
-    size_t init_byte_position, int* const hdr_size, int* const data_size) {
-  WebPEncodingError err = VP8_ENC_OK;
+    size_t init_byte_position, int* const hdr_size, int* const data_size,
+    const WebPPicture* const pic, int percent_range, int* const percent) {
   const uint32_t histogram_image_xysize =
       VP8LSubSampleSize(width, histogram_bits) *
       VP8LSubSampleSize(height, histogram_bits);
+  int remaining_percent = percent_range;
+  int percent_start = *percent;
   VP8LHistogramSet* histogram_image = NULL;
   VP8LHistogram* tmp_histo = NULL;
   int histogram_image_size = 0;
@@ -879,112 +1134,135 @@
       3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
   HuffmanTreeToken* tokens = NULL;
   HuffmanTreeCode* huffman_codes = NULL;
-  VP8LBackwardRefs* refs_best;
-  VP8LBackwardRefs* refs_tmp;
-  uint16_t* const histogram_symbols =
-      (uint16_t*)WebPSafeMalloc(histogram_image_xysize,
-                                sizeof(*histogram_symbols));
-  int lz77s_idx;
+  uint16_t* const histogram_symbols = (uint16_t*)WebPSafeMalloc(
+      histogram_image_xysize, sizeof(*histogram_symbols));
+  int sub_configs_idx;
+  int cache_bits_init, write_histogram_image;
   VP8LBitWriter bw_init = *bw, bw_best;
   int hdr_size_tmp;
+  VP8LHashChain hash_chain_histogram;  // histogram image hash chain
+  size_t bw_size_best = ~(size_t)0;
   assert(histogram_bits >= MIN_HUFFMAN_BITS);
   assert(histogram_bits <= MAX_HUFFMAN_BITS);
   assert(hdr_size != NULL);
   assert(data_size != NULL);
 
-  if (histogram_symbols == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  memset(&hash_chain_histogram, 0, sizeof(hash_chain_histogram));
+  if (!VP8LBitWriterInit(&bw_best, 0)) {
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
+  // Make sure we can allocate the different objects.
+  if (huff_tree == NULL || histogram_symbols == NULL ||
+      !VP8LHashChainInit(&hash_chain_histogram, histogram_image_xysize)) {
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    goto Error;
+  }
+
+  percent_range = remaining_percent / 5;
+  if (!VP8LHashChainFill(hash_chain, quality, argb, width, height,
+                         low_effort, pic, percent_range, percent)) {
+    goto Error;
+  }
+  percent_start += percent_range;
+  remaining_percent -= percent_range;
+
   if (use_cache) {
     // If the value is different from zero, it has been set during the
     // palette analysis.
-    if (*cache_bits == 0) *cache_bits = MAX_COLOR_CACHE_BITS;
+    cache_bits_init = (*cache_bits == 0) ? MAX_COLOR_CACHE_BITS : *cache_bits;
   } else {
-    *cache_bits = 0;
+    cache_bits_init = 0;
   }
-  // 'best_refs' is the reference to the best backward refs and points to one
-  // of refs_array[0] or refs_array[1].
-  // Calculate backward references from ARGB image.
-  if (huff_tree == NULL ||
-      !VP8LHashChainFill(hash_chain, quality, argb, width, height,
-                         low_effort) ||
-      !VP8LBitWriterInit(&bw_best, 0) ||
-      (config->lz77s_types_to_try_size_ > 1 &&
-       !VP8LBitWriterClone(bw, &bw_best))) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  // If several iterations will happen, clone into bw_best.
+  if ((config->sub_configs_size_ > 1 || config->sub_configs_[0].do_no_cache_) &&
+      !VP8LBitWriterClone(bw, &bw_best)) {
+    WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
-  for (lz77s_idx = 0; lz77s_idx < config->lz77s_types_to_try_size_;
-       ++lz77s_idx) {
-    refs_best = VP8LGetBackwardReferences(
-        width, height, argb, quality, low_effort,
-        config->lz77s_types_to_try_[lz77s_idx], cache_bits, hash_chain,
-        &refs_array[0], &refs_array[1]);
-    if (refs_best == NULL) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-      goto Error;
-    }
-    // Keep the best references aside and use the other element from the first
-    // two as a temporary for later usage.
-    refs_tmp = &refs_array[refs_best == &refs_array[0] ? 1 : 0];
 
-    histogram_image =
-        VP8LAllocateHistogramSet(histogram_image_xysize, *cache_bits);
-    tmp_histo = VP8LAllocateHistogram(*cache_bits);
-    if (histogram_image == NULL || tmp_histo == NULL) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  for (sub_configs_idx = 0; sub_configs_idx < config->sub_configs_size_;
+       ++sub_configs_idx) {
+    const CrunchSubConfig* const sub_config =
+        &config->sub_configs_[sub_configs_idx];
+    int cache_bits_best, i_cache;
+    int i_remaining_percent = remaining_percent / config->sub_configs_size_;
+    int i_percent_range = i_remaining_percent / 4;
+    i_remaining_percent -= i_percent_range;
+
+    if (!VP8LGetBackwardReferences(
+            width, height, argb, quality, low_effort, sub_config->lz77_,
+            cache_bits_init, sub_config->do_no_cache_, hash_chain,
+            &refs_array[0], &cache_bits_best, pic, i_percent_range, percent)) {
       goto Error;
     }
 
-    // Build histogram image and symbols from backward references.
-    if (!VP8LGetHistoImageSymbols(width, height, refs_best, quality, low_effort,
-                                  histogram_bits, *cache_bits, histogram_image,
-                                  tmp_histo, histogram_symbols)) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-      goto Error;
-    }
-    // Create Huffman bit lengths and codes for each histogram image.
-    histogram_image_size = histogram_image->size;
-    bit_array_size = 5 * histogram_image_size;
-    huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
-                                                     sizeof(*huffman_codes));
-    // Note: some histogram_image entries may point to tmp_histos[], so the
-    // latter need to outlive the following call to GetHuffBitLengthsAndCodes().
-    if (huffman_codes == NULL ||
-        !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-      goto Error;
-    }
-    // Free combined histograms.
-    VP8LFreeHistogramSet(histogram_image);
-    histogram_image = NULL;
+    for (i_cache = 0; i_cache < (sub_config->do_no_cache_ ? 2 : 1); ++i_cache) {
+      const int cache_bits_tmp = (i_cache == 0) ? cache_bits_best : 0;
+      // Speed-up: no need to study the no-cache case if it was already studied
+      // in i_cache == 0.
+      if (i_cache == 1 && cache_bits_best == 0) break;
 
-    // Free scratch histograms.
-    VP8LFreeHistogram(tmp_histo);
-    tmp_histo = NULL;
+      // Reset the bit writer for this iteration.
+      VP8LBitWriterReset(&bw_init, bw);
 
-    // Color Cache parameters.
-    if (*cache_bits > 0) {
-      VP8LPutBits(bw, 1, 1);
-      VP8LPutBits(bw, *cache_bits, 4);
-    } else {
-      VP8LPutBits(bw, 0, 1);
-    }
+      // Build histogram image and symbols from backward references.
+      histogram_image =
+          VP8LAllocateHistogramSet(histogram_image_xysize, cache_bits_tmp);
+      tmp_histo = VP8LAllocateHistogram(cache_bits_tmp);
+      if (histogram_image == NULL || tmp_histo == NULL) {
+        WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+        goto Error;
+      }
 
-    // Huffman image + meta huffman.
-    {
-      const int write_histogram_image = (histogram_image_size > 1);
+      i_percent_range = i_remaining_percent / 3;
+      i_remaining_percent -= i_percent_range;
+      if (!VP8LGetHistoImageSymbols(
+              width, height, &refs_array[i_cache], quality, low_effort,
+              histogram_bits, cache_bits_tmp, histogram_image, tmp_histo,
+              histogram_symbols, pic, i_percent_range, percent)) {
+        goto Error;
+      }
+      // Create Huffman bit lengths and codes for each histogram image.
+      histogram_image_size = histogram_image->size;
+      bit_array_size = 5 * histogram_image_size;
+      huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
+                                                       sizeof(*huffman_codes));
+      // Note: some histogram_image entries may point to tmp_histos[], so the
+      // latter need to outlive the following call to
+      // GetHuffBitLengthsAndCodes().
+      if (huffman_codes == NULL ||
+          !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
+        WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+        goto Error;
+      }
+      // Free combined histograms.
+      VP8LFreeHistogramSet(histogram_image);
+      histogram_image = NULL;
+
+      // Free scratch histograms.
+      VP8LFreeHistogram(tmp_histo);
+      tmp_histo = NULL;
+
+      // Color Cache parameters.
+      if (cache_bits_tmp > 0) {
+        VP8LPutBits(bw, 1, 1);
+        VP8LPutBits(bw, cache_bits_tmp, 4);
+      } else {
+        VP8LPutBits(bw, 0, 1);
+      }
+
+      // Huffman image + meta huffman.
+      write_histogram_image = (histogram_image_size > 1);
       VP8LPutBits(bw, write_histogram_image, 1);
       if (write_histogram_image) {
-        uint32_t* const histogram_argb =
-            (uint32_t*)WebPSafeMalloc(histogram_image_xysize,
-                                      sizeof(*histogram_argb));
+        uint32_t* const histogram_argb = (uint32_t*)WebPSafeMalloc(
+            histogram_image_xysize, sizeof(*histogram_argb));
         int max_index = 0;
         uint32_t i;
         if (histogram_argb == NULL) {
-          err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+          WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
           goto Error;
         }
         for (i = 0; i < histogram_image_xysize; ++i) {
@@ -997,73 +1275,84 @@
         histogram_image_size = max_index;
 
         VP8LPutBits(bw, histogram_bits - 2, 3);
-        err = EncodeImageNoHuffman(
-            bw, histogram_argb, hash_chain, refs_tmp, &refs_array[2],
-            VP8LSubSampleSize(width, histogram_bits),
-            VP8LSubSampleSize(height, histogram_bits), quality, low_effort);
+        i_percent_range = i_remaining_percent / 2;
+        i_remaining_percent -= i_percent_range;
+        if (!EncodeImageNoHuffman(
+                bw, histogram_argb, &hash_chain_histogram, &refs_array[2],
+                VP8LSubSampleSize(width, histogram_bits),
+                VP8LSubSampleSize(height, histogram_bits), quality, low_effort,
+                pic, i_percent_range, percent)) {
+          WebPSafeFree(histogram_argb);
+          goto Error;
+        }
         WebPSafeFree(histogram_argb);
-        if (err != VP8_ENC_OK) goto Error;
       }
-    }
 
-    // Store Huffman codes.
-    {
-      int i;
-      int max_tokens = 0;
-      // Find maximum number of symbols for the huffman tree-set.
-      for (i = 0; i < 5 * histogram_image_size; ++i) {
-        HuffmanTreeCode* const codes = &huffman_codes[i];
-        if (max_tokens < codes->num_symbols) {
-          max_tokens = codes->num_symbols;
+      // Store Huffman codes.
+      {
+        int i;
+        int max_tokens = 0;
+        // Find maximum number of symbols for the huffman tree-set.
+        for (i = 0; i < 5 * histogram_image_size; ++i) {
+          HuffmanTreeCode* const codes = &huffman_codes[i];
+          if (max_tokens < codes->num_symbols) {
+            max_tokens = codes->num_symbols;
+          }
+        }
+        tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
+        if (tokens == NULL) {
+          WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+          goto Error;
+        }
+        for (i = 0; i < 5 * histogram_image_size; ++i) {
+          HuffmanTreeCode* const codes = &huffman_codes[i];
+          StoreHuffmanCode(bw, huff_tree, tokens, codes);
+          ClearHuffmanTreeIfOnlyOneSymbol(codes);
         }
       }
-      tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
-      if (tokens == NULL) {
-        err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      // Store actual literals.
+      hdr_size_tmp = (int)(VP8LBitWriterNumBytes(bw) - init_byte_position);
+      if (!StoreImageToBitMask(bw, width, histogram_bits, &refs_array[i_cache],
+                               histogram_symbols, huffman_codes, pic)) {
         goto Error;
       }
-      for (i = 0; i < 5 * histogram_image_size; ++i) {
-        HuffmanTreeCode* const codes = &huffman_codes[i];
-        StoreHuffmanCode(bw, huff_tree, tokens, codes);
-        ClearHuffmanTreeIfOnlyOneSymbol(codes);
+      // Keep track of the smallest image so far.
+      if (VP8LBitWriterNumBytes(bw) < bw_size_best) {
+        bw_size_best = VP8LBitWriterNumBytes(bw);
+        *cache_bits = cache_bits_tmp;
+        *hdr_size = hdr_size_tmp;
+        *data_size =
+            (int)(VP8LBitWriterNumBytes(bw) - init_byte_position - *hdr_size);
+        VP8LBitWriterSwap(bw, &bw_best);
       }
-    }
-    // Store actual literals.
-    hdr_size_tmp = (int)(VP8LBitWriterNumBytes(bw) - init_byte_position);
-    err = StoreImageToBitMask(bw, width, histogram_bits, refs_best,
-                              histogram_symbols, huffman_codes);
-    // Keep track of the smallest image so far.
-    if (lz77s_idx == 0 ||
-        VP8LBitWriterNumBytes(bw) < VP8LBitWriterNumBytes(&bw_best)) {
-      *hdr_size = hdr_size_tmp;
-      *data_size =
-          (int)(VP8LBitWriterNumBytes(bw) - init_byte_position - *hdr_size);
-      VP8LBitWriterSwap(bw, &bw_best);
-    }
-    // Reset the bit writer for the following iteration if any.
-    if (config->lz77s_types_to_try_size_ > 1) VP8LBitWriterReset(&bw_init, bw);
-    WebPSafeFree(tokens);
-    tokens = NULL;
-    if (huffman_codes != NULL) {
-      WebPSafeFree(huffman_codes->codes);
-      WebPSafeFree(huffman_codes);
-      huffman_codes = NULL;
+      WebPSafeFree(tokens);
+      tokens = NULL;
+      if (huffman_codes != NULL) {
+        WebPSafeFree(huffman_codes->codes);
+        WebPSafeFree(huffman_codes);
+        huffman_codes = NULL;
+      }
     }
   }
   VP8LBitWriterSwap(bw, &bw_best);
 
+  if (!WebPReportProgress(pic, percent_start + remaining_percent, percent)) {
+    goto Error;
+  }
+
  Error:
   WebPSafeFree(tokens);
   WebPSafeFree(huff_tree);
   VP8LFreeHistogramSet(histogram_image);
   VP8LFreeHistogram(tmp_histo);
+  VP8LHashChainClear(&hash_chain_histogram);
   if (huffman_codes != NULL) {
     WebPSafeFree(huffman_codes->codes);
     WebPSafeFree(huffman_codes);
   }
   WebPSafeFree(histogram_symbols);
   VP8LBitWriterWipeOut(&bw_best);
-  return err;
+  return (pic->error_code == VP8_ENC_OK);
 }
 
 // -----------------------------------------------------------------------------
@@ -1072,72 +1361,73 @@
 static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
                                VP8LBitWriter* const bw) {
   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
-  VP8LPutBits(bw, SUBTRACT_GREEN, 2);
+  VP8LPutBits(bw, SUBTRACT_GREEN_TRANSFORM, 2);
   VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
 }
 
-static WebPEncodingError ApplyPredictFilter(const VP8LEncoder* const enc,
-                                            int width, int height,
-                                            int quality, int low_effort,
-                                            int used_subtract_green,
-                                            VP8LBitWriter* const bw) {
+static int ApplyPredictFilter(const VP8LEncoder* const enc, int width,
+                              int height, int quality, int low_effort,
+                              int used_subtract_green, VP8LBitWriter* const bw,
+                              int percent_range, int* const percent) {
   const int pred_bits = enc->transform_bits_;
   const int transform_width = VP8LSubSampleSize(width, pred_bits);
   const int transform_height = VP8LSubSampleSize(height, pred_bits);
   // we disable near-lossless quantization if palette is used.
-  const int near_lossless_strength = enc->use_palette_ ? 100
-                                   : enc->config_->near_lossless;
+  const int near_lossless_strength =
+      enc->use_palette_ ? 100 : enc->config_->near_lossless;
 
-  VP8LResidualImage(width, height, pred_bits, low_effort, enc->argb_,
-                    enc->argb_scratch_, enc->transform_data_,
-                    near_lossless_strength, enc->config_->exact,
-                    used_subtract_green);
+  if (!VP8LResidualImage(
+          width, height, pred_bits, low_effort, enc->argb_, enc->argb_scratch_,
+          enc->transform_data_, near_lossless_strength, enc->config_->exact,
+          used_subtract_green, enc->pic_, percent_range / 2, percent)) {
+    return 0;
+  }
   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   VP8LPutBits(bw, PREDICTOR_TRANSFORM, 2);
   assert(pred_bits >= 2);
   VP8LPutBits(bw, pred_bits - 2, 3);
   return EncodeImageNoHuffman(
       bw, enc->transform_data_, (VP8LHashChain*)&enc->hash_chain_,
-      (VP8LBackwardRefs*)&enc->refs_[0],  // cast const away
-      (VP8LBackwardRefs*)&enc->refs_[1], transform_width, transform_height,
-      quality, low_effort);
+      (VP8LBackwardRefs*)&enc->refs_[0], transform_width, transform_height,
+      quality, low_effort, enc->pic_, percent_range - percent_range / 2,
+      percent);
 }
 
-static WebPEncodingError ApplyCrossColorFilter(const VP8LEncoder* const enc,
-                                               int width, int height,
-                                               int quality, int low_effort,
-                                               VP8LBitWriter* const bw) {
+static int ApplyCrossColorFilter(const VP8LEncoder* const enc, int width,
+                                 int height, int quality, int low_effort,
+                                 VP8LBitWriter* const bw, int percent_range,
+                                 int* const percent) {
   const int ccolor_transform_bits = enc->transform_bits_;
   const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
   const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
 
-  VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
-                          enc->argb_, enc->transform_data_);
+  if (!VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
+                               enc->argb_, enc->transform_data_, enc->pic_,
+                               percent_range / 2, percent)) {
+    return 0;
+  }
   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   VP8LPutBits(bw, CROSS_COLOR_TRANSFORM, 2);
   assert(ccolor_transform_bits >= 2);
   VP8LPutBits(bw, ccolor_transform_bits - 2, 3);
   return EncodeImageNoHuffman(
       bw, enc->transform_data_, (VP8LHashChain*)&enc->hash_chain_,
-      (VP8LBackwardRefs*)&enc->refs_[0],  // cast const away
-      (VP8LBackwardRefs*)&enc->refs_[1], transform_width, transform_height,
-      quality, low_effort);
+      (VP8LBackwardRefs*)&enc->refs_[0], transform_width, transform_height,
+      quality, low_effort, enc->pic_, percent_range - percent_range / 2,
+      percent);
 }
 
 // -----------------------------------------------------------------------------
 
-static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
-                                         size_t riff_size, size_t vp8l_size) {
+static int WriteRiffHeader(const WebPPicture* const pic, size_t riff_size,
+                           size_t vp8l_size) {
   uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
     'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
     'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
   };
   PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
   PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
-  if (!pic->writer(riff, sizeof(riff), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
+  return pic->writer(riff, sizeof(riff), pic);
 }
 
 static int WriteImageSize(const WebPPicture* const pic,
@@ -1157,36 +1447,32 @@
   return !bw->error_;
 }
 
-static WebPEncodingError WriteImage(const WebPPicture* const pic,
-                                    VP8LBitWriter* const bw,
-                                    size_t* const coded_size) {
-  WebPEncodingError err = VP8_ENC_OK;
+static int WriteImage(const WebPPicture* const pic, VP8LBitWriter* const bw,
+                      size_t* const coded_size) {
   const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
   const size_t webpll_size = VP8LBitWriterNumBytes(bw);
   const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
   const size_t pad = vp8l_size & 1;
   const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
+  *coded_size = 0;
 
-  err = WriteRiffHeader(pic, riff_size, vp8l_size);
-  if (err != VP8_ENC_OK) goto Error;
+  if (bw->error_) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
 
-  if (!pic->writer(webpll_data, webpll_size, pic)) {
-    err = VP8_ENC_ERROR_BAD_WRITE;
-    goto Error;
+  if (!WriteRiffHeader(pic, riff_size, vp8l_size) ||
+      !pic->writer(webpll_data, webpll_size, pic)) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
   }
 
   if (pad) {
     const uint8_t pad_byte[1] = { 0 };
     if (!pic->writer(pad_byte, 1, pic)) {
-      err = VP8_ENC_ERROR_BAD_WRITE;
-      goto Error;
+      return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
     }
   }
   *coded_size = CHUNK_HEADER_SIZE + riff_size;
-  return VP8_ENC_OK;
-
- Error:
-  return err;
+  return 1;
 }
 
 // -----------------------------------------------------------------------------
@@ -1202,18 +1488,16 @@
 // Flags influencing the memory allocated:
 //  enc->transform_bits_
 //  enc->use_predict_, enc->use_cross_color_
-static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
-                                                 int width, int height) {
-  WebPEncodingError err = VP8_ENC_OK;
+static int AllocateTransformBuffer(VP8LEncoder* const enc, int width,
+                                   int height) {
   const uint64_t image_size = width * height;
   // VP8LResidualImage needs room for 2 scanlines of uint32 pixels with an extra
   // pixel in each, plus 2 regular scanlines of bytes.
   // TODO(skal): Clean up by using arithmetic in bytes instead of words.
   const uint64_t argb_scratch_size =
-      enc->use_predict_
-          ? (width + 1) * 2 +
-            (width * 2 + sizeof(uint32_t) - 1) / sizeof(uint32_t)
-          : 0;
+      enc->use_predict_ ? (width + 1) * 2 + (width * 2 + sizeof(uint32_t) - 1) /
+                                                sizeof(uint32_t)
+                        : 0;
   const uint64_t transform_data_size =
       (enc->use_predict_ || enc->use_cross_color_)
           ? VP8LSubSampleSize(width, enc->transform_bits_) *
@@ -1221,17 +1505,15 @@
           : 0;
   const uint64_t max_alignment_in_words =
       (WEBP_ALIGN_CST + sizeof(uint32_t) - 1) / sizeof(uint32_t);
-  const uint64_t mem_size =
-      image_size + max_alignment_in_words +
-      argb_scratch_size + max_alignment_in_words +
-      transform_data_size;
+  const uint64_t mem_size = image_size + max_alignment_in_words +
+                            argb_scratch_size + max_alignment_in_words +
+                            transform_data_size;
   uint32_t* mem = enc->transform_mem_;
   if (mem == NULL || mem_size > enc->transform_mem_size_) {
     ClearTransformBuffer(enc);
     mem = (uint32_t*)WebPSafeMalloc(mem_size, sizeof(*mem));
     if (mem == NULL) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-      goto Error;
+      return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
     }
     enc->transform_mem_ = mem;
     enc->transform_mem_size_ = (size_t)mem_size;
@@ -1244,47 +1526,34 @@
   enc->transform_data_ = mem;
 
   enc->current_width_ = width;
- Error:
-  return err;
+  return 1;
 }
 
-static WebPEncodingError MakeInputImageCopy(VP8LEncoder* const enc) {
-  WebPEncodingError err = VP8_ENC_OK;
+static int MakeInputImageCopy(VP8LEncoder* const enc) {
   const WebPPicture* const picture = enc->pic_;
   const int width = picture->width;
   const int height = picture->height;
-  int y;
-  err = AllocateTransformBuffer(enc, width, height);
-  if (err != VP8_ENC_OK) return err;
-  if (enc->argb_content_ == kEncoderARGB) return VP8_ENC_OK;
-  for (y = 0; y < height; ++y) {
-    memcpy(enc->argb_ + y * width,
-           picture->argb + y * picture->argb_stride,
-           width * sizeof(*enc->argb_));
+
+  if (!AllocateTransformBuffer(enc, width, height)) return 0;
+  if (enc->argb_content_ == kEncoderARGB) return 1;
+
+  {
+    uint32_t* dst = enc->argb_;
+    const uint32_t* src = picture->argb;
+    int y;
+    for (y = 0; y < height; ++y) {
+      memcpy(dst, src, width * sizeof(*dst));
+      dst += width;
+      src += picture->argb_stride;
+    }
   }
   enc->argb_content_ = kEncoderARGB;
   assert(enc->current_width_ == width);
-  return VP8_ENC_OK;
+  return 1;
 }
 
 // -----------------------------------------------------------------------------
 
-static WEBP_INLINE int SearchColorNoIdx(const uint32_t sorted[], uint32_t color,
-                                        int hi) {
-  int low = 0;
-  if (sorted[low] == color) return low;  // loop invariant: sorted[low] != color
-  while (1) {
-    const int mid = (low + hi) >> 1;
-    if (sorted[mid] == color) {
-      return mid;
-    } else if (sorted[mid] < color) {
-      low = mid;
-    } else {
-      hi = mid;
-    }
-  }
-}
-
 #define APPLY_PALETTE_GREEDY_MAX 4
 
 static WEBP_INLINE uint32_t SearchColorGreedy(const uint32_t palette[],
@@ -1319,17 +1588,6 @@
          (32 - PALETTE_INV_SIZE_BITS);
 }
 
-// Sort palette in increasing order and prepare an inverse mapping array.
-static void PrepareMapToPalette(const uint32_t palette[], int num_colors,
-                                uint32_t sorted[], uint32_t idx_map[]) {
-  int i;
-  memcpy(sorted, palette, num_colors * sizeof(*sorted));
-  qsort(sorted, num_colors, sizeof(*sorted), PaletteCompareColorsForQsort);
-  for (i = 0; i < num_colors; ++i) {
-    idx_map[SearchColorNoIdx(sorted, palette[i], num_colors)] = i;
-  }
-}
-
 // Use 1 pixel cache for ARGB pixels.
 #define APPLY_PALETTE_FOR(COLOR_INDEX) do {         \
   uint32_t prev_pix = palette[0];                   \
@@ -1353,16 +1611,18 @@
 // using 'row' as a temporary buffer of size 'width'.
 // We assume that all src[] values have a corresponding entry in the palette.
 // Note: src[] can be the same as dst[]
-static WebPEncodingError ApplyPalette(const uint32_t* src, uint32_t src_stride,
-                                      uint32_t* dst, uint32_t dst_stride,
-                                      const uint32_t* palette, int palette_size,
-                                      int width, int height, int xbits) {
+static int ApplyPalette(const uint32_t* src, uint32_t src_stride, uint32_t* dst,
+                        uint32_t dst_stride, const uint32_t* palette,
+                        int palette_size, int width, int height, int xbits,
+                        const WebPPicture* const pic) {
   // TODO(skal): this tmp buffer is not needed if VP8LBundleColorMap() can be
   // made to work in-place.
   uint8_t* const tmp_row = (uint8_t*)WebPSafeMalloc(width, sizeof(*tmp_row));
   int x, y;
 
-  if (tmp_row == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
+  if (tmp_row == NULL) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
 
   if (palette_size < APPLY_PALETTE_GREEDY_MAX) {
     APPLY_PALETTE_FOR(SearchColorGreedy(palette, palette_size, pix));
@@ -1407,7 +1667,7 @@
     }
   }
   WebPSafeFree(tmp_row);
-  return VP8_ENC_OK;
+  return 1;
 }
 #undef APPLY_PALETTE_FOR
 #undef PALETTE_INV_SIZE_BITS
@@ -1415,9 +1675,7 @@
 #undef APPLY_PALETTE_GREEDY_MAX
 
 // Note: Expects "enc->palette_" to be set properly.
-static WebPEncodingError MapImageFromPalette(VP8LEncoder* const enc,
-                                             int in_place) {
-  WebPEncodingError err = VP8_ENC_OK;
+static int MapImageFromPalette(VP8LEncoder* const enc, int in_place) {
   const WebPPicture* const pic = enc->pic_;
   const int width = pic->width;
   const int height = pic->height;
@@ -1435,19 +1693,22 @@
     xbits = (palette_size <= 16) ? 1 : 0;
   }
 
-  err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
-  if (err != VP8_ENC_OK) return err;
-
-  err = ApplyPalette(src, src_stride,
+  if (!AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height)) {
+    return 0;
+  }
+  if (!ApplyPalette(src, src_stride,
                      enc->argb_, enc->current_width_,
-                     palette, palette_size, width, height, xbits);
+                     palette, palette_size, width, height, xbits, pic)) {
+    return 0;
+  }
   enc->argb_content_ = kEncoderPalette;
-  return err;
+  return 1;
 }
 
 // Save palette_[] to bitstream.
 static WebPEncodingError EncodePalette(VP8LBitWriter* const bw, int low_effort,
-                                       VP8LEncoder* const enc) {
+                                       VP8LEncoder* const enc,
+                                       int percent_range, int* const percent) {
   int i;
   uint32_t tmp_palette[MAX_PALETTE_SIZE];
   const int palette_size = enc->palette_size_;
@@ -1461,8 +1722,8 @@
   }
   tmp_palette[0] = palette[0];
   return EncodeImageNoHuffman(bw, tmp_palette, &enc->hash_chain_,
-                              &enc->refs_[0], &enc->refs_[1], palette_size, 1,
-                              20 /* quality */, low_effort);
+                              &enc->refs_[0], palette_size, 1, /*quality=*/20,
+                              low_effort, enc->pic_, percent_range, percent);
 }
 
 // -----------------------------------------------------------------------------
@@ -1488,7 +1749,7 @@
   if (enc != NULL) {
     int i;
     VP8LHashChainClear(&enc->hash_chain_);
-    for (i = 0; i < 3; ++i) VP8LBackwardRefsClear(&enc->refs_[i]);
+    for (i = 0; i < 4; ++i) VP8LBackwardRefsClear(&enc->refs_[i]);
     ClearTransformBuffer(enc);
     WebPSafeFree(enc);
   }
@@ -1506,7 +1767,6 @@
   CrunchConfig crunch_configs_[CRUNCH_CONFIGS_MAX];
   int num_crunch_configs_;
   int red_and_blue_always_zero_;
-  WebPEncodingError err_;
   WebPAuxStats* stats_;
 } StreamEncodeContext;
 
@@ -1523,7 +1783,6 @@
 #if !defined(WEBP_DISABLE_STATS)
   WebPAuxStats* const stats = params->stats_;
 #endif
-  WebPEncodingError err = VP8_ENC_OK;
   const int quality = (int)config->quality;
   const int low_effort = (config->method == 0);
 #if (WEBP_NEAR_LOSSLESS == 1)
@@ -1531,6 +1790,7 @@
 #endif
   const int height = picture->height;
   const size_t byte_position = VP8LBitWriterNumBytes(bw);
+  int percent = 2;  // for WebPProgressHook
 #if (WEBP_NEAR_LOSSLESS == 1)
   int use_near_lossless = 0;
 #endif
@@ -1538,24 +1798,28 @@
   int data_size = 0;
   int use_delta_palette = 0;
   int idx;
-  size_t best_size = 0;
+  size_t best_size = ~(size_t)0;
   VP8LBitWriter bw_init = *bw, bw_best;
   (void)data2;
 
   if (!VP8LBitWriterInit(&bw_best, 0) ||
       (num_crunch_configs > 1 && !VP8LBitWriterClone(bw, &bw_best))) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
   for (idx = 0; idx < num_crunch_configs; ++idx) {
     const int entropy_idx = crunch_configs[idx].entropy_idx_;
-    enc->use_palette_ = (entropy_idx == kPalette);
+    int remaining_percent = 97 / num_crunch_configs, percent_range;
+    enc->use_palette_ =
+        (entropy_idx == kPalette) || (entropy_idx == kPaletteAndSpatial);
     enc->use_subtract_green_ =
         (entropy_idx == kSubGreen) || (entropy_idx == kSpatialSubGreen);
-    enc->use_predict_ =
-        (entropy_idx == kSpatial) || (entropy_idx == kSpatialSubGreen);
-    if (low_effort) {
+    enc->use_predict_ = (entropy_idx == kSpatial) ||
+                        (entropy_idx == kSpatialSubGreen) ||
+                        (entropy_idx == kPaletteAndSpatial);
+    // When using a palette, R/B==0, hence no need to test for cross-color.
+    if (low_effort || enc->use_palette_) {
       enc->use_cross_color_ = 0;
     } else {
       enc->use_cross_color_ = red_and_blue_always_zero ? 0 : enc->use_predict_;
@@ -1570,11 +1834,10 @@
     use_near_lossless = (config->near_lossless < 100) && !enc->use_palette_ &&
                         !enc->use_predict_;
     if (use_near_lossless) {
-      err = AllocateTransformBuffer(enc, width, height);
-      if (err != VP8_ENC_OK) goto Error;
+      if (!AllocateTransformBuffer(enc, width, height)) goto Error;
       if ((enc->argb_content_ != kEncoderNearLossless) &&
           !VP8ApplyNearLossless(picture, config->near_lossless, enc->argb_)) {
-        err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+        WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
         goto Error;
       }
       enc->argb_content_ = kEncoderNearLossless;
@@ -1587,10 +1850,26 @@
 
     // Encode palette
     if (enc->use_palette_) {
-      err = EncodePalette(bw, low_effort, enc);
-      if (err != VP8_ENC_OK) goto Error;
-      err = MapImageFromPalette(enc, use_delta_palette);
-      if (err != VP8_ENC_OK) goto Error;
+      if (crunch_configs[idx].palette_sorting_type_ == kSortedDefault) {
+        // Nothing to do, we have already sorted the palette.
+        memcpy(enc->palette_, enc->palette_sorted_,
+               enc->palette_size_ * sizeof(*enc->palette_));
+      } else if (crunch_configs[idx].palette_sorting_type_ == kMinimizeDelta) {
+        PaletteSortMinimizeDeltas(enc->palette_sorted_, enc->palette_size_,
+                                  enc->palette_);
+      } else {
+        assert(crunch_configs[idx].palette_sorting_type_ == kModifiedZeng);
+        if (!PaletteSortModifiedZeng(enc->pic_, enc->palette_sorted_,
+                                      enc->palette_size_, enc->palette_)) {
+          goto Error;
+        }
+      }
+      percent_range = remaining_percent / 4;
+      if (!EncodePalette(bw, low_effort, enc, percent_range, &percent)) {
+        goto Error;
+      }
+      remaining_percent -= percent_range;
+      if (!MapImageFromPalette(enc, use_delta_palette)) goto Error;
       // If using a color cache, do not have it bigger than the number of
       // colors.
       if (use_cache && enc->palette_size_ < (1 << MAX_COLOR_CACHE_BITS)) {
@@ -1601,8 +1880,7 @@
       // In case image is not packed.
       if (enc->argb_content_ != kEncoderNearLossless &&
           enc->argb_content_ != kEncoderPalette) {
-        err = MakeInputImageCopy(enc);
-        if (err != VP8_ENC_OK) goto Error;
+        if (!MakeInputImageCopy(enc)) goto Error;
       }
 
       // -----------------------------------------------------------------------
@@ -1613,15 +1891,22 @@
       }
 
       if (enc->use_predict_) {
-        err = ApplyPredictFilter(enc, enc->current_width_, height, quality,
-                                 low_effort, enc->use_subtract_green_, bw);
-        if (err != VP8_ENC_OK) goto Error;
+        percent_range = remaining_percent / 3;
+        if (!ApplyPredictFilter(enc, enc->current_width_, height, quality,
+                                low_effort, enc->use_subtract_green_, bw,
+                                percent_range, &percent)) {
+          goto Error;
+        }
+        remaining_percent -= percent_range;
       }
 
       if (enc->use_cross_color_) {
-        err = ApplyCrossColorFilter(enc, enc->current_width_, height, quality,
-                                    low_effort, bw);
-        if (err != VP8_ENC_OK) goto Error;
+        percent_range = remaining_percent / 2;
+        if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality,
+                                   low_effort, bw, percent_range, &percent)) {
+          goto Error;
+        }
+        remaining_percent -= percent_range;
       }
     }
 
@@ -1629,15 +1914,16 @@
 
     // -------------------------------------------------------------------------
     // Encode and write the transformed image.
-    err = EncodeImageInternal(bw, enc->argb_, &enc->hash_chain_, enc->refs_,
-                              enc->current_width_, height, quality, low_effort,
-                              use_cache, &crunch_configs[idx],
-                              &enc->cache_bits_, enc->histo_bits_,
-                              byte_position, &hdr_size, &data_size);
-    if (err != VP8_ENC_OK) goto Error;
+    if (!EncodeImageInternal(
+            bw, enc->argb_, &enc->hash_chain_, enc->refs_, enc->current_width_,
+            height, quality, low_effort, use_cache, &crunch_configs[idx],
+            &enc->cache_bits_, enc->histo_bits_, byte_position, &hdr_size,
+            &data_size, picture, remaining_percent, &percent)) {
+      goto Error;
+    }
 
     // If we are better than what we already have.
-    if (idx == 0 || VP8LBitWriterNumBytes(bw) < best_size) {
+    if (VP8LBitWriterNumBytes(bw) < best_size) {
       best_size = VP8LBitWriterNumBytes(bw);
       // Store the BitWriter.
       VP8LBitWriterSwap(bw, &bw_best);
@@ -1664,18 +1950,15 @@
   }
   VP8LBitWriterSwap(&bw_best, bw);
 
-Error:
+ Error:
   VP8LBitWriterWipeOut(&bw_best);
-  params->err_ = err;
   // The hook should return false in case of error.
-  return (err == VP8_ENC_OK);
+  return (params->picture_->error_code == VP8_ENC_OK);
 }
 
-WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
-                                   const WebPPicture* const picture,
-                                   VP8LBitWriter* const bw_main,
-                                   int use_cache) {
-  WebPEncodingError err = VP8_ENC_OK;
+int VP8LEncodeStream(const WebPConfig* const config,
+                     const WebPPicture* const picture,
+                     VP8LBitWriter* const bw_main, int use_cache) {
   VP8LEncoder* const enc_main = VP8LEncoderNew(config, picture);
   VP8LEncoder* enc_side = NULL;
   CrunchConfig crunch_configs[CRUNCH_CONFIGS_MAX];
@@ -1687,15 +1970,23 @@
   // The main thread uses picture->stats, the side thread uses stats_side.
   WebPAuxStats stats_side;
   VP8LBitWriter bw_side;
+  WebPPicture picture_side;
   const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface();
   int ok_main;
 
+  if (enc_main == NULL || !VP8LBitWriterInit(&bw_side, 0)) {
+    VP8LEncoderDelete(enc_main);
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+
+  // Avoid "garbage value" error from Clang's static analysis tool.
+  WebPPictureInit(&picture_side);
+
   // Analyze image (entropy, num_palettes etc)
-  if (enc_main == NULL ||
-      !EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
+  if (!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
                       &red_and_blue_always_zero) ||
-      !EncoderInit(enc_main) || !VP8LBitWriterInit(&bw_side, 0)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      !EncoderInit(enc_main)) {
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
@@ -1724,25 +2015,32 @@
       StreamEncodeContext* const param =
           (idx == 0) ? &params_main : &params_side;
       param->config_ = config;
-      param->picture_ = picture;
       param->use_cache_ = use_cache;
       param->red_and_blue_always_zero_ = red_and_blue_always_zero;
       if (idx == 0) {
+        param->picture_ = picture;
         param->stats_ = picture->stats;
         param->bw_ = bw_main;
         param->enc_ = enc_main;
       } else {
+        // Create a side picture (error_code is not thread-safe).
+        if (!WebPPictureView(picture, /*left=*/0, /*top=*/0, picture->width,
+                             picture->height, &picture_side)) {
+          assert(0);
+        }
+        picture_side.progress_hook = NULL;  // Progress hook is not thread-safe.
+        param->picture_ = &picture_side;  // No need to free a view afterwards.
         param->stats_ = (picture->stats == NULL) ? NULL : &stats_side;
         // Create a side bit writer.
         if (!VP8LBitWriterClone(bw_main, &bw_side)) {
-          err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+          WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
           goto Error;
         }
         param->bw_ = &bw_side;
         // Create a side encoder.
-        enc_side = VP8LEncoderNew(config, picture);
+        enc_side = VP8LEncoderNew(config, &picture_side);
         if (enc_side == NULL || !EncoderInit(enc_side)) {
-          err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+          WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
           goto Error;
         }
         // Copy the values that were computed for the main encoder.
@@ -1751,6 +2049,8 @@
         enc_side->palette_size_ = enc_main->palette_size_;
         memcpy(enc_side->palette_, enc_main->palette_,
                sizeof(enc_main->palette_));
+        memcpy(enc_side->palette_sorted_, enc_main->palette_sorted_,
+               sizeof(enc_main->palette_sorted_));
         param->enc_ = enc_side;
       }
       // Create the workers.
@@ -1764,7 +2064,7 @@
   // Start the second thread if needed.
   if (num_crunch_configs_side != 0) {
     if (!worker_interface->Reset(&worker_side)) {
-      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
       goto Error;
     }
 #if !defined(WEBP_DISABLE_STATS)
@@ -1774,8 +2074,6 @@
       memcpy(&stats_side, picture->stats, sizeof(stats_side));
     }
 #endif
-    // This line is only useful to remove a Clang static analyzer warning.
-    params_side.err_ = VP8_ENC_OK;
     worker_interface->Launch(&worker_side);
   }
   // Execute the main thread.
@@ -1787,7 +2085,10 @@
     const int ok_side = worker_interface->Sync(&worker_side);
     worker_interface->End(&worker_side);
     if (!ok_main || !ok_side) {
-      err = ok_main ? params_side.err_ : params_main.err_;
+      if (picture->error_code == VP8_ENC_OK) {
+        assert(picture_side.error_code != VP8_ENC_OK);
+        WebPEncodingSetError(picture, picture_side.error_code);
+      }
       goto Error;
     }
     if (VP8LBitWriterNumBytes(&bw_side) < VP8LBitWriterNumBytes(bw_main)) {
@@ -1798,22 +2099,17 @@
       }
 #endif
     }
-  } else {
-    if (!ok_main) {
-      err = params_main.err_;
-      goto Error;
-    }
   }
 
-Error:
+ Error:
   VP8LBitWriterWipeOut(&bw_side);
   VP8LEncoderDelete(enc_main);
   VP8LEncoderDelete(enc_side);
-  return err;
+  return (picture->error_code == VP8_ENC_OK);
 }
 
 #undef CRUNCH_CONFIGS_MAX
-#undef CRUNCH_CONFIGS_LZ77_MAX
+#undef CRUNCH_SUBCONFIGS_MAX
 
 int VP8LEncodeImage(const WebPConfig* const config,
                     const WebPPicture* const picture) {
@@ -1822,15 +2118,12 @@
   size_t coded_size;
   int percent = 0;
   int initial_size;
-  WebPEncodingError err = VP8_ENC_OK;
   VP8LBitWriter bw;
 
   if (picture == NULL) return 0;
 
   if (config == NULL || picture->argb == NULL) {
-    err = VP8_ENC_ERROR_NULL_PARAMETER;
-    WebPEncodingSetError(picture, err);
-    return 0;
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
   }
 
   width = picture->width;
@@ -1840,13 +2133,13 @@
   initial_size = (config->image_hint == WEBP_HINT_GRAPH) ?
       width * height : width * height * 2;
   if (!VP8LBitWriterInit(&bw, initial_size)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
   if (!WebPReportProgress(picture, 1, &percent)) {
  UserAbort:
-    err = VP8_ENC_ERROR_USER_ABORT;
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_USER_ABORT);
     goto Error;
   }
   // Reset stats (for pure lossless coding)
@@ -1862,28 +2155,26 @@
 
   // Write image size.
   if (!WriteImageSize(picture, &bw)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
   has_alpha = WebPPictureHasTransparency(picture);
   // Write the non-trivial Alpha flag and lossless version.
   if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
     goto Error;
   }
 
-  if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
+  if (!WebPReportProgress(picture, 2, &percent)) goto UserAbort;
 
   // Encode main image stream.
-  err = VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/);
-  if (err != VP8_ENC_OK) goto Error;
+  if (!VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/)) goto Error;
 
-  if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
+  if (!WebPReportProgress(picture, 99, &percent)) goto UserAbort;
 
   // Finish the RIFF chunk.
-  err = WriteImage(picture, &bw, &coded_size);
-  if (err != VP8_ENC_OK) goto Error;
+  if (!WriteImage(picture, &bw, &coded_size)) goto Error;
 
   if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
 
@@ -1902,13 +2193,11 @@
   }
 
  Error:
-  if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-  VP8LBitWriterWipeOut(&bw);
-  if (err != VP8_ENC_OK) {
-    WebPEncodingSetError(picture, err);
-    return 0;
+  if (bw.error_) {
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
   }
-  return 1;
+  VP8LBitWriterWipeOut(&bw);
+  return (picture->error_code == VP8_ENC_OK);
 }
 
 //------------------------------------------------------------------------------
diff --git a/third_party/libwebp/src/enc/vp8li_enc.h b/third_party/libwebp/src/enc/vp8li_enc.h
index 298a4a0..3d35e16 100644
--- a/third_party/libwebp/src/enc/vp8li_enc.h
+++ b/third_party/libwebp/src/enc/vp8li_enc.h
@@ -69,9 +69,11 @@
   int use_palette_;
   int palette_size_;
   uint32_t palette_[MAX_PALETTE_SIZE];
+  // Sorted version of palette_ for cache purposes.
+  uint32_t palette_sorted_[MAX_PALETTE_SIZE];
 
   // Some 'scratch' (potentially large) objects.
-  struct VP8LBackwardRefs refs_[3];  // Backward Refs array for temporaries.
+  struct VP8LBackwardRefs refs_[4];  // Backward Refs array for temporaries.
   VP8LHashChain hash_chain_;         // HashChain data for constructing
                                      // backward references.
 } VP8LEncoder;
@@ -87,9 +89,10 @@
 
 // Encodes the main image stream using the supplied bit writer.
 // If 'use_cache' is false, disables the use of color cache.
-WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
-                                   const WebPPicture* const picture,
-                                   VP8LBitWriter* const bw, int use_cache);
+// Returns false in case of error (stored in picture->error_code).
+int VP8LEncodeStream(const WebPConfig* const config,
+                     const WebPPicture* const picture, VP8LBitWriter* const bw,
+                     int use_cache);
 
 #if (WEBP_NEAR_LOSSLESS == 1)
 // in near_lossless.c
@@ -101,13 +104,18 @@
 //------------------------------------------------------------------------------
 // Image transforms in predictor.c.
 
-void VP8LResidualImage(int width, int height, int bits, int low_effort,
-                       uint32_t* const argb, uint32_t* const argb_scratch,
-                       uint32_t* const image, int near_lossless, int exact,
-                       int used_subtract_green);
+// pic and percent are for progress.
+// Returns false in case of error (stored in pic->error_code).
+int VP8LResidualImage(int width, int height, int bits, int low_effort,
+                      uint32_t* const argb, uint32_t* const argb_scratch,
+                      uint32_t* const image, int near_lossless, int exact,
+                      int used_subtract_green, const WebPPicture* const pic,
+                      int percent_range, int* const percent);
 
-void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
-                             uint32_t* const argb, uint32_t* image);
+int VP8LColorSpaceTransform(int width, int height, int bits, int quality,
+                            uint32_t* const argb, uint32_t* image,
+                            const WebPPicture* const pic, int percent_range,
+                            int* const percent);
 
 //------------------------------------------------------------------------------
 
@@ -115,4 +123,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_ENC_VP8LI_ENC_H_ */
+#endif  // WEBP_ENC_VP8LI_ENC_H_
diff --git a/third_party/libwebp/src/enc/webp_enc.c b/third_party/libwebp/src/enc/webp_enc.c
index ead0092..58df3e8 100644
--- a/third_party/libwebp/src/enc/webp_enc.c
+++ b/third_party/libwebp/src/enc/webp_enc.c
@@ -313,7 +313,10 @@
                          WebPEncodingError error) {
   assert((int)error < VP8_ENC_ERROR_LAST);
   assert((int)error >= VP8_ENC_OK);
-  ((WebPPicture*)pic)->error_code = error;
+  // The oldest error reported takes precedence over the new one.
+  if (pic->error_code == VP8_ENC_OK) {
+    ((WebPPicture*)pic)->error_code = error;
+  }
   return 0;
 }
 
@@ -323,8 +326,7 @@
     *percent_store = percent;
     if (pic->progress_hook && !pic->progress_hook(percent, pic)) {
       // user abort requested
-      WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
-      return 0;
+      return WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
     }
   }
   return 1;  // ok
@@ -335,16 +337,14 @@
   int ok = 0;
   if (pic == NULL) return 0;
 
-  WebPEncodingSetError(pic, VP8_ENC_OK);  // all ok so far
+  pic->error_code = VP8_ENC_OK;  // all ok so far
   if (config == NULL) {  // bad params
     return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
   }
   if (!WebPValidateConfig(config)) {
     return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
   }
-  if (pic->width <= 0 || pic->height <= 0) {
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
-  }
+  if (!WebPValidatePicture(pic)) return 0;
   if (pic->width > WEBP_MAX_DIMENSION || pic->height > WEBP_MAX_DIMENSION) {
     return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
   }
@@ -406,7 +406,7 @@
     }
 
     if (!config->exact) {
-      WebPCleanupTransparentAreaLossless(pic);
+      WebPReplaceTransparentPixels(pic, 0x000000);
     }
 
     ok = VP8LEncodeImage(config, pic);  // Sets pic->error in case of problem.
diff --git a/third_party/libwebp/src/libwebp.pc.in b/third_party/libwebp/src/libwebp.pc.in
index 733bb6d..783090e 100644
--- a/third_party/libwebp/src/libwebp.pc.in
+++ b/third_party/libwebp/src/libwebp.pc.in
@@ -6,6 +6,7 @@
 Name: libwebp
 Description: Library for the WebP graphics format
 Version: @PACKAGE_VERSION@
+Requires.private: libsharpyuv
 Cflags: -I${includedir}
-Libs: -L${libdir} -lwebp
+Libs: -L${libdir} -l@webp_libname_prefix@webp
 Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/third_party/libwebp/src/libwebp.rc b/third_party/libwebp/src/libwebp.rc
index d554124..5ce33db 100644
--- a/third_party/libwebp/src/libwebp.rc
+++ b/third_party/libwebp/src/libwebp.rc
@@ -6,8 +6,8 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,0
- PRODUCTVERSION 1,0,0,0
+ FILEVERSION 1,0,3,1
+ PRODUCTVERSION 1,0,3,1
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -24,12 +24,12 @@
         BEGIN
             VALUE "CompanyName", "Google, Inc."
             VALUE "FileDescription", "libwebp DLL"
-            VALUE "FileVersion", "1.0.0"
+            VALUE "FileVersion", "1.3.1"
             VALUE "InternalName", "libwebp.dll"
-            VALUE "LegalCopyright", "Copyright (C) 2018"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
             VALUE "OriginalFilename", "libwebp.dll"
             VALUE "ProductName", "WebP Image Codec"
-            VALUE "ProductVersion", "1.0.0"
+            VALUE "ProductVersion", "1.3.1"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/third_party/libwebp/src/libwebpdecoder.pc.in b/third_party/libwebp/src/libwebpdecoder.pc.in
index 3ef647a..134de0e 100644
--- a/third_party/libwebp/src/libwebpdecoder.pc.in
+++ b/third_party/libwebp/src/libwebpdecoder.pc.in
@@ -7,5 +7,5 @@
 Description: Library for the WebP graphics format (decode only)
 Version: @PACKAGE_VERSION@
 Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpdecoder
+Libs: -L${libdir} -l@webp_libname_prefix@webpdecoder
 Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/third_party/libwebp/src/libwebpdecoder.rc b/third_party/libwebp/src/libwebpdecoder.rc
index 8a2def4..1a5a253 100644
--- a/third_party/libwebp/src/libwebpdecoder.rc
+++ b/third_party/libwebp/src/libwebpdecoder.rc
@@ -6,8 +6,8 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,0
- PRODUCTVERSION 1,0,0,0
+ FILEVERSION 1,0,3,1
+ PRODUCTVERSION 1,0,3,1
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -24,12 +24,12 @@
         BEGIN
             VALUE "CompanyName", "Google, Inc."
             VALUE "FileDescription", "libwebpdecoder DLL"
-            VALUE "FileVersion", "1.0.0"
+            VALUE "FileVersion", "1.3.1"
             VALUE "InternalName", "libwebpdecoder.dll"
-            VALUE "LegalCopyright", "Copyright (C) 2018"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
             VALUE "OriginalFilename", "libwebpdecoder.dll"
             VALUE "ProductName", "WebP Image Decoder"
-            VALUE "ProductVersion", "1.0.0"
+            VALUE "ProductVersion", "1.3.1"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/third_party/libwebp/src/mux/Makefile.am b/third_party/libwebp/src/mux/Makefile.am
index 447bcce..71ec3aa 100644
--- a/third_party/libwebp/src/mux/Makefile.am
+++ b/third_party/libwebp/src/mux/Makefile.am
@@ -17,6 +17,6 @@
 noinst_HEADERS += ../webp/format_constants.h
 
 libwebpmux_la_LIBADD = ../libwebp.la
-libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:2:0 -lm
+libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:12:0 -lm
 libwebpmuxincludedir = $(includedir)/webp
 pkgconfig_DATA = libwebpmux.pc
diff --git a/third_party/libwebp/src/mux/anim_encode.c b/third_party/libwebp/src/mux/anim_encode.c
index 7be9906..7078d9a 100644
--- a/third_party/libwebp/src/mux/anim_encode.c
+++ b/third_party/libwebp/src/mux/anim_encode.c
@@ -248,9 +248,6 @@
 
   enc = (WebPAnimEncoder*)WebPSafeCalloc(1, sizeof(*enc));
   if (enc == NULL) return NULL;
-  // sanity inits, so we can call WebPAnimEncoderDelete():
-  enc->encoded_frames_ = NULL;
-  enc->mux_ = NULL;
   MarkNoError(enc);
 
   // Dimensions and options.
@@ -421,7 +418,7 @@
   const int max_allowed_diff_lossy = QualityToMaxDiff(quality);
   const int max_allowed_diff = is_lossless ? 0 : max_allowed_diff_lossy;
 
-  // Sanity checks.
+  // Assumption/correctness checks.
   assert(src->width == dst->width && src->height == dst->height);
   assert(rect->x_offset_ + rect->width_ <= dst->width);
   assert(rect->y_offset_ + rect->height_ <= dst->height);
@@ -949,7 +946,8 @@
   int new_duration;
 
   assert(enc->count_ >= 1);
-  assert(prev_enc_frame->sub_frame_.duration ==
+  assert(!prev_enc_frame->is_key_frame_ ||
+         prev_enc_frame->sub_frame_.duration ==
          prev_enc_frame->key_frame_.duration);
   assert(prev_enc_frame->sub_frame_.duration ==
          (prev_enc_frame->sub_frame_.duration & (MAX_DURATION - 1)));
@@ -966,7 +964,7 @@
       0x10, 0x88, 0x88, 0x08
     };
     const WebPData lossless_1x1 = {
-        lossless_1x1_bytes, sizeof(lossless_1x1_bytes)
+      lossless_1x1_bytes, sizeof(lossless_1x1_bytes)
     };
     const uint8_t lossy_1x1_bytes[] = {
       0x52, 0x49, 0x46, 0x46, 0x40, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50,
@@ -1358,6 +1356,12 @@
     if (!IncreasePreviousDuration(enc, (int)prev_frame_duration)) {
       return 0;
     }
+    // IncreasePreviousDuration() may add a frame to avoid exceeding
+    // MAX_DURATION which could cause CacheFrame() to over read encoded_frames_
+    // before the next flush.
+    if (enc->count_ == enc->size_ && !FlushFrames(enc)) {
+      return 0;
+    }
   } else {
     enc->first_timestamp_ = timestamp;
   }
diff --git a/third_party/libwebp/src/mux/animi.h b/third_party/libwebp/src/mux/animi.h
index 8889953..34c45ba 100644
--- a/third_party/libwebp/src/mux/animi.h
+++ b/third_party/libwebp/src/mux/animi.h
@@ -40,4 +40,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_MUX_ANIMI_H_ */
+#endif  // WEBP_MUX_ANIMI_H_
diff --git a/third_party/libwebp/src/mux/libwebpmux.pc.in b/third_party/libwebp/src/mux/libwebpmux.pc.in
index a96fac7..c770daa 100644
--- a/third_party/libwebp/src/mux/libwebpmux.pc.in
+++ b/third_party/libwebp/src/mux/libwebpmux.pc.in
@@ -6,7 +6,7 @@
 Name: libwebpmux
 Description: Library for manipulating the WebP graphics format container
 Version: @PACKAGE_VERSION@
-Requires: libwebp >= 0.2.0
+Requires.private: libwebp >= 0.2.0
 Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpmux
+Libs: -L${libdir} -l@webp_libname_prefix@webpmux
 Libs.private: -lm
diff --git a/third_party/libwebp/src/mux/libwebpmux.rc b/third_party/libwebp/src/mux/libwebpmux.rc
index 8c7d5f6..75afcaa 100644
--- a/third_party/libwebp/src/mux/libwebpmux.rc
+++ b/third_party/libwebp/src/mux/libwebpmux.rc
@@ -6,8 +6,8 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,0
- PRODUCTVERSION 1,0,0,0
+ FILEVERSION 1,0,3,1
+ PRODUCTVERSION 1,0,3,1
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -24,12 +24,12 @@
         BEGIN
             VALUE "CompanyName", "Google, Inc."
             VALUE "FileDescription", "libwebpmux DLL"
-            VALUE "FileVersion", "1.0.0"
+            VALUE "FileVersion", "1.3.1"
             VALUE "InternalName", "libwebpmux.dll"
-            VALUE "LegalCopyright", "Copyright (C) 2018"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
             VALUE "OriginalFilename", "libwebpmux.dll"
             VALUE "ProductName", "WebP Image Muxer"
-            VALUE "ProductVersion", "1.0.0"
+            VALUE "ProductVersion", "1.3.1"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/third_party/libwebp/src/mux/muxedit.c b/third_party/libwebp/src/mux/muxedit.c
index 7a027b3..63e71a0 100644
--- a/third_party/libwebp/src/mux/muxedit.c
+++ b/third_party/libwebp/src/mux/muxedit.c
@@ -69,12 +69,13 @@
   if (idx == (INDEX)) {                                                        \
     err = ChunkAssignData(&chunk, data, copy_data, tag);                       \
     if (err == WEBP_MUX_OK) {                                                  \
-      err = ChunkSetNth(&chunk, (LIST), nth);                                  \
+      err = ChunkSetHead(&chunk, (LIST));                                      \
+      if (err != WEBP_MUX_OK) ChunkRelease(&chunk);                            \
     }                                                                          \
     return err;                                                                \
   }
 
-static WebPMuxError MuxSet(WebPMux* const mux, uint32_t tag, uint32_t nth,
+static WebPMuxError MuxSet(WebPMux* const mux, uint32_t tag,
                            const WebPData* const data, int copy_data) {
   WebPChunk chunk;
   WebPMuxError err = WEBP_MUX_NOT_FOUND;
@@ -190,7 +191,7 @@
   if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
 
   // Add the given chunk.
-  return MuxSet(mux, tag, 1, chunk_data, copy_data);
+  return MuxSet(mux, tag, chunk_data, copy_data);
 }
 
 // Creates a chunk from given 'data' and sets it as 1st chunk in 'chunk_list'.
@@ -202,7 +203,7 @@
   ChunkInit(&chunk);
   err = ChunkAssignData(&chunk, data, copy_data, tag);
   if (err != WEBP_MUX_OK) goto Err;
-  err = ChunkSetNth(&chunk, chunk_list, 1);
+  err = ChunkSetHead(&chunk, chunk_list);
   if (err != WEBP_MUX_OK) goto Err;
   return WEBP_MUX_OK;
  Err:
@@ -235,7 +236,6 @@
   WebPMuxImage wpi;
   WebPMuxError err;
 
-  // Sanity checks.
   if (mux == NULL || bitstream == NULL || bitstream->bytes == NULL ||
       bitstream->size > MAX_CHUNK_PAYLOAD) {
     return WEBP_MUX_INVALID_ARGUMENT;
@@ -266,14 +266,13 @@
                               int copy_data) {
   WebPMuxImage wpi;
   WebPMuxError err;
-  const WebPData* const bitstream = &info->bitstream;
 
-  // Sanity checks.
   if (mux == NULL || info == NULL) return WEBP_MUX_INVALID_ARGUMENT;
 
   if (info->id != WEBP_CHUNK_ANMF) return WEBP_MUX_INVALID_ARGUMENT;
 
-  if (bitstream->bytes == NULL || bitstream->size > MAX_CHUNK_PAYLOAD) {
+  if (info->bitstream.bytes == NULL ||
+      info->bitstream.size > MAX_CHUNK_PAYLOAD) {
     return WEBP_MUX_INVALID_ARGUMENT;
   }
 
@@ -287,7 +286,7 @@
   }
 
   MuxImageInit(&wpi);
-  err = SetAlphaAndImageChunks(bitstream, copy_data, &wpi);
+  err = SetAlphaAndImageChunks(&info->bitstream, copy_data, &wpi);
   if (err != WEBP_MUX_OK) goto Err;
   assert(wpi.img_ != NULL);  // As SetAlphaAndImageChunks() was successful.
 
@@ -342,7 +341,7 @@
   // Set the animation parameters.
   PutLE32(data, params->bgcolor);
   PutLE16(data + 4, params->loop_count);
-  return MuxSet(mux, kChunks[IDX_ANIM].tag, 1, &anim, 1);
+  return MuxSet(mux, kChunks[IDX_ANIM].tag, &anim, 1);
 }
 
 WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux,
@@ -540,7 +539,7 @@
   PutLE24(data + 4, width - 1);   // canvas width.
   PutLE24(data + 7, height - 1);  // canvas height.
 
-  return MuxSet(mux, kChunks[IDX_VP8X].tag, 1, &vp8x, 1);
+  return MuxSet(mux, kChunks[IDX_VP8X].tag, &vp8x, 1);
 }
 
 // Cleans up 'mux' by removing any unnecessary chunks.
diff --git a/third_party/libwebp/src/mux/muxi.h b/third_party/libwebp/src/mux/muxi.h
index f1e1e97..fc44d6f 100644
--- a/third_party/libwebp/src/mux/muxi.h
+++ b/third_party/libwebp/src/mux/muxi.h
@@ -14,6 +14,7 @@
 #ifndef WEBP_MUX_MUXI_H_
 #define WEBP_MUX_MUXI_H_
 
+#include <assert.h>
 #include <stdlib.h>
 #include "src/dec/vp8i_dec.h"
 #include "src/dec/vp8li_dec.h"
@@ -27,8 +28,8 @@
 // Defines and constants.
 
 #define MUX_MAJ_VERSION 1
-#define MUX_MIN_VERSION 0
-#define MUX_REV_VERSION 0
+#define MUX_MIN_VERSION 3
+#define MUX_REV_VERSION 1
 
 // Chunk object.
 typedef struct WebPChunk WebPChunk;
@@ -126,11 +127,14 @@
 WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
                              int copy_data, uint32_t tag);
 
-// Sets 'chunk' at nth position in the 'chunk_list'.
-// nth = 0 has the special meaning "last of the list".
+// Sets 'chunk' as the only element in 'chunk_list' if it is empty.
 // On success ownership is transferred from 'chunk' to the 'chunk_list'.
-WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
-                         uint32_t nth);
+WebPMuxError ChunkSetHead(WebPChunk* const chunk, WebPChunk** const chunk_list);
+// Sets 'chunk' at last position in the 'chunk_list'.
+// On success ownership is transferred from 'chunk' to the 'chunk_list'.
+// *chunk_list also points towards the last valid element of the initial
+// *chunk_list.
+WebPMuxError ChunkAppend(WebPChunk* const chunk, WebPChunk*** const chunk_list);
 
 // Releases chunk and returns chunk->next_.
 WebPChunk* ChunkRelease(WebPChunk* const chunk);
@@ -143,13 +147,13 @@
 
 // Returns size of the chunk including chunk header and padding byte (if any).
 static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
+  assert(chunk_size <= MAX_CHUNK_PAYLOAD);
   return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
 }
 
 // Size of a chunk including header and padding.
 static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
   const size_t data_size = chunk->data_.size;
-  SB_DCHECK(data_size < MAX_CHUNK_PAYLOAD);
   return SizeWithPadding(data_size);
 }
 
@@ -227,4 +231,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_MUX_MUXI_H_ */
+#endif  // WEBP_MUX_MUXI_H_
diff --git a/third_party/libwebp/src/mux/muxinternal.c b/third_party/libwebp/src/mux/muxinternal.c
index 941222c..9fc41e0 100644
--- a/third_party/libwebp/src/mux/muxinternal.c
+++ b/third_party/libwebp/src/mux/muxinternal.c
@@ -116,27 +116,6 @@
   return ((nth > 0) && (iter > 0)) ? NULL : first;
 }
 
-// Outputs a pointer to 'prev_chunk->next_',
-//   where 'prev_chunk' is the pointer to the chunk at position (nth - 1).
-// Returns true if nth chunk was found.
-static int ChunkSearchListToSet(WebPChunk** chunk_list, uint32_t nth,
-                                WebPChunk*** const location) {
-  uint32_t count = 0;
-  assert(chunk_list != NULL);
-  *location = chunk_list;
-
-  while (*chunk_list != NULL) {
-    WebPChunk* const cur_chunk = *chunk_list;
-    ++count;
-    if (count == nth) return 1;  // Found.
-    chunk_list = &cur_chunk->next_;
-    *location = chunk_list;
-  }
-
-  // *chunk_list is ok to be NULL if adding at last location.
-  return (nth == 0 || (count == nth - 1)) ? 1 : 0;
-}
-
 //------------------------------------------------------------------------------
 // Chunk writer methods.
 
@@ -161,11 +140,12 @@
   return WEBP_MUX_OK;
 }
 
-WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
-                         uint32_t nth) {
+WebPMuxError ChunkSetHead(WebPChunk* const chunk,
+                          WebPChunk** const chunk_list) {
   WebPChunk* new_chunk;
 
-  if (!ChunkSearchListToSet(chunk_list, nth, &chunk_list)) {
+  assert(chunk_list != NULL);
+  if (*chunk_list != NULL) {
     return WEBP_MUX_NOT_FOUND;
   }
 
@@ -173,11 +153,27 @@
   if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
   *new_chunk = *chunk;
   chunk->owner_ = 0;
-  new_chunk->next_ = *chunk_list;
+  new_chunk->next_ = NULL;
   *chunk_list = new_chunk;
   return WEBP_MUX_OK;
 }
 
+WebPMuxError ChunkAppend(WebPChunk* const chunk,
+                         WebPChunk*** const chunk_list) {
+  WebPMuxError err;
+  assert(chunk_list != NULL && *chunk_list != NULL);
+
+  if (**chunk_list == NULL) {
+    err = ChunkSetHead(chunk, *chunk_list);
+  } else {
+    WebPChunk* last_chunk = **chunk_list;
+    while (last_chunk->next_ != NULL) last_chunk = last_chunk->next_;
+    err = ChunkSetHead(chunk, &last_chunk->next_);
+    if (err == WEBP_MUX_OK) *chunk_list = &last_chunk->next_;
+  }
+  return err;
+}
+
 //------------------------------------------------------------------------------
 // Chunk deletion method(s).
 
@@ -237,9 +233,11 @@
 WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
   WebPMuxImage* next;
   if (wpi == NULL) return NULL;
-  ChunkDelete(wpi->header_);
-  ChunkDelete(wpi->alpha_);
-  ChunkDelete(wpi->img_);
+  // There should be at most one chunk of header_, alpha_, img_ but we call
+  // ChunkListDelete to be safe
+  ChunkListDelete(&wpi->header_);
+  ChunkListDelete(&wpi->alpha_);
+  ChunkListDelete(&wpi->img_);
   ChunkListDelete(&wpi->unknown_);
 
   next = wpi->next_;
diff --git a/third_party/libwebp/src/mux/muxread.c b/third_party/libwebp/src/mux/muxread.c
index 0b55286..9862ec6 100644
--- a/third_party/libwebp/src/mux/muxread.c
+++ b/third_party/libwebp/src/mux/muxread.c
@@ -56,9 +56,10 @@
   uint32_t chunk_size;
   WebPData chunk_data;
 
-  // Sanity checks.
+  // Correctness checks.
   if (data_size < CHUNK_HEADER_SIZE) return WEBP_MUX_NOT_ENOUGH_DATA;
   chunk_size = GetLE32(data + TAG_SIZE);
+  if (chunk_size > MAX_CHUNK_PAYLOAD) return WEBP_MUX_BAD_DATA;
 
   {
     const size_t chunk_disk_size = SizeWithPadding(chunk_size);
@@ -99,9 +100,10 @@
                          WebPMuxImage* const wpi) {
   const uint8_t* bytes = chunk->data_.bytes;
   size_t size = chunk->data_.size;
-  const uint8_t* const last = bytes + size;
+  const uint8_t* const last = (bytes == NULL) ? NULL : bytes + size;
   WebPChunk subchunk;
   size_t subchunk_size;
+  WebPChunk** unknown_chunk_list = &wpi->unknown_;
   ChunkInit(&subchunk);
 
   assert(chunk->tag_ == kChunks[IDX_ANMF].tag);
@@ -114,9 +116,12 @@
     // Each of ANMF chunk contain a header at the beginning. So, its size should
     // be at least 'hdr_size'.
     if (size < hdr_size) goto Fail;
-    ChunkAssignData(&subchunk, &temp, copy_data, chunk->tag_);
+    if (ChunkAssignData(&subchunk, &temp, copy_data,
+                        chunk->tag_) != WEBP_MUX_OK) {
+      goto Fail;
+    }
   }
-  ChunkSetNth(&subchunk, &wpi->header_, 1);
+  if (ChunkSetHead(&subchunk, &wpi->header_) != WEBP_MUX_OK) goto Fail;
   wpi->is_partial_ = 1;  // Waiting for ALPH and/or VP8/VP8L chunks.
 
   // Rest of the chunks.
@@ -133,22 +138,26 @@
     switch (ChunkGetIdFromTag(subchunk.tag_)) {
       case WEBP_CHUNK_ALPHA:
         if (wpi->alpha_ != NULL) goto Fail;  // Consecutive ALPH chunks.
-        if (ChunkSetNth(&subchunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Fail;
+        if (ChunkSetHead(&subchunk, &wpi->alpha_) != WEBP_MUX_OK) goto Fail;
         wpi->is_partial_ = 1;  // Waiting for a VP8 chunk.
         break;
       case WEBP_CHUNK_IMAGE:
-        if (ChunkSetNth(&subchunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Fail;
+        if (wpi->img_ != NULL) goto Fail;  // Only 1 image chunk allowed.
+        if (ChunkSetHead(&subchunk, &wpi->img_) != WEBP_MUX_OK) goto Fail;
         if (!MuxImageFinalize(wpi)) goto Fail;
         wpi->is_partial_ = 0;  // wpi is completely filled.
         break;
       case WEBP_CHUNK_UNKNOWN:
-        if (wpi->is_partial_) goto Fail;  // Encountered an unknown chunk
-                                          // before some image chunks.
-        if (ChunkSetNth(&subchunk, &wpi->unknown_, 0) != WEBP_MUX_OK) goto Fail;
+        if (wpi->is_partial_) {
+          goto Fail;  // Encountered an unknown chunk
+                      // before some image chunks.
+        }
+        if (ChunkAppend(&subchunk, &unknown_chunk_list) != WEBP_MUX_OK) {
+          goto Fail;
+        }
         break;
       default:
         goto Fail;
-        break;
     }
     subchunk_size = ChunkDiskSize(&subchunk);
     bytes += subchunk_size;
@@ -175,9 +184,11 @@
   const uint8_t* data;
   size_t size;
   WebPChunk chunk;
+  // Stores the end of the chunk lists so that it is faster to append data to
+  // their ends.
+  WebPChunk** chunk_list_ends[WEBP_CHUNK_NIL + 1] = { NULL };
   ChunkInit(&chunk);
 
-  // Sanity checks.
   if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
     return NULL;  // version mismatch
   }
@@ -187,7 +198,7 @@
   size = bitstream->size;
 
   if (data == NULL) return NULL;
-  if (size < RIFF_HEADER_SIZE) return NULL;
+  if (size < RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE) return NULL;
   if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') ||
       GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) {
     return NULL;
@@ -196,8 +207,6 @@
   mux = WebPMuxNew();
   if (mux == NULL) return NULL;
 
-  if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err;
-
   tag = GetLE32(data + RIFF_HEADER_SIZE);
   if (tag != kChunks[IDX_VP8].tag &&
       tag != kChunks[IDX_VP8L].tag &&
@@ -205,13 +214,17 @@
     goto Err;  // First chunk should be VP8, VP8L or VP8X.
   }
 
-  riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
-  if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) {
-    goto Err;
-  } else {
-    if (riff_size < size) {  // Redundant data after last chunk.
-      size = riff_size;  // To make sure we don't read any data beyond mux_size.
-    }
+  riff_size = GetLE32(data + TAG_SIZE);
+  if (riff_size > MAX_CHUNK_PAYLOAD) goto Err;
+
+  // Note this padding is historical and differs from demux.c which does not
+  // pad the file size.
+  riff_size = SizeWithPadding(riff_size);
+  if (riff_size < CHUNK_HEADER_SIZE) goto Err;
+  if (riff_size > size) goto Err;
+  // There's no point in reading past the end of the RIFF chunk.
+  if (size > riff_size + CHUNK_HEADER_SIZE) {
+    size = riff_size + CHUNK_HEADER_SIZE;
   }
 
   end = data + size;
@@ -226,7 +239,6 @@
   while (data != end) {
     size_t data_size;
     WebPChunkId id;
-    WebPChunk** chunk_list;
     if (ChunkVerifyAndAssign(&chunk, data, size, riff_size,
                              copy_data) != WEBP_MUX_OK) {
       goto Err;
@@ -236,11 +248,11 @@
     switch (id) {
       case WEBP_CHUNK_ALPHA:
         if (wpi->alpha_ != NULL) goto Err;  // Consecutive ALPH chunks.
-        if (ChunkSetNth(&chunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Err;
+        if (ChunkSetHead(&chunk, &wpi->alpha_) != WEBP_MUX_OK) goto Err;
         wpi->is_partial_ = 1;  // Waiting for a VP8 chunk.
         break;
       case WEBP_CHUNK_IMAGE:
-        if (ChunkSetNth(&chunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Err;
+        if (ChunkSetHead(&chunk, &wpi->img_) != WEBP_MUX_OK) goto Err;
         if (!MuxImageFinalize(wpi)) goto Err;
         wpi->is_partial_ = 0;  // wpi is completely filled.
  PushImage:
@@ -253,13 +265,16 @@
         if (!MuxImageParse(&chunk, copy_data, wpi)) goto Err;
         ChunkRelease(&chunk);
         goto PushImage;
-        break;
       default:  // A non-image chunk.
         if (wpi->is_partial_) goto Err;  // Encountered a non-image chunk before
                                          // getting all chunks of an image.
-        chunk_list = MuxGetChunkListFromId(mux, id);  // List to add this chunk.
-        if (ChunkSetNth(&chunk, chunk_list, 0) != WEBP_MUX_OK) goto Err;
+        if (chunk_list_ends[id] == NULL) {
+          chunk_list_ends[id] =
+              MuxGetChunkListFromId(mux, id);  // List to add this chunk.
+        }
+        if (ChunkAppend(&chunk, &chunk_list_ends[id]) != WEBP_MUX_OK) goto Err;
         if (id == WEBP_CHUNK_VP8X) {  // grab global specs
+          if (data_size < CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE) goto Err;
           mux->canvas_width_ = GetLE24(data + 12) + 1;
           mux->canvas_height_ = GetLE24(data + 15) + 1;
         }
@@ -385,6 +400,10 @@
   uint8_t* const data = (uint8_t*)WebPSafeMalloc(1ULL, size);
   if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
 
+  // There should be at most one alpha_ chunk and exactly one img_ chunk.
+  assert(wpi->alpha_ == NULL || wpi->alpha_->next_ == NULL);
+  assert(wpi->img_ != NULL && wpi->img_->next_ == NULL);
+
   // Main RIFF header.
   dst = MuxEmitRiffHeader(data, size);
 
@@ -464,7 +483,6 @@
   WebPMuxError err;
   WebPMuxImage* wpi;
 
-  // Sanity checks.
   if (mux == NULL || frame == NULL) {
     return WEBP_MUX_INVALID_ARGUMENT;
   }
diff --git a/third_party/libwebp/src/utils/Makefile.am b/third_party/libwebp/src/utils/Makefile.am
index fbb0fe7..a4bff8b 100644
--- a/third_party/libwebp/src/utils/Makefile.am
+++ b/third_party/libwebp/src/utils/Makefile.am
@@ -9,6 +9,7 @@
 commondir = $(includedir)/webp
 
 noinst_HEADERS =
+noinst_HEADERS += ../dsp/cpu.h
 noinst_HEADERS += ../dsp/dsp.h
 noinst_HEADERS += ../webp/decode.h
 noinst_HEADERS += ../webp/encode.h
diff --git a/third_party/libwebp/src/utils/bit_reader_inl_utils.h b/third_party/libwebp/src/utils/bit_reader_inl_utils.h
index bf11a07..ecb6039 100644
--- a/third_party/libwebp/src/utils/bit_reader_inl_utils.h
+++ b/third_party/libwebp/src/utils/bit_reader_inl_utils.h
@@ -57,7 +57,7 @@
 
 // makes sure br->value_ has at least BITS bits worth of data
 static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
-void VP8LoadNewBytes(VP8BitReader* const br) {
+void VP8LoadNewBytes(VP8BitReader* WEBP_RESTRICT const br) {
   SB_DCHECK(br != NULL && br->buf_ != NULL);
   // Read 'BITS' bits at a time if possible.
   if (br->buf_ < br->buf_max_) {
@@ -106,7 +106,8 @@
 }
 
 // Read a bit with proba 'prob'. Speed-critical function!
-static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
+static WEBP_INLINE int VP8GetBit(VP8BitReader* WEBP_RESTRICT const br,
+                                 int prob, const char label[]) {
   // Don't move this declaration! It makes a big speed difference to store
   // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
   // alter br->range_ value.
@@ -131,13 +132,15 @@
       br->bits_ -= shift;
     }
     br->range_ = range - 1;
+    BT_TRACK(br);
     return bit;
   }
 }
 
 // simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here)
 static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
-int VP8GetSigned(VP8BitReader* const br, int v) {
+int VP8GetSigned(VP8BitReader* WEBP_RESTRICT const br, int v,
+                 const char label[]) {
   if (br->bits_ < 0) {
     VP8LoadNewBytes(br);
   }
@@ -147,14 +150,16 @@
     const range_t value = (range_t)(br->value_ >> pos);
     const int32_t mask = (int32_t)(split - value) >> 31;  // -1 or 0
     br->bits_ -= 1;
-    br->range_ += mask;
+    br->range_ += (range_t)mask;
     br->range_ |= 1;
-    br->value_ -= (bit_t)((split + 1) & mask) << pos;
+    br->value_ -= (bit_t)((split + 1) & (uint32_t)mask) << pos;
+    BT_TRACK(br);
     return (v ^ mask) - mask;
   }
 }
 
-static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) {
+static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* WEBP_RESTRICT const br,
+                                    int prob, const char label[]) {
   // Don't move this declaration! It makes a big speed difference to store
   // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
   // alter br->range_ value.
@@ -181,6 +186,7 @@
       br->bits_ -= shift;
     }
     br->range_ = range;
+    BT_TRACK(br);
     return bit;
   }
 }
@@ -189,4 +195,4 @@
 }    // extern "C"
 #endif
 
-#endif   // WEBP_UTILS_BIT_READER_INL_UTILS_H_
+#endif  // WEBP_UTILS_BIT_READER_INL_UTILS_H_
diff --git a/third_party/libwebp/src/utils/bit_reader_utils.c b/third_party/libwebp/src/utils/bit_reader_utils.c
index 17bbe8e..88fcbb3 100644
--- a/third_party/libwebp/src/utils/bit_reader_utils.c
+++ b/third_party/libwebp/src/utils/bit_reader_utils.c
@@ -19,6 +19,7 @@
 #include "starboard/client_porting/poem/assert_poem.h"
 #endif
 
+#include "src/dsp/cpu.h"
 #include "src/utils/bit_reader_inl_utils.h"
 #include "src/utils/utils.h"
 
@@ -106,17 +107,18 @@
 //------------------------------------------------------------------------------
 // Higher-level calls
 
-uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
+uint32_t VP8GetValue(VP8BitReader* const br, int bits, const char label[]) {
   uint32_t v = 0;
   while (bits-- > 0) {
-    v |= VP8GetBit(br, 0x80) << bits;
+    v |= VP8GetBit(br, 0x80, label) << bits;
   }
   return v;
 }
 
-int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
-  const int value = VP8GetValue(br, bits);
-  return VP8Get(br) ? -value : value;
+int32_t VP8GetSignedValue(VP8BitReader* const br, int bits,
+                          const char label[]) {
+  const int value = VP8GetValue(br, bits, label);
+  return VP8Get(br, label) ? -value : value;
 }
 
 //------------------------------------------------------------------------------
@@ -124,7 +126,7 @@
 
 #define VP8L_LOG8_WBITS 4  // Number of bytes needed to store VP8L_WBITS bits.
 
-#if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
+#if defined(__arm__) || defined(_M_ARM) || WEBP_AARCH64 || \
     defined(__i386__) || defined(_M_IX86) || \
     defined(__x86_64__) || defined(_M_X64)
 #define VP8L_USE_FAST_LOAD
@@ -224,3 +226,78 @@
 }
 
 //------------------------------------------------------------------------------
+// Bit-tracing tool
+
+#if (BITTRACE > 0)
+
+#include <stdlib.h>   // for atexit()
+#include <stdio.h>
+#include <string.h>
+
+#define MAX_NUM_LABELS 32
+static struct {
+  const char* label;
+  int size;
+  int count;
+} kLabels[MAX_NUM_LABELS];
+
+static int last_label = 0;
+static int last_pos = 0;
+static const uint8_t* buf_start = NULL;
+static int init_done = 0;
+
+static void PrintBitTraces(void) {
+  int i;
+  int scale = 1;
+  int total = 0;
+  const char* units = "bits";
+#if (BITTRACE == 2)
+  scale = 8;
+  units = "bytes";
+#endif
+  for (i = 0; i < last_label; ++i) total += kLabels[i].size;
+  if (total < 1) total = 1;   // avoid rounding errors
+  printf("=== Bit traces ===\n");
+  for (i = 0; i < last_label; ++i) {
+    const int skip = 16 - (int)strlen(kLabels[i].label);
+    const int value = (kLabels[i].size + scale - 1) / scale;
+    assert(skip > 0);
+    printf("%s \%*s: %6d %s   \t[%5.2f%%] [count: %7d]\n",
+           kLabels[i].label, skip, "", value, units,
+           100.f * kLabels[i].size / total,
+           kLabels[i].count);
+  }
+  total = (total + scale - 1) / scale;
+  printf("Total: %d %s\n", total, units);
+}
+
+void BitTrace(const struct VP8BitReader* const br, const char label[]) {
+  int i, pos;
+  if (!init_done) {
+    memset(kLabels, 0, sizeof(kLabels));
+    atexit(PrintBitTraces);
+    buf_start = br->buf_;
+    init_done = 1;
+  }
+  pos = (int)(br->buf_ - buf_start) * 8 - br->bits_;
+  // if there's a too large jump, we've changed partition -> reset counter
+  if (abs(pos - last_pos) > 32) {
+    buf_start = br->buf_;
+    pos = 0;
+    last_pos = 0;
+  }
+  if (br->range_ >= 0x7f) pos += kVP8Log2Range[br->range_ - 0x7f];
+  for (i = 0; i < last_label; ++i) {
+    if (!strcmp(label, kLabels[i].label)) break;
+  }
+  if (i == MAX_NUM_LABELS) abort();   // overflow!
+  kLabels[i].label = label;
+  kLabels[i].size += pos - last_pos;
+  kLabels[i].count += 1;
+  if (i == last_label) ++last_label;
+  last_pos = pos;
+}
+
+#endif  // BITTRACE > 0
+
+//------------------------------------------------------------------------------
diff --git a/third_party/libwebp/src/utils/bit_reader_utils.h b/third_party/libwebp/src/utils/bit_reader_utils.h
index 45878cf..1dd80b8 100644
--- a/third_party/libwebp/src/utils/bit_reader_utils.h
+++ b/third_party/libwebp/src/utils/bit_reader_utils.h
@@ -24,8 +24,30 @@
 #endif
 #endif
 
+#include "src/dsp/cpu.h"
 #include "src/webp/types.h"
 
+// Warning! This macro triggers quite some MACRO wizardry around func signature!
+#if !defined(BITTRACE)
+#define BITTRACE 0    // 0 = off, 1 = print bits, 2 = print bytes
+#endif
+
+#if (BITTRACE > 0)
+struct VP8BitReader;
+extern void BitTrace(const struct VP8BitReader* const br, const char label[]);
+#define BT_TRACK(br) BitTrace(br, label)
+#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
+#else
+#define BT_TRACK(br)
+// We'll REMOVE the 'const char label[]' from all signatures and calls (!!):
+#define VP8GetValue(BR, N, L) VP8GetValue(BR, N)
+#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
+#define VP8GetSignedValue(BR, N, L) VP8GetSignedValue(BR, N)
+#define VP8GetBit(BR, P, L) VP8GetBit(BR, P)
+#define VP8GetBitAlt(BR, P, L) VP8GetBitAlt(BR, P)
+#define VP8GetSigned(BR, V, L) VP8GetSigned(BR, V)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -48,7 +70,7 @@
 #define BITS 56
 #elif defined(__arm__) || defined(_M_ARM)      // ARM
 #define BITS 24
-#elif defined(__aarch64__)                     // ARM 64bit
+#elif WEBP_AARCH64                             // ARM 64bit
 #define BITS 56
 #elif defined(__mips__)                        // MIPS
 #define BITS 24
@@ -97,17 +119,15 @@
 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
 
 // return the next value made of 'num_bits' bits
-uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
-static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
-  return VP8GetValue(br, 1);
-}
+uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]);
 
 // return the next value with sign-extension.
-int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
+int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits,
+                          const char label[]);
 
 // bit_reader_inl.h will implement the following methods:
-//   static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob)
-//   static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v)
+//   static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...)
+//   static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...)
 // and should be included by the .c files that actually need them.
 // This is to avoid recompiling the whole library whenever this file is touched,
 // and also allowing platform-specific ad-hoc hacks.
@@ -177,4 +197,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_BIT_READER_UTILS_H_ */
+#endif  // WEBP_UTILS_BIT_READER_UTILS_H_
diff --git a/third_party/libwebp/src/utils/bit_writer_utils.c b/third_party/libwebp/src/utils/bit_writer_utils.c
index 6aaf5f3..8c6d0cf 100644
--- a/third_party/libwebp/src/utils/bit_writer_utils.c
+++ b/third_party/libwebp/src/utils/bit_writer_utils.c
@@ -76,7 +76,7 @@
       const int value = (bits & 0x100) ? 0x00 : 0xff;
       for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
     }
-    bw->buf_[pos++] = bits;
+    bw->buf_[pos++] = bits & 0xff;
     bw->pos_ = pos;
   } else {
     bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
@@ -254,6 +254,7 @@
   dst->bits_ = src->bits_;
   dst->used_ = src->used_;
   dst->error_ = src->error_;
+  dst->cur_ = dst->buf_ + current_size;
   return 1;
 }
 
@@ -283,7 +284,7 @@
   // If needed, make some room by flushing some bits out.
   if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
     const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
-    if (extra_size != (size_t)extra_size ||
+    if (!CheckSizeOverflow(extra_size) ||
         !VP8LBitWriterResize(bw, (size_t)extra_size)) {
       bw->cur_ = bw->buf_;
       bw->error_ = 1;
@@ -319,7 +320,7 @@
     while (used >= VP8L_WRITER_BITS) {
       if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
         const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
-        if (extra_size != (size_t)extra_size ||
+        if (!CheckSizeOverflow(extra_size) ||
             !VP8LBitWriterResize(bw, (size_t)extra_size)) {
           bw->cur_ = bw->buf_;
           bw->error_ = 1;
diff --git a/third_party/libwebp/src/utils/bit_writer_utils.h b/third_party/libwebp/src/utils/bit_writer_utils.h
index 2cf5976..b9d5102 100644
--- a/third_party/libwebp/src/utils/bit_writer_utils.h
+++ b/third_party/libwebp/src/utils/bit_writer_utils.h
@@ -151,4 +151,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_BIT_WRITER_UTILS_H_ */
+#endif  // WEBP_UTILS_BIT_WRITER_UTILS_H_
diff --git a/third_party/libwebp/src/utils/color_cache_utils.c b/third_party/libwebp/src/utils/color_cache_utils.c
index d49ec76..d1e3d13 100644
--- a/third_party/libwebp/src/utils/color_cache_utils.c
+++ b/third_party/libwebp/src/utils/color_cache_utils.c
@@ -27,22 +27,22 @@
 //------------------------------------------------------------------------------
 // VP8LColorCache.
 
-int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
+int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits) {
   const int hash_size = 1 << hash_bits;
-  assert(cc != NULL);
+  assert(color_cache != NULL);
   assert(hash_bits > 0);
-  cc->colors_ = (uint32_t*)WebPSafeCalloc((uint64_t)hash_size,
-                                          sizeof(*cc->colors_));
-  if (cc->colors_ == NULL) return 0;
-  cc->hash_shift_ = 32 - hash_bits;
-  cc->hash_bits_ = hash_bits;
+  color_cache->colors_ = (uint32_t*)WebPSafeCalloc(
+      (uint64_t)hash_size, sizeof(*color_cache->colors_));
+  if (color_cache->colors_ == NULL) return 0;
+  color_cache->hash_shift_ = 32 - hash_bits;
+  color_cache->hash_bits_ = hash_bits;
   return 1;
 }
 
-void VP8LColorCacheClear(VP8LColorCache* const cc) {
-  if (cc != NULL) {
-    WebPSafeFree(cc->colors_);
-    cc->colors_ = NULL;
+void VP8LColorCacheClear(VP8LColorCache* const color_cache) {
+  if (color_cache != NULL) {
+    WebPSafeFree(color_cache->colors_);
+    color_cache->colors_ = NULL;
   }
 }
 
diff --git a/third_party/libwebp/src/utils/color_cache_utils.h b/third_party/libwebp/src/utils/color_cache_utils.h
index 7ba2d52..227d9c4 100644
--- a/third_party/libwebp/src/utils/color_cache_utils.h
+++ b/third_party/libwebp/src/utils/color_cache_utils.h
@@ -21,6 +21,7 @@
 #include <assert.h>
 #endif
 
+#include "src/dsp/dsp.h"
 #include "src/webp/types.h"
 
 #ifdef __cplusplus
@@ -29,15 +30,16 @@
 
 // Main color cache struct.
 typedef struct {
-  uint32_t *colors_;  // color entries
+  uint32_t* colors_;  // color entries
   int hash_shift_;    // Hash shift: 32 - hash_bits_.
   int hash_bits_;
 } VP8LColorCache;
 
-static const uint64_t kHashMul = 0x1e35a7bdull;
+static const uint32_t kHashMul = 0x1e35a7bdu;
 
-static WEBP_INLINE int VP8LHashPix(uint32_t argb, int shift) {
-  return (int)(((argb * kHashMul) & 0xffffffffu) >> shift);
+static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
+int VP8LHashPix(uint32_t argb, int shift) {
+  return (int)((argb * kHashMul) >> shift);
 }
 
 static WEBP_INLINE uint32_t VP8LColorCacheLookup(
diff --git a/third_party/libwebp/src/utils/filters_utils.h b/third_party/libwebp/src/utils/filters_utils.h
index 410f2fc..61da66e 100644
--- a/third_party/libwebp/src/utils/filters_utils.h
+++ b/third_party/libwebp/src/utils/filters_utils.h
@@ -29,4 +29,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_FILTERS_UTILS_H_ */
+#endif  // WEBP_UTILS_FILTERS_UTILS_H_
diff --git a/third_party/libwebp/src/utils/huffman_encode_utils.c b/third_party/libwebp/src/utils/huffman_encode_utils.c
index 6f3b1bb..585db91 100644
--- a/third_party/libwebp/src/utils/huffman_encode_utils.c
+++ b/third_party/libwebp/src/utils/huffman_encode_utils.c
@@ -161,7 +161,7 @@
 // especially when population counts are longer than 2**tree_limit, but
 // we are not planning to use this with extremely long blocks.
 //
-// See http://en.wikipedia.org/wiki/Huffman_coding
+// See https://en.wikipedia.org/wiki/Huffman_coding
 static void GenerateOptimalTree(const uint32_t* const histogram,
                                 int histogram_size,
                                 HuffmanTree* tree, int tree_depth_limit,
@@ -404,8 +404,7 @@
 // Main entry point
 
 void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
-                           uint8_t* const buf_rle,
-                           HuffmanTree* const huff_tree,
+                           uint8_t* const buf_rle, HuffmanTree* const huff_tree,
                            HuffmanTreeCode* const huff_code) {
   const int num_symbols = huff_code->num_symbols;
   memset(buf_rle, 0, num_symbols * sizeof(*buf_rle));
diff --git a/third_party/libwebp/src/utils/huffman_encode_utils.h b/third_party/libwebp/src/utils/huffman_encode_utils.h
index 3e6763c..3f7f1d8 100644
--- a/third_party/libwebp/src/utils/huffman_encode_utils.h
+++ b/third_party/libwebp/src/utils/huffman_encode_utils.h
@@ -51,7 +51,7 @@
 // huffman code tree.
 void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
                            uint8_t* const buf_rle, HuffmanTree* const huff_tree,
-                           HuffmanTreeCode* const tree);
+                           HuffmanTreeCode* const huff_code);
 
 #ifdef __cplusplus
 }
diff --git a/third_party/libwebp/src/utils/huffman_utils.c b/third_party/libwebp/src/utils/huffman_utils.c
index 7a69963..90c2fbf 100644
--- a/third_party/libwebp/src/utils/huffman_utils.c
+++ b/third_party/libwebp/src/utils/huffman_utils.c
@@ -91,7 +91,8 @@
 
   assert(code_lengths_size != 0);
   assert(code_lengths != NULL);
-  assert(root_table != NULL);
+  assert((root_table != NULL && sorted != NULL) ||
+         (root_table == NULL && sorted == NULL));
   assert(root_bits > 0);
 
   // Build histogram of code lengths.
@@ -120,22 +121,28 @@
   for (symbol = 0; symbol < code_lengths_size; ++symbol) {
     const int symbol_code_length = code_lengths[symbol];
     if (code_lengths[symbol] > 0) {
-      sorted[offset[symbol_code_length]++] = symbol;
+      if (sorted != NULL) {
+        sorted[offset[symbol_code_length]++] = symbol;
+      } else {
+        offset[symbol_code_length]++;
+      }
     }
   }
 
   // Special case code with only one value.
   if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
-    HuffmanCode code;
-    code.bits = 0;
-    code.value = (uint16_t)sorted[0];
-    ReplicateValue(table, 1, total_size, code);
+    if (sorted != NULL) {
+      HuffmanCode code;
+      code.bits = 0;
+      code.value = (uint16_t)sorted[0];
+      ReplicateValue(table, 1, total_size, code);
+    }
     return total_size;
   }
 
   {
     int step;              // step size to replicate values in current table
-    uint32_t low = -1;     // low bits for current root entry
+    uint32_t low = 0xffffffffu;        // low bits for current root entry
     uint32_t mask = total_size - 1;    // mask for low bits
     uint32_t key = 0;      // reversed prefix code
     int num_nodes = 1;     // number of Huffman tree nodes
@@ -151,6 +158,7 @@
       if (num_open < 0) {
         return 0;
       }
+      if (root_table == NULL) continue;
       for (; count[len] > 0; --count[len]) {
         HuffmanCode code;
         code.bits = (uint8_t)len;
@@ -169,6 +177,7 @@
       if (num_open < 0) {
         return 0;
       }
+      if (root_table == NULL) continue;
       for (; count[len] > 0; --count[len]) {
         HuffmanCode code;
         if ((key & mask) != low) {
@@ -206,7 +215,10 @@
                           const int code_lengths[], int code_lengths_size) {
   int total_size;
   assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
-  if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+  if (root_table == NULL) {
+    total_size = BuildHuffmanTable(NULL, root_bits,
+                                   code_lengths, code_lengths_size, NULL);
+  } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
     // use local stack-allocated array.
     uint16_t sorted[SORTED_SIZE_CUTOFF];
     total_size = BuildHuffmanTable(root_table, root_bits,
diff --git a/third_party/libwebp/src/utils/huffman_utils.h b/third_party/libwebp/src/utils/huffman_utils.h
index 862ffc1..9d97ab2 100644
--- a/third_party/libwebp/src/utils/huffman_utils.h
+++ b/third_party/libwebp/src/utils/huffman_utils.h
@@ -82,6 +82,8 @@
 // the huffman table.
 // Returns built table size or 0 in case of error (invalid tree or
 // memory error).
+// If root_table is NULL, it returns 0 if a lookup cannot be built, something
+// > 0 otherwise (but not the table size).
 int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
                           const int code_lengths[], int code_lengths_size);
 
diff --git a/third_party/libwebp/src/utils/quant_levels_dec_utils.c b/third_party/libwebp/src/utils/quant_levels_dec_utils.c
index 3818a78..97e7893 100644
--- a/third_party/libwebp/src/utils/quant_levels_dec_utils.c
+++ b/third_party/libwebp/src/utils/quant_levels_dec_utils.c
@@ -30,7 +30,7 @@
 
 #define DFIX 4           // extra precision for ordered dithering
 #define DSIZE 4          // dithering size (must be a power of two)
-// cf. http://en.wikipedia.org/wiki/Ordered_dithering
+// cf. https://en.wikipedia.org/wiki/Ordered_dithering
 static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
   {  0,  8,  2, 10 },     // coefficients are in DFIX fixed-point precision
   { 12,  4, 14,  6 },
@@ -261,9 +261,15 @@
 
 int WebPDequantizeLevels(uint8_t* const data, int width, int height, int stride,
                          int strength) {
-  const int radius = 4 * strength / 100;
+  int radius = 4 * strength / 100;
+
   if (strength < 0 || strength > 100) return 0;
   if (data == NULL || width <= 0 || height <= 0) return 0;  // bad params
+
+  // limit the filter size to not exceed the image dimensions
+  if (2 * radius + 1 > width) radius = (width - 1) >> 1;
+  if (2 * radius + 1 > height) radius = (height - 1) >> 1;
+
   if (radius > 0) {
     SmoothParams p;
     memset(&p, 0, sizeof(p));
diff --git a/third_party/libwebp/src/utils/quant_levels_dec_utils.h b/third_party/libwebp/src/utils/quant_levels_dec_utils.h
index f822107..327f19f 100644
--- a/third_party/libwebp/src/utils/quant_levels_dec_utils.h
+++ b/third_party/libwebp/src/utils/quant_levels_dec_utils.h
@@ -32,4 +32,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_QUANT_LEVELS_DEC_UTILS_H_ */
+#endif  // WEBP_UTILS_QUANT_LEVELS_DEC_UTILS_H_
diff --git a/third_party/libwebp/src/utils/quant_levels_utils.h b/third_party/libwebp/src/utils/quant_levels_utils.h
index 75df2ba..9ee3ea0 100644
--- a/third_party/libwebp/src/utils/quant_levels_utils.h
+++ b/third_party/libwebp/src/utils/quant_levels_utils.h
@@ -33,4 +33,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_QUANT_LEVELS_UTILS_H_ */
+#endif  // WEBP_UTILS_QUANT_LEVELS_UTILS_H_
diff --git a/third_party/libwebp/src/utils/random_utils.h b/third_party/libwebp/src/utils/random_utils.h
index 5b8ce5d..c84a24f 100644
--- a/third_party/libwebp/src/utils/random_utils.h
+++ b/third_party/libwebp/src/utils/random_utils.h
@@ -64,4 +64,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_RANDOM_UTILS_H_ */
+#endif  // WEBP_UTILS_RANDOM_UTILS_H_
diff --git a/third_party/libwebp/src/utils/rescaler_utils.c b/third_party/libwebp/src/utils/rescaler_utils.c
index 90e2ea7..a0581a1 100644
--- a/third_party/libwebp/src/utils/rescaler_utils.c
+++ b/third_party/libwebp/src/utils/rescaler_utils.c
@@ -12,66 +12,74 @@
 // Author: Skal (pascal.massimino@gmail.com)
 
 #include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include "src/dsp/dsp.h"
 #include "src/utils/rescaler_utils.h"
+#include "src/utils/utils.h"
 
 //------------------------------------------------------------------------------
 
-void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
-                      uint8_t* const dst,
-                      int dst_width, int dst_height, int dst_stride,
-                      int num_channels, rescaler_t* const work) {
+int WebPRescalerInit(WebPRescaler* const rescaler,
+                     int src_width, int src_height,
+                     uint8_t* const dst,
+                     int dst_width, int dst_height, int dst_stride,
+                     int num_channels, rescaler_t* const work) {
   const int x_add = src_width, x_sub = dst_width;
   const int y_add = src_height, y_sub = dst_height;
-  wrk->x_expand = (src_width < dst_width);
-  wrk->y_expand = (src_height < dst_height);
-  wrk->src_width = src_width;
-  wrk->src_height = src_height;
-  wrk->dst_width = dst_width;
-  wrk->dst_height = dst_height;
-  wrk->src_y = 0;
-  wrk->dst_y = 0;
-  wrk->dst = dst;
-  wrk->dst_stride = dst_stride;
-  wrk->num_channels = num_channels;
+  const uint64_t total_size = 2ull * dst_width * num_channels * sizeof(*work);
+  if (!CheckSizeOverflow(total_size)) return 0;
+
+  rescaler->x_expand = (src_width < dst_width);
+  rescaler->y_expand = (src_height < dst_height);
+  rescaler->src_width = src_width;
+  rescaler->src_height = src_height;
+  rescaler->dst_width = dst_width;
+  rescaler->dst_height = dst_height;
+  rescaler->src_y = 0;
+  rescaler->dst_y = 0;
+  rescaler->dst = dst;
+  rescaler->dst_stride = dst_stride;
+  rescaler->num_channels = num_channels;
 
   // for 'x_expand', we use bilinear interpolation
-  wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add;
-  wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub;
-  if (!wrk->x_expand) {  // fx_scale is not used otherwise
-    wrk->fx_scale = WEBP_RESCALER_FRAC(1, wrk->x_sub);
+  rescaler->x_add = rescaler->x_expand ? (x_sub - 1) : x_add;
+  rescaler->x_sub = rescaler->x_expand ? (x_add - 1) : x_sub;
+  if (!rescaler->x_expand) {  // fx_scale is not used otherwise
+    rescaler->fx_scale = WEBP_RESCALER_FRAC(1, rescaler->x_sub);
   }
   // vertical scaling parameters
-  wrk->y_add = wrk->y_expand ? y_add - 1 : y_add;
-  wrk->y_sub = wrk->y_expand ? y_sub - 1 : y_sub;
-  wrk->y_accum = wrk->y_expand ? wrk->y_sub : wrk->y_add;
-  if (!wrk->y_expand) {
+  rescaler->y_add = rescaler->y_expand ? y_add - 1 : y_add;
+  rescaler->y_sub = rescaler->y_expand ? y_sub - 1 : y_sub;
+  rescaler->y_accum = rescaler->y_expand ? rescaler->y_sub : rescaler->y_add;
+  if (!rescaler->y_expand) {
     // This is WEBP_RESCALER_FRAC(dst_height, x_add * y_add) without the cast.
-    // Its value is <= WEBP_RESCALER_ONE, because dst_height <= wrk->y_add, and
-    // wrk->x_add >= 1;
-    const uint64_t ratio =
-        (uint64_t)dst_height * WEBP_RESCALER_ONE / (wrk->x_add * wrk->y_add);
+    // Its value is <= WEBP_RESCALER_ONE, because dst_height <= rescaler->y_add
+    // and rescaler->x_add >= 1;
+    const uint64_t num = (uint64_t)dst_height * WEBP_RESCALER_ONE;
+    const uint64_t den = (uint64_t)rescaler->x_add * rescaler->y_add;
+    const uint64_t ratio = num / den;
     if (ratio != (uint32_t)ratio) {
       // When ratio == WEBP_RESCALER_ONE, we can't represent the ratio with the
       // current fixed-point precision. This happens when src_height ==
-      // wrk->y_add (which == src_height), and wrk->x_add == 1.
+      // rescaler->y_add (which == src_height), and rescaler->x_add == 1.
       // => We special-case fxy_scale = 0, in WebPRescalerExportRow().
-      wrk->fxy_scale = 0;
+      rescaler->fxy_scale = 0;
     } else {
-      wrk->fxy_scale = (uint32_t)ratio;
+      rescaler->fxy_scale = (uint32_t)ratio;
     }
-    wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->y_sub);
+    rescaler->fy_scale = WEBP_RESCALER_FRAC(1, rescaler->y_sub);
   } else {
-    wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->x_add);
-    // wrk->fxy_scale is unused here.
+    rescaler->fy_scale = WEBP_RESCALER_FRAC(1, rescaler->x_add);
+    // rescaler->fxy_scale is unused here.
   }
-  wrk->irow = work;
-  wrk->frow = work + num_channels * dst_width;
-  memset(work, 0, 2 * dst_width * num_channels * sizeof(*work));
+  rescaler->irow = work;
+  rescaler->frow = work + num_channels * dst_width;
+  memset(work, 0, (size_t)total_size);
 
   WebPRescalerDspInit();
+  return 1;
 }
 
 int WebPRescalerGetScaledDimensions(int src_width, int src_height,
@@ -82,19 +90,20 @@
   {
     int width = *scaled_width;
     int height = *scaled_height;
+    const int max_size = INT_MAX / 2;
 
     // if width is unspecified, scale original proportionally to height ratio.
-    if (width == 0) {
+    if (width == 0 && src_height > 0) {
       width =
-          (int)(((uint64_t)src_width * height + src_height / 2) / src_height);
+          (int)(((uint64_t)src_width * height + src_height - 1) / src_height);
     }
     // if height is unspecified, scale original proportionally to width ratio.
-    if (height == 0) {
+    if (height == 0 && src_width > 0) {
       height =
-          (int)(((uint64_t)src_height * width + src_width / 2) / src_width);
+          (int)(((uint64_t)src_height * width + src_width - 1) / src_width);
     }
     // Check if the overall dimensions still make sense.
-    if (width <= 0 || height <= 0) {
+    if (width <= 0 || height <= 0 || width > max_size || height > max_size) {
       return 0;
     }
 
@@ -107,31 +116,34 @@
 //------------------------------------------------------------------------------
 // all-in-one calls
 
-int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) {
-  const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub;
+int WebPRescaleNeededLines(const WebPRescaler* const rescaler,
+                           int max_num_lines) {
+  const int num_lines =
+      (rescaler->y_accum + rescaler->y_sub - 1) / rescaler->y_sub;
   return (num_lines > max_num_lines) ? max_num_lines : num_lines;
 }
 
-int WebPRescalerImport(WebPRescaler* const wrk, int num_lines,
+int WebPRescalerImport(WebPRescaler* const rescaler, int num_lines,
                        const uint8_t* src, int src_stride) {
   int total_imported = 0;
-  while (total_imported < num_lines && !WebPRescalerHasPendingOutput(wrk)) {
-    if (wrk->y_expand) {
-      rescaler_t* const tmp = wrk->irow;
-      wrk->irow = wrk->frow;
-      wrk->frow = tmp;
+  while (total_imported < num_lines &&
+         !WebPRescalerHasPendingOutput(rescaler)) {
+    if (rescaler->y_expand) {
+      rescaler_t* const tmp = rescaler->irow;
+      rescaler->irow = rescaler->frow;
+      rescaler->frow = tmp;
     }
-    WebPRescalerImportRow(wrk, src);
-    if (!wrk->y_expand) {     // Accumulate the contribution of the new row.
+    WebPRescalerImportRow(rescaler, src);
+    if (!rescaler->y_expand) {    // Accumulate the contribution of the new row.
       int x;
-      for (x = 0; x < wrk->num_channels * wrk->dst_width; ++x) {
-        wrk->irow[x] += wrk->frow[x];
+      for (x = 0; x < rescaler->num_channels * rescaler->dst_width; ++x) {
+        rescaler->irow[x] += rescaler->frow[x];
       }
     }
-    ++wrk->src_y;
+    ++rescaler->src_y;
     src += src_stride;
     ++total_imported;
-    wrk->y_accum -= wrk->y_sub;
+    rescaler->y_accum -= rescaler->y_sub;
   }
   return total_imported;
 }
diff --git a/third_party/libwebp/src/utils/rescaler_utils.h b/third_party/libwebp/src/utils/rescaler_utils.h
index 8890e6f..ef201ef 100644
--- a/third_party/libwebp/src/utils/rescaler_utils.h
+++ b/third_party/libwebp/src/utils/rescaler_utils.h
@@ -47,12 +47,13 @@
 };
 
 // Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
-void WebPRescalerInit(WebPRescaler* const rescaler,
-                      int src_width, int src_height,
-                      uint8_t* const dst,
-                      int dst_width, int dst_height, int dst_stride,
-                      int num_channels,
-                      rescaler_t* const work);
+// Returns false in case of error.
+int WebPRescalerInit(WebPRescaler* const rescaler,
+                     int src_width, int src_height,
+                     uint8_t* const dst,
+                     int dst_width, int dst_height, int dst_stride,
+                     int num_channels,
+                     rescaler_t* const work);
 
 // If either 'scaled_width' or 'scaled_height' (but not both) is 0 the value
 // will be calculated preserving the aspect ratio, otherwise the values are
@@ -98,4 +99,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_RESCALER_UTILS_H_ */
+#endif  // WEBP_UTILS_RESCALER_UTILS_H_
diff --git a/third_party/libwebp/src/utils/thread_utils.c b/third_party/libwebp/src/utils/thread_utils.c
index 2052b6b..4e470e1 100644
--- a/third_party/libwebp/src/utils/thread_utils.c
+++ b/third_party/libwebp/src/utils/thread_utils.c
@@ -73,7 +73,7 @@
 #endif
 
 static int pthread_create(pthread_t* const thread, const void* attr,
-                          unsigned int (__stdcall *start)(void*), void* arg) {
+                          unsigned int (__stdcall* start)(void*), void* arg) {
   (void)attr;
 #ifdef USE_CREATE_THREAD
   *thread = CreateThread(NULL,   /* lpThreadAttributes */
@@ -217,8 +217,12 @@
       done = 1;
     }
     // signal to the main thread that we're done (for Sync())
-    pthread_cond_signal(&impl->condition_);
+    // Note the associated mutex does not need to be held when signaling the
+    // condition. Unlocking the mutex first may improve performance in some
+    // implementations, avoiding the case where the waiting thread can't
+    // reacquire the mutex when woken.
     pthread_mutex_unlock(&impl->mutex_);
+    pthread_cond_signal(&impl->condition_);
   }
   return THREAD_RETURN(NULL);    // Thread is finished
 }
@@ -240,7 +244,13 @@
     // assign new status and release the working thread if needed
     if (new_status != OK) {
       worker->status_ = new_status;
+      // Note the associated mutex does not need to be held when signaling the
+      // condition. Unlocking the mutex first may improve performance in some
+      // implementations, avoiding the case where the waiting thread can't
+      // reacquire the mutex when woken.
+      pthread_mutex_unlock(&impl->mutex_);
       pthread_cond_signal(&impl->condition_);
+      return;
     }
   }
   pthread_mutex_unlock(&impl->mutex_);
diff --git a/third_party/libwebp/src/utils/thread_utils.h b/third_party/libwebp/src/utils/thread_utils.h
index c8ae6c9..29ad49f 100644
--- a/third_party/libwebp/src/utils/thread_utils.h
+++ b/third_party/libwebp/src/utils/thread_utils.h
@@ -87,4 +87,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_THREAD_UTILS_H_ */
+#endif  // WEBP_UTILS_THREAD_UTILS_H_
diff --git a/third_party/libwebp/src/utils/utils.c b/third_party/libwebp/src/utils/utils.c
index d85850c..4989abf 100644
--- a/third_party/libwebp/src/utils/utils.c
+++ b/third_party/libwebp/src/utils/utils.c
@@ -28,7 +28,7 @@
 // alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
 // and not multi-thread safe!).
 // An interesting alternative is valgrind's 'massif' tool:
-//    http://valgrind.org/docs/manual/ms-manual.html
+//    https://valgrind.org/docs/manual/ms-manual.html
 // Here is an example command line:
 /*    valgrind --tool=massif --massif-out-file=massif.out \
                --stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc
@@ -108,6 +108,9 @@
 #if defined(MALLOC_LIMIT)
     {
       const char* const malloc_limit_str = getenv("MALLOC_LIMIT");
+#if MALLOC_LIMIT > 1
+      mem_limit = (size_t)MALLOC_LIMIT;
+#endif
       if (malloc_limit_str != NULL) {
         mem_limit = atoi(malloc_limit_str);
       }
@@ -176,16 +179,16 @@
   const uint64_t total_size = nmemb * size;
   if (nmemb == 0) return 1;
   if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0;
-  if (total_size != (size_t)total_size) return 0;
+  if (!CheckSizeOverflow(total_size)) return 0;
 #if defined(PRINT_MEM_INFO) && defined(MALLOC_FAIL_AT)
   if (countdown_to_fail > 0 && --countdown_to_fail == 0) {
     return 0;    // fake fail!
   }
 #endif
-#if defined(MALLOC_LIMIT)
+#if defined(PRINT_MEM_INFO) && defined(MALLOC_LIMIT)
   if (mem_limit > 0) {
     const uint64_t new_total_mem = (uint64_t)total_mem + total_size;
-    if (new_total_mem != (size_t)new_total_mem ||
+    if (!CheckSizeOverflow(new_total_mem) ||
         new_total_mem > mem_limit) {
       return 0;   // fake fail!
     }
@@ -223,9 +226,14 @@
   free(ptr);
 }
 
-// Public API function.
+// Public API functions.
+
+void* WebPMalloc(size_t size) {
+  return WebPSafeMalloc(1, size);
+}
+
 void WebPFree(void* ptr) {
-  free(ptr);
+  WebPSafeFree(ptr);
 }
 
 //------------------------------------------------------------------------------
@@ -233,7 +241,7 @@
 void WebPCopyPlane(const uint8_t* src, int src_stride,
                    uint8_t* dst, int dst_stride, int width, int height) {
   assert(src != NULL && dst != NULL);
-  assert(src_stride >= width && dst_stride >= width);
+  assert(abs(src_stride) >= width && abs(dst_stride) >= width);
   while (height-- > 0) {
     memcpy(dst, src, width);
     src += src_stride;
diff --git a/third_party/libwebp/src/utils/utils.h b/third_party/libwebp/src/utils/utils.h
index 4b2bf1c..51ea15c 100644
--- a/third_party/libwebp/src/utils/utils.h
+++ b/third_party/libwebp/src/utils/utils.h
@@ -47,6 +47,10 @@
 #endif
 #endif  // WEBP_MAX_ALLOCABLE_MEMORY
 
+static WEBP_INLINE int CheckSizeOverflow(uint64_t size) {
+  return size == (size_t)size;
+}
+
 // size-checking safe malloc/calloc: verify that the requested size is not too
 // large, or return NULL. You don't need to call these for constructs like
 // malloc(sizeof(foo)), but only if there's picture-dependent size involved
@@ -65,7 +69,8 @@
 // Alignment
 
 #define WEBP_ALIGN_CST 31
-#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
+#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & \
+                         ~(uintptr_t)WEBP_ALIGN_CST)
 
 #if !defined(STARBOARD)
 #include <string.h>
@@ -77,10 +82,19 @@
   memcpy(&A, ptr, sizeof(A));
   return A;
 }
+
+static WEBP_INLINE int32_t WebPMemToInt32(const uint8_t* const ptr) {
+  return (int32_t)WebPMemToUint32(ptr);
+}
+
 static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
   memcpy(ptr, &val, sizeof(val));
 }
 
+static WEBP_INLINE void WebPInt32ToMem(uint8_t* const ptr, int val) {
+  WebPUint32ToMem(ptr, (uint32_t)val);
+}
+
 //------------------------------------------------------------------------------
 // Reading/writing data.
 
@@ -100,14 +114,14 @@
 // Store 16, 24 or 32 bits in little-endian order.
 static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
   SB_DCHECK(val < (1 << 16));
-  data[0] = (val >> 0);
-  data[1] = (val >> 8);
+  data[0] = (val >> 0) & 0xff;
+  data[1] = (val >> 8) & 0xff;
 }
 
 static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
   SB_DCHECK(val < (1 << 24));
   PutLE16(data, val & 0xffff);
-  data[2] = (val >> 16);
+  data[2] = (val >> 16) & 0xff;
 }
 
 static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {
@@ -115,6 +129,33 @@
   PutLE16(data + 2, (int)(val >> 16));
 }
 
+// use GNU builtins where available.
+#if !defined(STARBOARD) && defined(__GNUC__) && \
+    ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+// Returns (int)floor(log2(n)). n must be > 0.
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+  return 31 ^ __builtin_clz(n);
+}
+// counts the number of trailing zero
+static WEBP_INLINE int BitsCtz(uint32_t n) { return __builtin_ctz(n); }
+#elif !defined(STARBOARD) && defined(_MSC_VER) && _MSC_VER > 1310 && \
+      (defined(_M_X64) || defined(_M_IX86))
+#include <intrin.h>
+#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
+
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+  unsigned long first_set_bit;  // NOLINT (runtime/int)
+  _BitScanReverse(&first_set_bit, n);
+  return first_set_bit;
+}
+static WEBP_INLINE int BitsCtz(uint32_t n) {
+  unsigned long first_set_bit;  // NOLINT (runtime/int)
+  _BitScanForward(&first_set_bit, n);
+  return first_set_bit;
+}
+#else   // default: use the (slow) C-version.
+#define WEBP_HAVE_SLOW_CLZ_CTZ   // signal that the Clz/Ctz function are slow
 // Returns 31 ^ clz(n) = log2(n). This is the default C-implementation, either
 // based on table or not. Can be used as fallback if clz() is not available.
 #define WEBP_NEED_LOG_TABLE_8BIT
@@ -128,25 +169,16 @@
   return log_value + WebPLogTable8bit[n];
 }
 
-// Returns (int)floor(log2(n)). n must be > 0.
-// use GNU builtins where available.
-#if !defined(STARBOARD) && defined(__GNUC__) && \
-    ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
-static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
-  return 31 ^ __builtin_clz(n);
-}
-#elif !defined(STARBOARD) && defined(_MSC_VER) && _MSC_VER > 1310 && \
-      (defined(_M_X64) || defined(_M_IX86))
-#include <intrin.h>
-#pragma intrinsic(_BitScanReverse)
-
-static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
-  unsigned long first_set_bit;
-  _BitScanReverse(&first_set_bit, n);
-  return first_set_bit;
-}
-#else   // default: use the C-version.
 static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return WebPLog2FloorC(n); }
+
+static WEBP_INLINE int BitsCtz(uint32_t n) {
+  int i;
+  for (i = 0; i < 32; ++i, n >>= 1) {
+    if (n & 1) return i;
+  }
+  return 32;
+}
+
 #endif
 
 //------------------------------------------------------------------------------
@@ -183,4 +215,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_UTILS_UTILS_H_ */
+#endif  // WEBP_UTILS_UTILS_H_
diff --git a/third_party/libwebp/src/webp/decode.h b/third_party/libwebp/src/webp/decode.h
index 2165e96..0177b12 100644
--- a/third_party/libwebp/src/webp/decode.h
+++ b/third_party/libwebp/src/webp/decode.h
@@ -20,7 +20,7 @@
 extern "C" {
 #endif
 
-#define WEBP_DECODER_ABI_VERSION 0x0208    // MAJOR(8b) + MINOR(8b)
+#define WEBP_DECODER_ABI_VERSION 0x0209    // MAJOR(8b) + MINOR(8b)
 
 // Note: forward declaring enumerations is not allowed in (strict) C and C++,
 // the types are left here for reference.
@@ -42,6 +42,12 @@
 // This function will also validate the header, returning true on success,
 // false otherwise. '*width' and '*height' are only valid on successful return.
 // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
+// Note: The following chunk sequences (before the raw VP8/VP8L data) are
+// considered valid by this function:
+// RIFF + VP8(L)
+// RIFF + VP8X + (optional chunks) + VP8(L)
+// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
+// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
 WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size,
                             int* width, int* height);
 
@@ -75,19 +81,17 @@
 // returned is the Y samples buffer. Upon return, *u and *v will point to
 // the U and V chroma data. These U and V buffers need NOT be passed to
 // WebPFree(), unlike the returned Y luma one. The dimension of the U and V
-// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
+// planes are both (*width + 1) / 2 and (*height + 1) / 2.
 // Upon return, the Y buffer has a stride returned as '*stride', while U and V
 // have a common stride returned as '*uv_stride'.
-// Return NULL in case of error.
-// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
+// 'width' and 'height' may be NULL, the other pointers must not be.
+// Returns NULL in case of error.
+// (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr
 WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
                                    int* width, int* height,
                                    uint8_t** u, uint8_t** v,
                                    int* stride, int* uv_stride);
 
-// Releases memory returned by the WebPDecode*() functions above.
-WEBP_EXTERN void WebPFree(void* ptr);
-
 // These five functions are variants of the above ones, that decode the image
 // directly into a pre-allocated buffer 'output_buffer'. The maximum storage
 // available in this buffer is indicated by 'output_buffer_size'. If this
@@ -425,6 +429,12 @@
 // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
 // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
 // features from headers. Returns error in other cases.
+// Note: The following chunk sequences (before the raw VP8/VP8L data) are
+// considered valid by this function:
+// RIFF + VP8(L)
+// RIFF + VP8X + (optional chunks) + VP8(L)
+// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
+// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
 static WEBP_INLINE VP8StatusCode WebPGetFeatures(
     const uint8_t* data, size_t data_size,
     WebPBitstreamFeatures* features) {
@@ -444,7 +454,7 @@
   int scaled_width, scaled_height;    // final resolution
   int use_threads;                    // if true, use multi-threaded decoding
   int dithering_strength;             // dithering strength (0=Off, 100=full)
-  int flip;                           // flip output vertically
+  int flip;                           // if true, flip output vertically
   int alpha_dithering_strength;       // alpha dithering strength in [0..100]
 
   uint32_t pad[5];                    // padding for later use
@@ -491,4 +501,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_WEBP_DECODE_H_ */
+#endif  // WEBP_WEBP_DECODE_H_
diff --git a/third_party/libwebp/src/webp/demux.h b/third_party/libwebp/src/webp/demux.h
index 555d641..846eeb1 100644
--- a/third_party/libwebp/src/webp/demux.h
+++ b/third_party/libwebp/src/webp/demux.h
@@ -360,4 +360,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_WEBP_DEMUX_H_ */
+#endif  // WEBP_WEBP_DEMUX_H_
diff --git a/third_party/libwebp/src/webp/encode.h b/third_party/libwebp/src/webp/encode.h
index 7ec3543..56b68e2 100644
--- a/third_party/libwebp/src/webp/encode.h
+++ b/third_party/libwebp/src/webp/encode.h
@@ -20,7 +20,7 @@
 extern "C" {
 #endif
 
-#define WEBP_ENCODER_ABI_VERSION 0x020e    // MAJOR(8b) + MINOR(8b)
+#define WEBP_ENCODER_ABI_VERSION 0x020f    // MAJOR(8b) + MINOR(8b)
 
 // Note: forward declaring enumerations is not allowed in (strict) C and C++,
 // the types are left here for reference.
@@ -62,6 +62,10 @@
 // These functions are the equivalent of the above, but compressing in a
 // lossless manner. Files are usually larger than lossy format, but will
 // not suffer any compression loss.
+// Note these functions, like the lossy versions, use the library's default
+// settings. For lossless this means 'exact' is disabled. RGB values in
+// transparent areas will be modified to improve compression. To avoid this,
+// use WebPEncode() and set WebPConfig::exact to 1.
 WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
                                          int width, int height, int stride,
                                          uint8_t** output);
@@ -75,9 +79,6 @@
                                           int width, int height, int stride,
                                           uint8_t** output);
 
-// Releases memory returned by the WebPEncode*() functions above.
-WEBP_EXTERN void WebPFree(void* ptr);
-
 //------------------------------------------------------------------------------
 // Coding parameters
 
@@ -147,7 +148,8 @@
   int use_delta_palette;  // reserved for future lossless feature
   int use_sharp_yuv;      // if needed, use sharp (and slow) RGB->YUV conversion
 
-  uint32_t pad[2];        // padding for later use
+  int qmin;               // minimum permissible quality factor
+  int qmax;               // maximum permissible quality factor
 };
 
 // Enumerate some predefined settings for WebPConfig, depending on the type
@@ -290,6 +292,11 @@
 #define WEBP_MAX_DIMENSION 16383
 
 // Main exchange structure (input samples, output bytes, statistics)
+//
+// Once WebPPictureInit() has been called, it's ok to make all the INPUT fields
+// (use_argb, y/u/v, argb, ...) point to user-owned data, even if
+// WebPPictureAlloc() has been called. Depending on the value use_argb,
+// it's guaranteed that either *argb or *y/*u/*v content will be kept untouched.
 struct WebPPicture {
   //   INPUT
   //////////////
@@ -302,7 +309,7 @@
   // YUV input (mostly used for input to lossy compression)
   WebPEncCSP colorspace;     // colorspace: should be YUV420 for now (=Y'CbCr).
   int width, height;         // dimensions (less or equal to WEBP_MAX_DIMENSION)
-  uint8_t *y, *u, *v;        // pointers to luma/chroma planes.
+  uint8_t* y, *u, *v;        // pointers to luma/chroma planes.
   int y_stride, uv_stride;   // luma/chroma strides.
   uint8_t* a;                // pointer to the alpha plane
   int a_stride;              // stride of the alpha plane
@@ -346,7 +353,7 @@
   uint32_t pad3[3];       // padding for later use
 
   // Unused for now
-  uint8_t *pad4, *pad5;
+  uint8_t* pad4, *pad5;
   uint32_t pad6[8];       // padding for later use
 
   // PRIVATE FIELDS
@@ -434,7 +441,7 @@
 // the original dimension will be lost). Picture 'dst' need not be initialized
 // with WebPPictureInit() if it is different from 'src', since its content will
 // be overwritten.
-// Returns false in case of memory allocation error or invalid parameters.
+// Returns false in case of invalid parameters.
 WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
                                 int left, int top, int width, int height,
                                 WebPPicture* dst);
@@ -448,7 +455,7 @@
 // dimension will be calculated preserving the aspect ratio.
 // No gamma correction is applied.
 // Returns false in case of error (invalid parameter or insufficient memory).
-WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height);
+WEBP_EXTERN int WebPPictureRescale(WebPPicture* picture, int width, int height);
 
 // Colorspace conversion function to import RGB samples.
 // Previous buffer will be free'd, if any.
@@ -519,7 +526,7 @@
 // Remove the transparency information (if present) by blending the color with
 // the background color 'background_rgb' (specified as 24bit RGB triplet).
 // After this call, all alpha values are reset to 0xff.
-WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
+WEBP_EXTERN void WebPBlendAlpha(WebPPicture* picture, uint32_t background_rgb);
 
 //------------------------------------------------------------------------------
 // Main call
@@ -542,4 +549,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_WEBP_ENCODE_H_ */
+#endif  // WEBP_WEBP_ENCODE_H_
diff --git a/third_party/libwebp/src/webp/format_constants.h b/third_party/libwebp/src/webp/format_constants.h
index 329fc8a..999035c 100644
--- a/third_party/libwebp/src/webp/format_constants.h
+++ b/third_party/libwebp/src/webp/format_constants.h
@@ -55,7 +55,7 @@
 typedef enum {
   PREDICTOR_TRANSFORM      = 0,
   CROSS_COLOR_TRANSFORM    = 1,
-  SUBTRACT_GREEN           = 2,
+  SUBTRACT_GREEN_TRANSFORM = 2,
   COLOR_INDEXING_TRANSFORM = 3
 } VP8LImageTransformType;
 
@@ -84,4 +84,4 @@
 // overflow a uint32_t.
 #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
 
-#endif  /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */
+#endif  // WEBP_WEBP_FORMAT_CONSTANTS_H_
diff --git a/third_party/libwebp/src/webp/mux.h b/third_party/libwebp/src/webp/mux.h
index 28bb4a4..7d27489 100644
--- a/third_party/libwebp/src/webp/mux.h
+++ b/third_party/libwebp/src/webp/mux.h
@@ -57,7 +57,7 @@
   WebPMuxGetChunk(mux, "ICCP", &icc_profile);
   // ... (Consume icc_data).
   WebPMuxDelete(mux);
-  free(data);
+  WebPFree(data);
 */
 
 // Note: forward declaring enumerations is not allowed in (strict) C and C++,
@@ -245,7 +245,7 @@
     WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
 
 // Gets the nth frame from the mux object.
-// The content of 'frame->bitstream' is allocated using malloc(), and NOT
+// The content of 'frame->bitstream' is allocated using WebPMalloc(), and NOT
 // owned by the 'mux' object. It MUST be deallocated by the caller by calling
 // WebPDataClear().
 // nth=0 has a special meaning - last position.
@@ -376,10 +376,10 @@
 // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
 // This function also validates the mux object.
 // Note: The content of 'assembled_data' will be ignored and overwritten.
-// Also, the content of 'assembled_data' is allocated using malloc(), and NOT
-// owned by the 'mux' object. It MUST be deallocated by the caller by calling
-// WebPDataClear(). It's always safe to call WebPDataClear() upon return,
-// even in case of error.
+// Also, the content of 'assembled_data' is allocated using WebPMalloc(), and
+// NOT owned by the 'mux' object. It MUST be deallocated by the caller by
+// calling WebPDataClear(). It's always safe to call WebPDataClear() upon
+// return, even in case of error.
 // Parameters:
 //   mux - (in/out) object whose chunks are to be assembled
 //   assembled_data - (out) assembled WebP data
@@ -527,4 +527,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_WEBP_MUX_H_ */
+#endif  // WEBP_WEBP_MUX_H_
diff --git a/third_party/libwebp/src/webp/mux_types.h b/third_party/libwebp/src/webp/mux_types.h
index fcc9304..087e9f9 100644
--- a/third_party/libwebp/src/webp/mux_types.h
+++ b/third_party/libwebp/src/webp/mux_types.h
@@ -17,8 +17,6 @@
 #if defined(STARBOARD)
 #include "starboard/common/log.h"
 #include "starboard/memory.h"
-#else
-#include <stdlib.h>  // free()
 #include <string.h>  // memset()
 #endif
 #include "./types.h"
@@ -61,6 +59,7 @@
 
 // Data type used to describe 'raw' data, e.g., chunk data
 // (ICC profile, metadata) and WebP compressed image data.
+// 'bytes' memory must be allocated using WebPMalloc() and such.
 struct WebPData {
   const uint8_t* bytes;
   size_t size;
@@ -73,11 +72,11 @@
   }
 }
 
-// Clears the contents of the 'webp_data' object by calling free(). Does not
-// deallocate the object itself.
+// Clears the contents of the 'webp_data' object by calling WebPFree().
+// Does not deallocate the object itself.
 static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
   if (webp_data != NULL) {
-    SbMemoryDeallocate((void*)webp_data->bytes);
+    WebPFree((void*)webp_data->bytes);
     WebPDataInit(webp_data);
   }
 }
@@ -88,7 +87,7 @@
   if (src == NULL || dst == NULL) return 0;
   WebPDataInit(dst);
   if (src->bytes != NULL && src->size != 0) {
-    dst->bytes = (uint8_t*)SbMemoryAllocate(src->size);
+    dst->bytes = (uint8_t*)WebPMalloc(src->size);
     if (dst->bytes == NULL) return 0;
     memcpy((void*)dst->bytes, src->bytes, src->size);
     dst->size = src->size;
@@ -100,4 +99,4 @@
 }    // extern "C"
 #endif
 
-#endif  /* WEBP_WEBP_MUX_TYPES_H_ */
+#endif  // WEBP_WEBP_MUX_TYPES_H_
diff --git a/third_party/libwebp/src/webp/types.h b/third_party/libwebp/src/webp/types.h
index 5c35487..e2a6350 100644
--- a/third_party/libwebp/src/webp/types.h
+++ b/third_party/libwebp/src/webp/types.h
@@ -7,7 +7,7 @@
 // be found in the AUTHORS file in the root of the source tree.
 // -----------------------------------------------------------------------------
 //
-//  Common types
+//  Common types + memory wrappers
 //
 // Author: Skal (pascal.massimino@gmail.com)
 
@@ -48,11 +48,31 @@
 # if defined(__GNUC__) && __GNUC__ >= 4
 #  define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
 # else
-#  define WEBP_EXTERN extern
+#  if defined(_MSC_VER) && defined(WEBP_DLL)
+#   define WEBP_EXTERN __declspec(dllexport)
+#  else
+#   define WEBP_EXTERN extern
+#  endif
 # endif  /* __GNUC__ >= 4 */
 #endif  /* WEBP_EXTERN */
 
 // Macro to check ABI compatibility (same major revision number)
 #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
 
-#endif  /* WEBP_WEBP_TYPES_H_ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Allocates 'size' bytes of memory. Returns NULL upon error. Memory
+// must be deallocated by calling WebPFree(). This function is made available
+// by the core 'libwebp' library.
+WEBP_EXTERN void* WebPMalloc(size_t size);
+
+// Releases memory returned by the WebPDecode*() functions (from decode.h).
+WEBP_EXTERN void WebPFree(void* ptr);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  // WEBP_WEBP_TYPES_H_
diff --git a/third_party/libwebp/swig/README b/third_party/libwebp/swig/README.md
similarity index 78%
rename from third_party/libwebp/swig/README
rename to third_party/libwebp/swig/README.md
index 725c071..7fa1c38 100644
--- a/third_party/libwebp/swig/README
+++ b/third_party/libwebp/swig/README.md
@@ -1,15 +1,20 @@
-Building:
-=========
+# SWIG bindings
 
-JNI SWIG bindings:
-------------------
+## Building
+
+### JNI SWIG bindings
+
+```shell
  $ gcc -shared -fPIC -fno-strict-aliasing -O2 \
        -I/path/to/your/jdk/includes \
        libwebp_java_wrap.c \
        -lwebp \
        -o libwebp_jni.so
+```
 
--------------------------------------- BEGIN PSEUDO EXAMPLE
+Example usage:
+
+```java
 import com.google.webp.libwebp;
 
 import java.lang.reflect.Method;
@@ -33,17 +38,23 @@
     }
   }
 }
--------------------------------------- END PSEUDO EXAMPLE
+```
 
+```shell
  $ javac -cp libwebp.jar libwebp_jni_example.java
  $ java -Djava.library.path=. -cp libwebp.jar:. libwebp_jni_example
+```
 
-Python SWIG bindings:
----------------------
+### Python SWIG bindings:
+
+```shell
  $ python setup.py build_ext
  $ python setup.py install --prefix=pylocal
+```
 
--------------------------------------- BEGIN PSEUDO EXAMPLE
+Example usage:
+
+```python
 import glob
 import sys
 sys.path.append(glob.glob('pylocal/lib/python*/site-packages')[0])
@@ -53,4 +64,4 @@
 
 print "libwebp attributes:"
 for attr in dir(libwebp): print attr
--------------------------------------- END PSEUDO EXAMPLE
+```
diff --git a/third_party/libwebp/swig/libwebp.py b/third_party/libwebp/swig/libwebp.py
index 4ff11f8..2d126b5 100644
--- a/third_party/libwebp/swig/libwebp.py
+++ b/third_party/libwebp/swig/libwebp.py
@@ -1,13 +1,22 @@
 # This file was automatically generated by SWIG (http://www.swig.org).
-# Version 2.0.4
+# Version 3.0.12
 #
 # Do not make changes to this file unless you know what you are doing--modify
 # the SWIG interface file instead.
 
-
-
-from sys import version_info
-if version_info >= (2,6,0):
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info >= (2, 7, 0):
+    def swig_import_helper():
+        import importlib
+        pkg = __name__.rpartition('.')[0]
+        mname = '.'.join((pkg, '_libwebp')).lstrip('.')
+        try:
+            return importlib.import_module(mname)
+        except ImportError:
+            return importlib.import_module('_libwebp')
+    _libwebp = swig_import_helper()
+    del swig_import_helper
+elif _swig_python_version_info >= (2, 6, 0):
     def swig_import_helper():
         from os.path import dirname
         import imp
@@ -17,122 +26,143 @@
         except ImportError:
             import _libwebp
             return _libwebp
-        if fp is not None:
-            try:
-                _mod = imp.load_module('_libwebp', fp, pathname, description)
-            finally:
+        try:
+            _mod = imp.load_module('_libwebp', fp, pathname, description)
+        finally:
+            if fp is not None:
                 fp.close()
-            return _mod
+        return _mod
     _libwebp = swig_import_helper()
     del swig_import_helper
 else:
     import _libwebp
-del version_info
+del _swig_python_version_info
+
 try:
     _swig_property = property
 except NameError:
-    pass # Python < 2.2 doesn't have 'property'.
-def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
-    if (name == "thisown"): return self.this.own(value)
+    pass  # Python < 2.2 doesn't have 'property'.
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
+    if (name == "thisown"):
+        return self.this.own(value)
     if (name == "this"):
         if type(value).__name__ == 'SwigPyObject':
             self.__dict__[name] = value
             return
-    method = class_type.__swig_setmethods__.get(name,None)
-    if method: return method(self,value)
+    method = class_type.__swig_setmethods__.get(name, None)
+    if method:
+        return method(self, value)
     if (not static):
-        self.__dict__[name] = value
+        if _newclass:
+            object.__setattr__(self, name, value)
+        else:
+            self.__dict__[name] = value
     else:
         raise AttributeError("You cannot add attributes to %s" % self)
 
-def _swig_setattr(self,class_type,name,value):
-    return _swig_setattr_nondynamic(self,class_type,name,value,0)
 
-def _swig_getattr(self,class_type,name):
-    if (name == "thisown"): return self.this.own()
-    method = class_type.__swig_getmethods__.get(name,None)
-    if method: return method(self)
-    raise AttributeError(name)
+def _swig_setattr(self, class_type, name, value):
+    return _swig_setattr_nondynamic(self, class_type, name, value, 0)
+
+
+def _swig_getattr(self, class_type, name):
+    if (name == "thisown"):
+        return self.this.own()
+    method = class_type.__swig_getmethods__.get(name, None)
+    if method:
+        return method(self)
+    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
+
 
 def _swig_repr(self):
-    try: strthis = "proxy of " + self.this.__repr__()
-    except: strthis = ""
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
     return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
 
 try:
     _object = object
     _newclass = 1
-except AttributeError:
-    class _object : pass
+except __builtin__.Exception:
+    class _object:
+        pass
     _newclass = 0
 
 
-
 def WebPGetDecoderVersion():
-  """WebPGetDecoderVersion() -> int"""
-  return _libwebp.WebPGetDecoderVersion()
+    """WebPGetDecoderVersion() -> int"""
+    return _libwebp.WebPGetDecoderVersion()
 
-def WebPGetInfo(*args):
-  """WebPGetInfo(uint8_t data) -> (width, height)"""
-  return _libwebp.WebPGetInfo(*args)
+def WebPGetInfo(data):
+    """WebPGetInfo(uint8_t data) -> (width, height)"""
+    return _libwebp.WebPGetInfo(data)
 
-def WebPDecodeRGB(*args):
-  """WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"""
-  return _libwebp.WebPDecodeRGB(*args)
+def WebPDecodeRGB(data):
+    """WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"""
+    return _libwebp.WebPDecodeRGB(data)
 
-def WebPDecodeRGBA(*args):
-  """WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"""
-  return _libwebp.WebPDecodeRGBA(*args)
+def WebPDecodeRGBA(data):
+    """WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"""
+    return _libwebp.WebPDecodeRGBA(data)
 
-def WebPDecodeARGB(*args):
-  """WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"""
-  return _libwebp.WebPDecodeARGB(*args)
+def WebPDecodeARGB(data):
+    """WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"""
+    return _libwebp.WebPDecodeARGB(data)
 
-def WebPDecodeBGR(*args):
-  """WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"""
-  return _libwebp.WebPDecodeBGR(*args)
+def WebPDecodeBGR(data):
+    """WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"""
+    return _libwebp.WebPDecodeBGR(data)
 
-def WebPDecodeBGRA(*args):
-  """WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"""
-  return _libwebp.WebPDecodeBGRA(*args)
+def WebPDecodeBGRA(data):
+    """WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"""
+    return _libwebp.WebPDecodeBGRA(data)
 
 def WebPGetEncoderVersion():
-  """WebPGetEncoderVersion() -> int"""
-  return _libwebp.WebPGetEncoderVersion()
+    """WebPGetEncoderVersion() -> int"""
+    return _libwebp.WebPGetEncoderVersion()
 
-def wrap_WebPEncodeRGB(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeRGB(*args)
+def wrap_WebPEncodeRGB(rgb, unused1, unused2, width, height, stride, quality_factor):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeRGB(rgb, unused1, unused2, width, height, stride, quality_factor)
 
-def wrap_WebPEncodeBGR(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeBGR(*args)
+def wrap_WebPEncodeBGR(rgb, unused1, unused2, width, height, stride, quality_factor):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeBGR(rgb, unused1, unused2, width, height, stride, quality_factor)
 
-def wrap_WebPEncodeRGBA(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeRGBA(*args)
+def wrap_WebPEncodeRGBA(rgb, unused1, unused2, width, height, stride, quality_factor):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeRGBA(rgb, unused1, unused2, width, height, stride, quality_factor)
 
-def wrap_WebPEncodeBGRA(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeBGRA(*args)
+def wrap_WebPEncodeBGRA(rgb, unused1, unused2, width, height, stride, quality_factor):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeBGRA(rgb, unused1, unused2, width, height, stride, quality_factor)
 
-def wrap_WebPEncodeLosslessRGB(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeLosslessRGB(*args)
+def wrap_WebPEncodeLosslessRGB(rgb, unused1, unused2, width, height, stride):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeLosslessRGB(rgb, unused1, unused2, width, height, stride)
 
-def wrap_WebPEncodeLosslessBGR(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeLosslessBGR(*args)
+def wrap_WebPEncodeLosslessBGR(rgb, unused1, unused2, width, height, stride):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeLosslessBGR(rgb, unused1, unused2, width, height, stride)
 
-def wrap_WebPEncodeLosslessRGBA(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeLosslessRGBA(*args)
+def wrap_WebPEncodeLosslessRGBA(rgb, unused1, unused2, width, height, stride):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeLosslessRGBA(rgb, unused1, unused2, width, height, stride)
 
-def wrap_WebPEncodeLosslessBGRA(*args):
-  """private, do not call directly."""
-  return _libwebp.wrap_WebPEncodeLosslessBGRA(*args)
+def wrap_WebPEncodeLosslessBGRA(rgb, unused1, unused2, width, height, stride):
+    """private, do not call directly."""
+    return _libwebp.wrap_WebPEncodeLosslessBGRA(rgb, unused1, unused2, width, height, stride)
+
 _UNUSED = 1
 
+
 def WebPEncodeRGB(rgb, width, height, stride, quality_factor):
   """WebPEncodeRGB(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
   webp = wrap_WebPEncodeRGB(
@@ -141,6 +171,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeRGBA(rgb, width, height, stride, quality_factor):
   """WebPEncodeRGBA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
   webp = wrap_WebPEncodeRGBA(
@@ -149,6 +180,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeBGR(rgb, width, height, stride, quality_factor):
   """WebPEncodeBGR(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
   webp = wrap_WebPEncodeBGR(
@@ -157,6 +189,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeBGRA(rgb, width, height, stride, quality_factor):
   """WebPEncodeBGRA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
   webp = wrap_WebPEncodeBGRA(
@@ -165,6 +198,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeLosslessRGB(rgb, width, height, stride):
   """WebPEncodeLosslessRGB(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
   webp = wrap_WebPEncodeLosslessRGB(rgb, _UNUSED, _UNUSED, width, height, stride)
@@ -172,6 +206,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeLosslessRGBA(rgb, width, height, stride):
   """WebPEncodeLosslessRGBA(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
   webp = wrap_WebPEncodeLosslessRGBA(rgb, _UNUSED, _UNUSED, width, height, stride)
@@ -179,6 +214,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeLosslessBGR(rgb, width, height, stride):
   """WebPEncodeLosslessBGR(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
   webp = wrap_WebPEncodeLosslessBGR(rgb, _UNUSED, _UNUSED, width, height, stride)
@@ -186,6 +222,7 @@
     return None
   return webp[0]
 
+
 def WebPEncodeLosslessBGRA(rgb, width, height, stride):
   """WebPEncodeLosslessBGRA(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
   webp = wrap_WebPEncodeLosslessBGRA(rgb, _UNUSED, _UNUSED, width, height, stride)
diff --git a/third_party/libwebp/swig/libwebp.swig b/third_party/libwebp/swig/libwebp.swig
index 17748b9..ca38298 100644
--- a/third_party/libwebp/swig/libwebp.swig
+++ b/third_party/libwebp/swig/libwebp.swig
@@ -32,6 +32,9 @@
 
 #ifdef SWIGPYTHON
 %module(package="com.google.webp") libwebp
+%begin %{
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
+%}
 #else
 %module libwebp
 #endif  /* SWIGPYTHON */
diff --git a/third_party/libwebp/swig/libwebp_python_wrap.c b/third_party/libwebp/swig/libwebp_python_wrap.c
index b29f834..3aa2728 100644
--- a/third_party/libwebp/swig/libwebp_python_wrap.c
+++ b/third_party/libwebp/swig/libwebp_python_wrap.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------------
  * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 2.0.4
+ * Version 3.0.12
  *
  * This file is not intended to be easily readable and contains a number of
  * coding conventions designed to improve portability and efficiency. Do not make
@@ -8,7 +8,14 @@
  * interface file instead.
  * ----------------------------------------------------------------------------- */
 
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
+
+
+
+#ifndef SWIGPYTHON
 #define SWIGPYTHON
+#endif
+
 #define SWIG_PYTHON_DIRECTOR_NO_VTABLE
 
 /* -----------------------------------------------------------------------------
@@ -78,9 +85,11 @@
 #endif
 
 /* exporting methods */
-#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-#  ifndef GCC_HASCLASSVISIBILITY
-#    define GCC_HASCLASSVISIBILITY
+#if defined(__GNUC__)
+#  if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#    ifndef GCC_HASCLASSVISIBILITY
+#      define GCC_HASCLASSVISIBILITY
+#    endif
 #  endif
 #endif
 
@@ -119,10 +128,29 @@
 # define _SCL_SECURE_NO_DEPRECATE
 #endif
 
+/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */
+#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES)
+# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
+#endif
+
+/* Intel's compiler complains if a variable which was never initialised is
+ * cast to void, which is a common idiom which we use to indicate that we
+ * are aware a variable isn't used.  So we just silence that warning.
+ * See: https://github.com/swig/swig/issues/192 for more discussion.
+ */
+#ifdef __INTEL_COMPILER
+# pragma warning disable 592
+#endif
 
 
-/* Python.h has to appear first */
-#include <Python.h>
+#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
+/* Use debug wrappers with the Python release dll */
+# undef _DEBUG
+# include <Python.h>
+# define _DEBUG
+#else
+# include <Python.h>
+#endif
 
 /* -----------------------------------------------------------------------------
  * swigrun.swg
@@ -294,7 +322,7 @@
   return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
 }
 #else /* no cast-rank mode */
-#  define SWIG_AddCast
+#  define SWIG_AddCast(r) (r)
 #  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
 #endif
 
@@ -358,18 +386,18 @@
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if not equal, 1 if equal
+  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
 */
 SWIGRUNTIME int
-SWIG_TypeEquiv(const char *nb, const char *tb) {
-  int equiv = 0;
+SWIG_TypeCmp(const char *nb, const char *tb) {
+  int equiv = 1;
   const char* te = tb + strlen(tb);
   const char* ne = nb;
-  while (!equiv && *ne) {
+  while (equiv != 0 && *ne) {
     for (nb = ne; *ne; ++ne) {
       if (*ne == '|') break;
     }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
     if (*ne) ++ne;
   }
   return equiv;
@@ -377,24 +405,13 @@
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+  Return 0 if not equal, 1 if equal
 */
 SWIGRUNTIME int
-SWIG_TypeCompare(const char *nb, const char *tb) {
-  int equiv = 0;
-  const char* te = tb + strlen(tb);
-  const char* ne = nb;
-  while (!equiv && *ne) {
-    for (nb = ne; *ne; ++ne) {
-      if (*ne == '|') break;
-    }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
-    if (*ne) ++ne;
-  }
-  return equiv;
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
 }
 
-
 /*
   Check the typename
 */
@@ -541,14 +558,14 @@
   swig_module_info *iter = start;
   do {
     if (iter->size) {
-      register size_t l = 0;
-      register size_t r = iter->size - 1;
+      size_t l = 0;
+      size_t r = iter->size - 1;
       do {
         /* since l+r >= 0, we can (>> 1) instead (/ 2) */
-        register size_t i = (l + r) >> 1;
+        size_t i = (l + r) >> 1;
         const char *iname = iter->types[i]->name;
         if (iname) {
-          register int compare = strcmp(name, iname);
+          int compare = strcmp(name, iname);
           if (compare == 0) {
             return iter->types[i];
           } else if (compare < 0) {
@@ -592,7 +609,7 @@
        of the str field (the human readable name) */
     swig_module_info *iter = start;
     do {
-      register size_t i = 0;
+      size_t i = 0;
       for (; i < iter->size; ++i) {
         if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
           return iter->types[i];
@@ -611,10 +628,10 @@
 SWIGRUNTIME char *
 SWIG_PackData(char *c, void *ptr, size_t sz) {
   static const char hex[17] = "0123456789abcdef";
-  register const unsigned char *u = (unsigned char *) ptr;
-  register const unsigned char *eu =  u + sz;
+  const unsigned char *u = (unsigned char *) ptr;
+  const unsigned char *eu =  u + sz;
   for (; u != eu; ++u) {
-    register unsigned char uu = *u;
+    unsigned char uu = *u;
     *(c++) = hex[(uu & 0xf0) >> 4];
     *(c++) = hex[uu & 0xf];
   }
@@ -626,22 +643,22 @@
 */
 SWIGRUNTIME const char *
 SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
-  register unsigned char *u = (unsigned char *) ptr;
-  register const unsigned char *eu = u + sz;
+  unsigned char *u = (unsigned char *) ptr;
+  const unsigned char *eu = u + sz;
   for (; u != eu; ++u) {
-    register char d = *(c++);
-    register unsigned char uu;
+    char d = *(c++);
+    unsigned char uu;
     if ((d >= '0') && (d <= '9'))
-      uu = ((d - '0') << 4);
+      uu = (unsigned char)((d - '0') << 4);
     else if ((d >= 'a') && (d <= 'f'))
-      uu = ((d - ('a'-10)) << 4);
+      uu = (unsigned char)((d - ('a'-10)) << 4);
     else
       return (char *) 0;
     d = *(c++);
     if ((d >= '0') && (d <= '9'))
-      uu |= (d - '0');
+      uu |= (unsigned char)(d - '0');
     else if ((d >= 'a') && (d <= 'f'))
-      uu |= (d - ('a'-10));
+      uu |= (unsigned char)(d - ('a'-10));
     else
       return (char *) 0;
     *u = uu;
@@ -732,8 +749,10 @@
 #define PyInt_Check(x) PyLong_Check(x)
 #define PyInt_AsLong(x) PyLong_AsLong(x)
 #define PyInt_FromLong(x) PyLong_FromLong(x)
+#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
 #define PyString_Check(name) PyBytes_Check(name)
 #define PyString_FromString(x) PyUnicode_FromString(x)
+#define PyString_FromStringAndSize(x, y) PyBytes_FromStringAndSize(x, y)
 #define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
 #define PyString_AsString(str) PyBytes_AsString(str)
 #define PyString_Size(str) PyBytes_Size(str)
@@ -823,10 +842,6 @@
 }
 #endif
 
-/* Add PyObject_Del for old Pythons */
-#if PY_VERSION_HEX < 0x01060000
-# define PyObject_Del(op) PyMem_DEL((op))
-#endif
 #ifndef PyObject_DEL
 # define PyObject_DEL PyObject_Del
 #endif
@@ -901,6 +916,10 @@
 }
 #endif
 
+#if PY_VERSION_HEX < 0x02050000
+#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
+#endif
+
 #if PY_VERSION_HEX < 0x02040000
 #define Py_VISIT(op)                            \
   do {                                          \
@@ -937,6 +956,7 @@
 #if PY_VERSION_HEX < 0x03020000
 #define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
 #define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
+#define Py_hash_t long
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -1172,7 +1192,7 @@
 
 /* Runtime API */
 
-#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule()
+#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
 #define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
 #define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
 
@@ -1198,7 +1218,7 @@
 SWIGINTERN void
 SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
   SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-  PyErr_SetString(errtype, (char *) msg);
+  PyErr_SetString(errtype, msg);
   SWIG_PYTHON_THREAD_END_BLOCK;
 }
 
@@ -1217,7 +1237,11 @@
 
 SWIGINTERN void
 SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {
+#if PY_VERSION_HEX < 0x02030000
   PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
   Py_DECREF(obj);
   if (public_interface)
     SwigPyBuiltin_AddPublicSymbol(public_interface, name);
@@ -1227,7 +1251,11 @@
 
 SWIGINTERN void
 SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
+#if PY_VERSION_HEX < 0x02030000
   PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
   Py_DECREF(obj);
 }
 
@@ -1280,7 +1308,7 @@
 
 /* Unpack the argument tuple */
 
-SWIGINTERN int
+SWIGINTERN Py_ssize_t
 SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
 {
   if (!args) {
@@ -1294,7 +1322,7 @@
   }
   if (!PyTuple_Check(args)) {
     if (min <= 1 && max >= 1) {
-      register int i;
+      Py_ssize_t i;
       objs[0] = args;
       for (i = 1; i < max; ++i) {
         objs[i] = 0;
@@ -1304,7 +1332,7 @@
     PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
     return 0;
   } else {
-    register Py_ssize_t l = PyTuple_GET_SIZE(args);
+    Py_ssize_t l = PyTuple_GET_SIZE(args);
     if (l < min) {
       PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
                    name, (min == max ? "" : "at least "), (int)min, (int)l);
@@ -1314,7 +1342,7 @@
                    name, (min == max ? "" : "at most "), (int)max, (int)l);
       return 0;
     } else {
-      register int i;
+      Py_ssize_t i;
       for (i = 0; i < l; ++i) {
         objs[i] = PyTuple_GET_ITEM(args, i);
       }
@@ -1500,6 +1528,23 @@
 #endif
 } SwigPyObject;
 
+
+#ifdef SWIGPYTHON_BUILTIN
+
+SWIGRUNTIME PyObject *
+SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
+{
+  SwigPyObject *sobj = (SwigPyObject *)v;
+
+  if (!sobj->dict)
+    sobj->dict = PyDict_New();
+
+  Py_INCREF(sobj->dict);
+  return sobj->dict;
+}
+
+#endif
+
 SWIGRUNTIME PyObject *
 SwigPyObject_long(SwigPyObject *v)
 {
@@ -1548,7 +1593,7 @@
 #endif
 {
   const char *name = SWIG_TypePrettyName(v->ty);
-  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", name, (void *)v);
+  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
   if (v->next) {
 # ifdef METH_NOARGS
     PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
@@ -1567,32 +1612,12 @@
   return repr;
 }
 
-SWIGRUNTIME int
-SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
-{
-  char *str;
-#ifdef METH_NOARGS
-  PyObject *repr = SwigPyObject_repr(v);
-#else
-  PyObject *repr = SwigPyObject_repr(v, NULL);
-#endif
-  if (repr) {
-    str = SWIG_Python_str_AsChar(repr);
-    fputs(str, fp);
-    SWIG_Python_str_DelForPy3(str);
-    Py_DECREF(repr);
-    return 0;
-  } else {
-    return 1;
-  }
-}
-
+/* We need a version taking two PyObject* parameters so it's a valid
+ * PyCFunction to use in swigobject_methods[]. */
 SWIGRUNTIME PyObject *
-SwigPyObject_str(SwigPyObject *v)
+SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
 {
-  char result[SWIG_BUFFER_SIZE];
-  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
-    SWIG_Python_str_FromChar(result) : 0;
+  return SwigPyObject_repr((SwigPyObject*)v);
 }
 
 SWIGRUNTIME int
@@ -1666,6 +1691,17 @@
     if (destroy) {
       /* destroy is always a VARARGS method */
       PyObject *res;
+
+      /* PyObject_CallFunction() has the potential to silently drop
+         the active active exception.  In cases of unnamed temporary
+         variable or where we just finished iterating over a generator
+         StopIteration will be active right now, and this needs to
+         remain true upon return from SwigPyObject_dealloc.  So save
+         and restore. */
+
+      PyObject *val = NULL, *type = NULL, *tb = NULL;
+      PyErr_Fetch(&val, &type, &tb);
+
       if (data->delargs) {
         /* we need to create a temporary object to carry the destroy operation */
         PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
@@ -1676,6 +1712,11 @@
         PyObject *mself = PyCFunction_GET_SELF(destroy);
         res = ((*meth)(mself, v));
       }
+      if (!res)
+        PyErr_WriteUnraisable(destroy);
+
+      PyErr_Restore(val, type, tb);
+
       Py_XDECREF(res);
     }
 #if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
@@ -1699,6 +1740,7 @@
   next = tmp;
 #endif
   if (!SwigPyObject_Check(next)) {
+    PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
     return NULL;
   }
   sobj->next = next;
@@ -1707,11 +1749,7 @@
 }
 
 SWIGRUNTIME PyObject*
-#ifdef METH_NOARGS
-SwigPyObject_next(PyObject* v)
-#else
 SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-#endif
 {
   SwigPyObject *sobj = (SwigPyObject *) v;
   if (sobj->next) {
@@ -1746,14 +1784,30 @@
   return SWIG_Py_Void();
 }
 
+#ifdef METH_NOARGS
+static PyObject*
+SwigPyObject_disown2(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+{
+  return SwigPyObject_disown(v);
+}
+
+static PyObject*
+SwigPyObject_acquire2(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+{
+  return SwigPyObject_acquire(v);
+}
+#endif
+
 SWIGINTERN PyObject*
 SwigPyObject_own(PyObject *v, PyObject *args)
 {
   PyObject *val = 0;
 #if (PY_VERSION_HEX < 0x02020000)
   if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
-#else
+#elif (PY_VERSION_HEX < 0x02050000)
   if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
+#else
+  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val))
 #endif
     {
       return NULL;
@@ -1784,23 +1838,23 @@
 #ifdef METH_O
 static PyMethodDef
 swigobject_methods[] = {
-  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
-  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"aquires ownership of the pointer"},
+  {(char *)"disown",  (PyCFunction)SwigPyObject_disown2, METH_NOARGS,  (char *)"releases ownership of the pointer"},
+  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire2,METH_NOARGS,  (char *)"acquires ownership of the pointer"},
   {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
   {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
   {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
-  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
+  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr2,   METH_NOARGS,  (char *)"returns object representation"},
   {0, 0, 0, 0}
 };
 #else
 static PyMethodDef
 swigobject_methods[] = {
   {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
-  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
+  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"acquires ownership of the pointer"},
   {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
   {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
   {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
-  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
+  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_VARARGS,  (char *)"returns object representation"},
   {0, 0, 0, 0}
 };
 #endif
@@ -1852,7 +1906,9 @@
     (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
     (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
 #endif
-#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
+#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */
+#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
 #elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
@@ -1867,7 +1923,6 @@
   static int type_init = 0;
   if (!type_init) {
     const PyTypeObject tmp = {
-      /* PyObject header changed in Python 3 */
 #if PY_VERSION_HEX >= 0x03000000
       PyVarObject_HEAD_INIT(NULL, 0)
 #else
@@ -1878,7 +1933,7 @@
       sizeof(SwigPyObject),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
-      (printfunc)SwigPyObject_print,        /* tp_print */
+      0,                                    /* tp_print */
 #if PY_VERSION_HEX < 0x02020000
       (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
 #else
@@ -1886,7 +1941,7 @@
 #endif
       (setattrfunc)0,                       /* tp_setattr */
 #if PY_VERSION_HEX >= 0x03000000
-    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
+      0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
 #else
       (cmpfunc)SwigPyObject_compare,        /* tp_compare */
 #endif
@@ -1896,7 +1951,7 @@
       0,                                    /* tp_as_mapping */
       (hashfunc)0,                          /* tp_hash */
       (ternaryfunc)0,                       /* tp_call */
-      (reprfunc)SwigPyObject_str,           /* tp_str */
+      0,                                    /* tp_str */
       PyObject_GenericGetAttr,              /* tp_getattro */
       0,                                    /* tp_setattro */
       0,                                    /* tp_as_buffer */
@@ -1932,10 +1987,19 @@
       0,                                    /* tp_del */
 #endif
 #if PY_VERSION_HEX >= 0x02060000
-      0,                                    /* tp_version */
+      0,                                    /* tp_version_tag */
+#endif
+#if PY_VERSION_HEX >= 0x03040000
+      0,                                    /* tp_finalize */
 #endif
 #ifdef COUNT_ALLOCS
-      0,0,0,0                               /* tp_alloc -> tp_next */
+      0,                                    /* tp_allocs */
+      0,                                    /* tp_frees */
+      0,                                    /* tp_maxalloc */
+#if PY_VERSION_HEX >= 0x02050000
+      0,                                    /* tp_prev */
+#endif
+      0                                     /* tp_next */
 #endif
     };
     swigpyobject_type = tmp;
@@ -2050,7 +2114,6 @@
   static int type_init = 0;
   if (!type_init) {
     const PyTypeObject tmp = {
-      /* PyObject header changed in Python 3 */
 #if PY_VERSION_HEX>=0x03000000
       PyVarObject_HEAD_INIT(NULL, 0)
 #else
@@ -2111,10 +2174,19 @@
       0,                                    /* tp_del */
 #endif
 #if PY_VERSION_HEX >= 0x02060000
-      0,                                    /* tp_version */
+      0,                                    /* tp_version_tag */
+#endif
+#if PY_VERSION_HEX >= 0x03040000
+      0,                                    /* tp_finalize */
 #endif
 #ifdef COUNT_ALLOCS
-      0,0,0,0                               /* tp_alloc -> tp_next */
+      0,                                    /* tp_allocs */
+      0,                                    /* tp_frees */
+      0,                                    /* tp_maxalloc */
+#if PY_VERSION_HEX >= 0x02050000
+      0,                                    /* tp_prev */
+#endif
+      0                                     /* tp_next */
 #endif
     };
     swigpypacked_type = tmp;
@@ -2273,10 +2345,11 @@
 SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
   int res;
   SwigPyObject *sobj;
+  int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0;
 
   if (!obj)
     return SWIG_ERROR;
-  if (obj == Py_None) {
+  if (obj == Py_None && !implicit_conv) {
     if (ptr)
       *ptr = 0;
     return SWIG_OK;
@@ -2325,7 +2398,7 @@
     }
     res = SWIG_OK;
   } else {
-    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+    if (implicit_conv) {
       SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
       if (data && !data->implicitconv) {
         PyObject *klass = data->klass;
@@ -2360,6 +2433,13 @@
         }
       }
     }
+    if (!SWIG_IsOK(res) && obj == Py_None) {
+      if (ptr)
+        *ptr = 0;
+      if (PyErr_Occurred())
+        PyErr_Clear();
+      res = SWIG_OK;
+    }
   }
   return res;
 }
@@ -2447,24 +2527,30 @@
     }
   } else {
 #if PY_VERSION_HEX >= 0x03000000
-    inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
-    PyObject_SetAttr(inst, SWIG_This(), swig_this);
-    Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+    inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
+    if (inst) {
+      PyObject_SetAttr(inst, SWIG_This(), swig_this);
+      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+    }
 #else
     PyObject *dict = PyDict_New();
-    PyDict_SetItem(dict, SWIG_This(), swig_this);
-    inst = PyInstance_NewRaw(data->newargs, dict);
-    Py_DECREF(dict);
+    if (dict) {
+      PyDict_SetItem(dict, SWIG_This(), swig_this);
+      inst = PyInstance_NewRaw(data->newargs, dict);
+      Py_DECREF(dict);
+    }
 #endif
   }
   return inst;
 #else
 #if (PY_VERSION_HEX >= 0x02010000)
-  PyObject *inst;
+  PyObject *inst = 0;
   PyObject *dict = PyDict_New();
-  PyDict_SetItem(dict, SWIG_This(), swig_this);
-  inst = PyInstance_NewRaw(data->newargs, dict);
-  Py_DECREF(dict);
+  if (dict) {
+    PyDict_SetItem(dict, SWIG_This(), swig_this);
+    inst = PyInstance_NewRaw(data->newargs, dict);
+    Py_DECREF(dict);
+  }
   return (PyObject *) inst;
 #else
   PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
@@ -2515,7 +2601,7 @@
 SWIGINTERN PyObject *
 SWIG_Python_InitShadowInstance(PyObject *args) {
   PyObject *obj[2];
-  if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
     return NULL;
   } else {
     SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
@@ -2551,18 +2637,21 @@
           newobj = (SwigPyObject *) newobj->next;
         newobj->next = next_self;
         newobj = (SwigPyObject *)next_self;
+#ifdef SWIGPYTHON_BUILTIN
+        newobj->dict = 0;
+#endif
       }
     } else {
       newobj = PyObject_New(SwigPyObject, clientdata->pytype);
+#ifdef SWIGPYTHON_BUILTIN
+      newobj->dict = 0;
+#endif
     }
     if (newobj) {
       newobj->ptr = ptr;
       newobj->ty = type;
       newobj->own = own;
       newobj->next = 0;
-#ifdef SWIGPYTHON_BUILTIN
-      newobj->dict = 0;
-#endif
       return (PyObject*) newobj;
     }
     return SWIG_Py_Void();
@@ -2571,12 +2660,10 @@
   assert(!(flags & SWIG_BUILTIN_TP_INIT));
 
   robj = SwigPyObject_New(ptr, type, own);
-  if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
     PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
-    if (inst) {
-      Py_DECREF(robj);
-      robj = inst;
-    }
+    Py_DECREF(robj);
+    robj = inst;
   }
   return robj;
 }
@@ -2597,7 +2684,7 @@
 #endif
 
 SWIGRUNTIME swig_module_info *
-SWIG_Python_GetModule(void) {
+SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
   static void *type_pointer = (void *)0;
   /* first check if module already created */
   if (!type_pointer) {
@@ -2627,13 +2714,11 @@
 {
   PyObject *dict;
   if (!PyModule_Check(m)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "PyModule_AddObject() needs module as first arg");
+    PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs module as first arg");
     return SWIG_ERROR;
   }
   if (!o) {
-    PyErr_SetString(PyExc_TypeError,
-                    "PyModule_AddObject() needs non-NULL value");
+    PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs non-NULL value");
     return SWIG_ERROR;
   }
 
@@ -2679,7 +2764,7 @@
 SWIGRUNTIME void
 SWIG_Python_SetModule(swig_module_info *swig_module) {
 #if PY_VERSION_HEX >= 0x03000000
- /* Add a dummy module object into sys.modules */
+ /* Add a placeholder module object into sys.modules */
   PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
 #else
   static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
@@ -2723,7 +2808,7 @@
     descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
 #endif
   } else {
-    swig_module_info *swig_module = SWIG_Python_GetModule();
+    swig_module_info *swig_module = SWIG_GetModule(0);
     descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
     if (descriptor) {
 #ifdef SWIGPY_USE_CAPSULE
@@ -2791,7 +2876,7 @@
 {
   SwigPyObject *v = (SwigPyObject *)self;
   swig_type_info *ty = v ? v->ty : 0;
-  return ty ? ty->str : (char*)"";
+  return ty ? ty->str : "";
 }
 
 SWIGRUNTIME void
@@ -2848,23 +2933,24 @@
   return result;
 }
 
+#ifdef SWIGPYTHON_BUILTIN
 SWIGRUNTIME int
 SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
   PyTypeObject *tp = obj->ob_type;
   PyObject *descr;
   PyObject *encoded_name;
   descrsetfunc f;
-  int res;
+  int res = -1;
 
-#ifdef Py_USING_UNICODE
+# ifdef Py_USING_UNICODE
   if (PyString_Check(name)) {
     name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
     if (!name)
       return -1;
   } else if (!PyUnicode_Check(name))
-#else
+# else
   if (!PyString_Check(name))
-#endif
+# endif
   {
     PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
     return -1;
@@ -2877,7 +2963,6 @@
       goto done;
   }
 
-  res = -1;
   descr = _PyType_Lookup(tp, name);
   f = NULL;
   if (descr != NULL)
@@ -2899,6 +2984,7 @@
   Py_DECREF(name);
   return res;
 }
+#endif
 
 
 #ifdef __cplusplus
@@ -2946,7 +3032,7 @@
 #endif
 #define SWIG_name    "_libwebp"
 
-#define SWIGVERSION 0x020004
+#define SWIGVERSION 0x030012
 #define SWIG_VERSION SWIGVERSION
 
 
@@ -2954,13 +3040,10 @@
 #define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a))
 
 
-  #define SWIG_From_long   PyInt_FromLong
-
-
-SWIGINTERNINLINE PyObject *
-SWIG_From_int  (int value)
+SWIGINTERNINLINE PyObject*
+  SWIG_From_int  (int value)
 {
-  return SWIG_From_long  (value);
+  return PyInt_FromLong((long) value);
 }
 
 
@@ -2981,13 +3064,18 @@
 SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
 {
 #if PY_VERSION_HEX>=0x03000000
+#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+  if (PyBytes_Check(obj))
+#else
   if (PyUnicode_Check(obj))
+#endif
 #else
   if (PyString_Check(obj))
 #endif
   {
     char *cstr; Py_ssize_t len;
 #if PY_VERSION_HEX>=0x03000000
+#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
     if (!alloc && cptr) {
         /* We can't allow converting without allocation, since the internal
            representation of string in Python 3 is UCS-2/UCS-4 but we require
@@ -2996,8 +3084,9 @@
         return SWIG_RuntimeError;
     }
     obj = PyUnicode_AsUTF8String(obj);
-    PyBytes_AsStringAndSize(obj, &cstr, &len);
     if(alloc) *alloc = SWIG_NEWOBJ;
+#endif
+    PyBytes_AsStringAndSize(obj, &cstr, &len);
 #else
     PyString_AsStringAndSize(obj, &cstr, &len);
 #endif
@@ -3017,27 +3106,58 @@
 #else
         if (*alloc == SWIG_NEWOBJ)
 #endif
-          {
-            *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
-            *alloc = SWIG_NEWOBJ;
-          }
-        else {
+        {
+          *cptr = (char *)memcpy(malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
+          *alloc = SWIG_NEWOBJ;
+        } else {
           *cptr = cstr;
           *alloc = SWIG_OLDOBJ;
         }
       } else {
-        #if PY_VERSION_HEX>=0x03000000
-        assert(0); /* Should never reach here in Python 3 */
-        #endif
+#if PY_VERSION_HEX>=0x03000000
+#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+        *cptr = PyBytes_AsString(obj);
+#else
+        assert(0); /* Should never reach here with Unicode strings in Python 3 */
+#endif
+#else
         *cptr = SWIG_Python_str_AsChar(obj);
+#endif
       }
     }
     if (psize) *psize = len + 1;
-#if PY_VERSION_HEX>=0x03000000
+#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
     Py_XDECREF(obj);
 #endif
     return SWIG_OK;
   } else {
+#if defined(SWIG_PYTHON_2_UNICODE)
+#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once"
+#endif
+#if PY_VERSION_HEX<0x03000000
+    if (PyUnicode_Check(obj)) {
+      char *cstr; Py_ssize_t len;
+      if (!alloc && cptr) {
+        return SWIG_RuntimeError;
+      }
+      obj = PyUnicode_AsUTF8String(obj);
+      if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) {
+        if (cptr) {
+          if (alloc) *alloc = SWIG_NEWOBJ;
+          *cptr = (char *)memcpy(malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
+        }
+        if (psize) *psize = len + 1;
+
+        Py_XDECREF(obj);
+        return SWIG_OK;
+      } else {
+        Py_XDECREF(obj);
+      }
+    }
+#endif
+#endif
+
     swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
     if (pchar_descriptor) {
       void* vptr = 0;
@@ -3060,9 +3180,11 @@
   if (PyFloat_Check(obj)) {
     if (val) *val = PyFloat_AsDouble(obj);
     return SWIG_OK;
+#if PY_VERSION_HEX < 0x03000000
   } else if (PyInt_Check(obj)) {
-    if (val) *val = PyInt_AsLong(obj);
+    if (val) *val = (double) PyInt_AsLong(obj);
     return SWIG_OK;
+#endif
   } else if (PyLong_Check(obj)) {
     double v = PyLong_AsDouble(obj);
     if (!PyErr_Occurred()) {
@@ -3136,6 +3258,7 @@
 SWIGINTERN int
 SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val)
 {
+#if PY_VERSION_HEX < 0x03000000
   if (PyInt_Check(obj)) {
     long v = PyInt_AsLong(obj);
     if (v >= 0) {
@@ -3144,13 +3267,16 @@
     } else {
       return SWIG_OverflowError;
     }
-  } else if (PyLong_Check(obj)) {
+  } else
+#endif
+  if (PyLong_Check(obj)) {
     unsigned long v = PyLong_AsUnsignedLong(obj);
     if (!PyErr_Occurred()) {
       if (val) *val = v;
       return SWIG_OK;
     } else {
       PyErr_Clear();
+      return SWIG_OverflowError;
     }
   }
 #ifdef SWIG_PYTHON_CAST_MODE
@@ -3177,12 +3303,79 @@
 }
 
 
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+#   define LLONG_MAX __LONG_LONG_MAX__
+#   define LLONG_MIN (-LLONG_MAX - 1LL)
+#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+
+
+#if defined(LLONG_MAX) && !defined(SWIG_LONG_LONG_AVAILABLE)
+#  define SWIG_LONG_LONG_AVAILABLE
+#endif
+
+
+#ifdef SWIG_LONG_LONG_AVAILABLE
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_long_SS_long (PyObject *obj, unsigned long long *val)
+{
+  int res = SWIG_TypeError;
+  if (PyLong_Check(obj)) {
+    unsigned long long v = PyLong_AsUnsignedLongLong(obj);
+    if (!PyErr_Occurred()) {
+      if (val) *val = v;
+      return SWIG_OK;
+    } else {
+      PyErr_Clear();
+      res = SWIG_OverflowError;
+    }
+  } else {
+    unsigned long v;
+    res = SWIG_AsVal_unsigned_SS_long (obj,&v);
+    if (SWIG_IsOK(res)) {
+      if (val) *val = v;
+      return res;
+    }
+  }
+#ifdef SWIG_PYTHON_CAST_MODE
+  {
+    const double mant_max = 1LL << DBL_MANT_DIG;
+    double d;
+    res = SWIG_AsVal_double (obj,&d);
+    if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, 0, mant_max))
+      return SWIG_OverflowError;
+    if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) {
+      if (val) *val = (unsigned long long)(d);
+      return SWIG_AddCast(res);
+    }
+    res = SWIG_TypeError;
+  }
+#endif
+  return res;
+}
+#endif
+
+
 SWIGINTERNINLINE int
 SWIG_AsVal_size_t (PyObject * obj, size_t *val)
 {
-  unsigned long v;
-  int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
-  if (SWIG_IsOK(res) && val) *val = (size_t)(v);
+  int res = SWIG_TypeError;
+#ifdef SWIG_LONG_LONG_AVAILABLE
+  if (sizeof(size_t) <= sizeof(unsigned long)) {
+#endif
+    unsigned long v;
+    res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
+    if (SWIG_IsOK(res) && val) *val = (size_t)(v);
+#ifdef SWIG_LONG_LONG_AVAILABLE
+  } else if (sizeof(size_t) <= sizeof(unsigned long long)) {
+    unsigned long long v;
+    res = SWIG_AsVal_unsigned_SS_long_SS_long (obj, val ? &v : 0);
+    if (SWIG_IsOK(res) && val) *val = (size_t)(v);
+  }
+#endif
   return res;
 }
 
@@ -3316,29 +3509,23 @@
 
 
 
-#include <limits.h>
-#if !defined(SWIG_NO_LLONG_MAX)
-# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
-#   define LLONG_MAX __LONG_LONG_MAX__
-#   define LLONG_MIN (-LLONG_MAX - 1LL)
-#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
-# endif
-#endif
-
-
 SWIGINTERN int
 SWIG_AsVal_long (PyObject *obj, long* val)
 {
+#if PY_VERSION_HEX < 0x03000000
   if (PyInt_Check(obj)) {
     if (val) *val = PyInt_AsLong(obj);
     return SWIG_OK;
-  } else if (PyLong_Check(obj)) {
+  } else
+#endif
+  if (PyLong_Check(obj)) {
     long v = PyLong_AsLong(obj);
     if (!PyErr_Occurred()) {
       if (val) *val = v;
       return SWIG_OK;
     } else {
       PyErr_Clear();
+      return SWIG_OverflowError;
     }
   }
 #ifdef SWIG_PYTHON_CAST_MODE
@@ -3381,13 +3568,51 @@
 }
 
 
+/* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */
+#ifndef SWIG_isfinite
+/* isfinite() is a macro for C99 */
+# if defined(isfinite)
+#  define SWIG_isfinite(X) (isfinite(X))
+# elif defined __cplusplus && __cplusplus >= 201103L
+/* Use a template so that this works whether isfinite() is std::isfinite() or
+ * in the global namespace.  The reality seems to vary between compiler
+ * versions.
+ *
+ * Make sure namespace std exists to avoid compiler warnings.
+ *
+ * extern "C++" is required as this fragment can end up inside an extern "C" { } block
+ */
+namespace std { }
+extern "C++" template<typename T>
+inline int SWIG_isfinite_func(T x) {
+  using namespace std;
+  return isfinite(x);
+}
+#  define SWIG_isfinite(X) (SWIG_isfinite_func(X))
+# elif defined(_MSC_VER)
+#  define SWIG_isfinite(X) (_finite(X))
+# elif defined(__sun) && defined(__SVR4)
+#  include <ieeefp.h>
+#  define SWIG_isfinite(X) (finite(X))
+# endif
+#endif
+
+
+/* Accept infinite as a valid float value unless we are unable to check if a value is finite */
+#ifdef SWIG_isfinite
+# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX) && SWIG_isfinite(X))
+#else
+# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX))
+#endif
+
+
 SWIGINTERN int
 SWIG_AsVal_float (PyObject * obj, float *val)
 {
   double v;
   int res = SWIG_AsVal_double (obj, &v);
   if (SWIG_IsOK(res)) {
-    if ((v < -FLT_MAX || v > FLT_MAX)) {
+    if (SWIG_Float_Overflow_Check(v)) {
       return SWIG_OverflowError;
     } else {
       if (val) *val = (float)(v);
@@ -4663,23 +4888,23 @@
 
 
 static PyMethodDef SwigMethods[] = {
-         { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
-         { (char *)"WebPGetDecoderVersion", _wrap_WebPGetDecoderVersion, METH_VARARGS, (char *)"WebPGetDecoderVersion() -> int"},
-         { (char *)"WebPGetInfo", _wrap_WebPGetInfo, METH_VARARGS, (char *)"WebPGetInfo(uint8_t data) -> (width, height)"},
-         { (char *)"WebPDecodeRGB", _wrap_WebPDecodeRGB, METH_VARARGS, (char *)"WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"},
-         { (char *)"WebPDecodeRGBA", _wrap_WebPDecodeRGBA, METH_VARARGS, (char *)"WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"},
-         { (char *)"WebPDecodeARGB", _wrap_WebPDecodeARGB, METH_VARARGS, (char *)"WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"},
-         { (char *)"WebPDecodeBGR", _wrap_WebPDecodeBGR, METH_VARARGS, (char *)"WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"},
-         { (char *)"WebPDecodeBGRA", _wrap_WebPDecodeBGRA, METH_VARARGS, (char *)"WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"},
-         { (char *)"WebPGetEncoderVersion", _wrap_WebPGetEncoderVersion, METH_VARARGS, (char *)"WebPGetEncoderVersion() -> int"},
-         { (char *)"wrap_WebPEncodeRGB", _wrap_wrap_WebPEncodeRGB, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeBGR", _wrap_wrap_WebPEncodeBGR, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeRGBA", _wrap_wrap_WebPEncodeRGBA, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeBGRA", _wrap_wrap_WebPEncodeBGRA, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeLosslessRGB", _wrap_wrap_WebPEncodeLosslessRGB, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeLosslessBGR", _wrap_wrap_WebPEncodeLosslessBGR, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeLosslessRGBA", _wrap_wrap_WebPEncodeLosslessRGBA, METH_VARARGS, (char *)"private, do not call directly."},
-         { (char *)"wrap_WebPEncodeLosslessBGRA", _wrap_wrap_WebPEncodeLosslessBGRA, METH_VARARGS, (char *)"private, do not call directly."},
+         { "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL},
+         { "WebPGetDecoderVersion", _wrap_WebPGetDecoderVersion, METH_VARARGS, (char *)"WebPGetDecoderVersion() -> int"},
+         { "WebPGetInfo", _wrap_WebPGetInfo, METH_VARARGS, (char *)"WebPGetInfo(uint8_t data) -> (width, height)"},
+         { "WebPDecodeRGB", _wrap_WebPDecodeRGB, METH_VARARGS, (char *)"WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"},
+         { "WebPDecodeRGBA", _wrap_WebPDecodeRGBA, METH_VARARGS, (char *)"WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"},
+         { "WebPDecodeARGB", _wrap_WebPDecodeARGB, METH_VARARGS, (char *)"WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"},
+         { "WebPDecodeBGR", _wrap_WebPDecodeBGR, METH_VARARGS, (char *)"WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"},
+         { "WebPDecodeBGRA", _wrap_WebPDecodeBGRA, METH_VARARGS, (char *)"WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"},
+         { "WebPGetEncoderVersion", _wrap_WebPGetEncoderVersion, METH_VARARGS, (char *)"WebPGetEncoderVersion() -> int"},
+         { "wrap_WebPEncodeRGB", _wrap_wrap_WebPEncodeRGB, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeBGR", _wrap_wrap_WebPEncodeBGR, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeRGBA", _wrap_wrap_WebPEncodeRGBA, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeBGRA", _wrap_wrap_WebPEncodeBGRA, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeLosslessRGB", _wrap_wrap_WebPEncodeLosslessRGB, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeLosslessBGR", _wrap_wrap_WebPEncodeLosslessBGR, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeLosslessRGBA", _wrap_wrap_WebPEncodeLosslessRGBA, METH_VARARGS, (char *)"private, do not call directly."},
+         { "wrap_WebPEncodeLosslessBGRA", _wrap_wrap_WebPEncodeLosslessBGRA, METH_VARARGS, (char *)"private, do not call directly."},
          { NULL, NULL, 0, NULL }
 };
 
@@ -4728,7 +4953,7 @@
  * array with the correct data and linking the correct swig_cast_info
  * structures together.
  *
- * The generated swig_type_info structures are assigned staticly to an initial
+ * The generated swig_type_info structures are assigned statically to an initial
  * array. We just loop through that array, and handle each type individually.
  * First we lookup if this type has been already loaded, and if so, use the
  * loaded structure instead of the generated one. Then we have to fill in the
@@ -4772,9 +4997,7 @@
 SWIG_InitializeModule(void *clientdata) {
   size_t i;
   swig_module_info *module_head, *iter;
-  int found, init;
-
-  clientdata = clientdata;
+  int init;
 
   /* check to see if the circular list has been setup, if not, set it up */
   if (swig_module.next==0) {
@@ -4793,27 +5016,23 @@
     /* This is the first module loaded for this interpreter */
     /* so set the swig module into the interpreter */
     SWIG_SetModule(clientdata, &swig_module);
-    module_head = &swig_module;
   } else {
     /* the interpreter has loaded a SWIG module, but has it loaded this one? */
-    found=0;
     iter=module_head;
     do {
       if (iter==&swig_module) {
-        found=1;
-        break;
+        /* Our module is already in the list, so there's nothing more to do. */
+        return;
       }
       iter=iter->next;
     } while (iter!= module_head);
 
-    /* if the is found in the list, then all is done and we may leave */
-    if (found) return;
-    /* otherwise we must add out module into the list */
+    /* otherwise we must add our module into the list */
     swig_module.next = module_head->next;
     module_head->next = &swig_module;
   }
 
-  /* When multiple interpeters are used, a module could have already been initialized in
+  /* When multiple interpreters are used, a module could have already been initialized in
        a different interpreter, but not yet have a pointer in this interpreter.
        In this case, we do not want to continue adding types... everything should be
        set up already */
@@ -5060,7 +5279,7 @@
       var = var->next;
     }
     if (res == NULL && !PyErr_Occurred()) {
-      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+      PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
     }
     return res;
   }
@@ -5077,7 +5296,7 @@
       var = var->next;
     }
     if (res == 1 && !PyErr_Occurred()) {
-      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+      PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
     }
     return res;
   }
@@ -5089,7 +5308,6 @@
     static int type_init = 0;
     if (!type_init) {
       const PyTypeObject tmp = {
-        /* PyObject header changed in Python 3 */
 #if PY_VERSION_HEX >= 0x03000000
         PyVarObject_HEAD_INIT(NULL, 0)
 #else
@@ -5127,10 +5345,19 @@
         0,                                  /* tp_del */
 #endif
 #if PY_VERSION_HEX >= 0x02060000
-        0,                                  /* tp_version */
+        0,                                  /* tp_version_tag */
+#endif
+#if PY_VERSION_HEX >= 0x03040000
+        0,                                  /* tp_finalize */
 #endif
 #ifdef COUNT_ALLOCS
-        0,0,0,0                             /* tp_alloc -> tp_next */
+        0,                                  /* tp_allocs */
+        0,                                  /* tp_frees */
+        0,                                  /* tp_maxalloc */
+#if PY_VERSION_HEX >= 0x02050000
+        0,                                  /* tp_prev */
+#endif
+        0                                   /* tp_next */
 #endif
       };
       varlink_type = tmp;
@@ -5219,7 +5446,9 @@
     size_t i;
     for (i = 0; methods[i].ml_name; ++i) {
       const char *c = methods[i].ml_doc;
-      if (c && (c = strstr(c, "swig_ptr: "))) {
+      if (!c) continue;
+      c = strstr(c, "swig_ptr: ");
+      if (c) {
         int j;
         swig_const_info *ci = 0;
         const char *name = c + 10;
@@ -5240,9 +5469,9 @@
             char *ndoc = (char*)malloc(ldoc + lptr + 10);
             if (ndoc) {
               char *buff = ndoc;
-              strncpy(buff, methods[i].ml_doc, ldoc);
+              memcpy(buff, methods[i].ml_doc, ldoc);
               buff += ldoc;
-              strncpy(buff, "swig_ptr: ", 10);
+              memcpy(buff, "swig_ptr: ", 10);
               buff += 10;
               SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
               methods[i].ml_doc = ndoc;
@@ -5304,23 +5533,24 @@
     (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
   };
   static SwigPyGetSet thisown_getset_closure = {
-    (PyCFunction) SwigPyObject_own,
-    (PyCFunction) SwigPyObject_own
+    SwigPyObject_own,
+    SwigPyObject_own
   };
   static PyGetSetDef thisown_getset_def = {
     (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
   };
-  PyObject *metatype_args;
   PyTypeObject *builtin_pytype;
   int builtin_base_count;
   swig_type_info *builtin_basetype;
   PyObject *tuple;
   PyGetSetDescrObject *static_getset;
   PyTypeObject *metatype;
+  PyTypeObject *swigpyobject;
   SwigPyClientData *cd;
   PyObject *public_interface, *public_symbol;
   PyObject *this_descr;
   PyObject *thisown_descr;
+  PyObject *self = 0;
   int i;
 
   (void)builtin_pytype;
@@ -5328,15 +5558,11 @@
   (void)builtin_basetype;
   (void)tuple;
   (void)static_getset;
+  (void)self;
 
-  /* metatype is used to implement static member variables. */
-  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
-  assert(metatype_args);
-  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
+  /* Metaclass is used to implement static member variables */
+  metatype = SwigPyObjectType();
   assert(metatype);
-  Py_DECREF(metatype_args);
-  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
-  assert(PyType_Ready(metatype) >= 0);
 #endif
 
   /* Fix SwigMethods to carry the callback ptrs when needed */
@@ -5347,18 +5573,22 @@
 #else
   m = Py_InitModule((char *) SWIG_name, SwigMethods);
 #endif
+
   md = d = PyModule_GetDict(m);
+  (void)md;
 
   SWIG_InitializeModule(0);
 
 #ifdef SWIGPYTHON_BUILTIN
+  swigpyobject = SwigPyObject_TypeOnce();
+
   SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
   assert(SwigPyObject_stype);
   cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
   if (!cd) {
     SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
-    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
-  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
+    SwigPyObject_clientdata.pytype = swigpyobject;
+  } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) {
     PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
 # if PY_VERSION_HEX >= 0x03000000
     return NULL;
diff --git a/third_party/libwebp/tests/README.md b/third_party/libwebp/tests/README.md
new file mode 100644
index 0000000..91daba2
--- /dev/null
+++ b/third_party/libwebp/tests/README.md
@@ -0,0 +1,18 @@
+# Tests
+
+This is a collection of tests for the libwebp libraries, currently covering
+fuzzing through the APIs. Additional test vector coverage can be found at:
+https://chromium.googlesource.com/webm/libwebp-test-data
+
+## Building
+
+### Fuzzers
+
+Follow the [build instructions](../doc/building.md) for libwebp, optionally
+adding build flags for various sanitizers (e.g., -fsanitize=address).
+
+`fuzzer/makefile.unix` can then be used to compile the fuzzer targets:
+
+```shell
+$ make -C fuzzer -f makefile.unix
+```
diff --git a/third_party/libwebp/tests/fuzzer/advanced_api_fuzzer.c b/third_party/libwebp/tests/fuzzer/advanced_api_fuzzer.c
new file mode 100644
index 0000000..c8fb176
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/advanced_api_fuzzer.c
@@ -0,0 +1,139 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stdint.h>
+#include <string.h>
+
+#include "./fuzz_utils.h"
+#include "src/utils/rescaler_utils.h"
+#include "src/webp/decode.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  WebPDecoderConfig config;
+  if (!WebPInitDecoderConfig(&config)) return 0;
+  if (WebPGetFeatures(data, size, &config.input) != VP8_STATUS_OK) return 0;
+  if ((size_t)config.input.width * config.input.height > kFuzzPxLimit) return 0;
+
+  // Using two independent criteria ensures that all combinations of options
+  // can reach each path at the decoding stage, with meaningful differences.
+
+  const uint8_t value = FuzzHash(data, size);
+  const float factor = value / 255.f;  // 0-1
+
+  config.options.flip = value & 1;
+  config.options.bypass_filtering = value & 2;
+  config.options.no_fancy_upsampling = value & 4;
+  config.options.use_threads = value & 8;
+  if (size & 1) {
+    config.options.use_cropping = 1;
+    config.options.crop_width = (int)(config.input.width * (1 - factor));
+    config.options.crop_height = (int)(config.input.height * (1 - factor));
+    config.options.crop_left = config.input.width - config.options.crop_width;
+    config.options.crop_top = config.input.height - config.options.crop_height;
+  }
+  if (size & 2) {
+    int strength = (int)(factor * 100);
+    config.options.dithering_strength = strength;
+    config.options.alpha_dithering_strength = 100 - strength;
+  }
+  if (size & 4) {
+    config.options.use_scaling = 1;
+    config.options.scaled_width = (int)(config.input.width * factor * 2);
+    config.options.scaled_height = (int)(config.input.height * factor * 2);
+  }
+
+#if defined(WEBP_REDUCE_CSP)
+  config.output.colorspace = (value & 1)
+                                 ? ((value & 2) ? MODE_RGBA : MODE_BGRA)
+                                 : ((value & 2) ? MODE_rgbA : MODE_bgrA);
+#else
+  config.output.colorspace = (WEBP_CSP_MODE)(value % MODE_LAST);
+#endif  // WEBP_REDUCE_CSP
+
+  for (int i = 0; i < 2; ++i) {
+    if (i == 1) {
+      // Use the bitstream data to generate extreme ranges for the options. An
+      // alternative approach would be to use a custom corpus containing webp
+      // files prepended with sizeof(config.options) zeroes to allow the fuzzer
+      // to modify these independently.
+      const int data_offset = 50;
+      if (data_offset + sizeof(config.options) >= size) break;
+      memcpy(&config.options, data + data_offset, sizeof(config.options));
+
+      // Skip easily avoidable out-of-memory fuzzing errors.
+      if (config.options.use_scaling) {
+        int scaled_width = config.options.scaled_width;
+        int scaled_height = config.options.scaled_height;
+        if (WebPRescalerGetScaledDimensions(config.input.width,
+                                            config.input.height, &scaled_width,
+                                            &scaled_height)) {
+          size_t fuzz_px_limit = kFuzzPxLimit;
+          if (scaled_width != config.input.width ||
+              scaled_height != config.input.height) {
+            // Using the WebPRescalerImport internally can significantly slow
+            // down the execution. Avoid timeouts due to that.
+            fuzz_px_limit /= 2;
+          }
+          // A big output canvas can lead to out-of-memory and timeout issues,
+          // but a big internal working buffer can too. Also, rescaling from a
+          // very wide input image to a very tall canvas can be as slow as
+          // decoding a huge number of pixels. Avoid timeouts due to these.
+          const uint64_t max_num_operations =
+              (uint64_t)Max(scaled_width, config.input.width) *
+              Max(scaled_height, config.input.height);
+          if (max_num_operations > fuzz_px_limit) {
+            break;
+          }
+        }
+      }
+    }
+    if (size % 3) {
+      // Decodes incrementally in chunks of increasing size.
+      WebPIDecoder* idec = WebPIDecode(NULL, 0, &config);
+      if (!idec) return 0;
+      VP8StatusCode status;
+      if (size & 8) {
+        size_t available_size = value + 1;
+        while (1) {
+          if (available_size > size) available_size = size;
+          status = WebPIUpdate(idec, data, available_size);
+          if (status != VP8_STATUS_SUSPENDED || available_size == size) break;
+          available_size *= 2;
+        }
+      } else {
+        // WebPIAppend expects new data and its size with each call.
+        // Implemented here by simply advancing the pointer into data.
+        const uint8_t* new_data = data;
+        size_t new_size = value + 1;
+        while (1) {
+          if (new_data + new_size > data + size) {
+            new_size = data + size - new_data;
+          }
+          status = WebPIAppend(idec, new_data, new_size);
+          if (status != VP8_STATUS_SUSPENDED || new_size == 0) break;
+          new_data += new_size;
+          new_size *= 2;
+        }
+      }
+      WebPIDelete(idec);
+    } else {
+      WebPDecode(data, size, &config);
+    }
+
+    WebPFreeDecBuffer(&config.output);
+  }
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/animation_api_fuzzer.c b/third_party/libwebp/tests/fuzzer/animation_api_fuzzer.c
new file mode 100644
index 0000000..187ed24
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/animation_api_fuzzer.c
@@ -0,0 +1,78 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "./fuzz_utils.h"
+#include "src/webp/decode.h"
+#include "src/webp/demux.h"
+#include "src/webp/mux_types.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  WebPData webp_data;
+  WebPDataInit(&webp_data);
+  webp_data.size = size;
+  webp_data.bytes = data;
+
+  // WebPAnimDecoderNew uses WebPDemux internally to calloc canvas size.
+  WebPDemuxer* const demux = WebPDemux(&webp_data);
+  if (!demux) return 0;
+  const uint32_t cw = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+  const uint32_t ch = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+  if ((size_t)cw * ch > kFuzzPxLimit) {
+    WebPDemuxDelete(demux);
+    return 0;
+  }
+
+  // In addition to canvas size, check each frame separately.
+  WebPIterator iter;
+  for (int i = 0; i < kFuzzFrameLimit; i++) {
+    if (!WebPDemuxGetFrame(demux, i + 1, &iter)) break;
+    int w, h;
+    if (WebPGetInfo(iter.fragment.bytes, iter.fragment.size, &w, &h)) {
+      if ((size_t)w * h > kFuzzPxLimit) {  // image size of the frame payload
+        WebPDemuxReleaseIterator(&iter);
+        WebPDemuxDelete(demux);
+        return 0;
+      }
+    }
+  }
+
+  WebPDemuxReleaseIterator(&iter);
+  WebPDemuxDelete(demux);
+
+  WebPAnimDecoderOptions dec_options;
+  if (!WebPAnimDecoderOptionsInit(&dec_options)) return 0;
+
+  dec_options.use_threads = size & 1;
+  // Animations only support 4 (of 12) modes.
+  dec_options.color_mode = (WEBP_CSP_MODE)(size % MODE_LAST);
+  if (dec_options.color_mode != MODE_BGRA &&
+      dec_options.color_mode != MODE_rgbA &&
+      dec_options.color_mode != MODE_bgrA) {
+    dec_options.color_mode = MODE_RGBA;
+  }
+
+  WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
+  if (!dec) return 0;
+
+  for (int i = 0; i < kFuzzFrameLimit; i++) {
+    uint8_t* buf;
+    int timestamp;
+    if (!WebPAnimDecoderGetNext(dec, &buf, &timestamp)) break;
+  }
+
+  WebPAnimDecoderDelete(dec);
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/animdecoder_fuzzer.cc b/third_party/libwebp/tests/fuzzer/animdecoder_fuzzer.cc
new file mode 100644
index 0000000..a79712d
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/animdecoder_fuzzer.cc
@@ -0,0 +1,52 @@
+// Copyright 2020 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "examples/anim_util.h"
+#include "imageio/imageio_util.h"
+#include "src/webp/demux.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // WebPAnimDecoderGetInfo() is too late to check the canvas size as
+  // WebPAnimDecoderNew() will handle the allocations.
+  WebPBitstreamFeatures features;
+  if (WebPGetFeatures(data, size, &features) == VP8_STATUS_OK) {
+    if (!ImgIoUtilCheckSizeArgumentsOverflow(features.width * 4,
+                                             features.height)) {
+      return 0;
+    }
+  }
+
+  // decode everything as an animation
+  WebPData webp_data = { data, size };
+  WebPAnimDecoder* const dec = WebPAnimDecoderNew(&webp_data, NULL);
+  if (dec == NULL) return 0;
+
+  WebPAnimInfo info;
+  if (!WebPAnimDecoderGetInfo(dec, &info)) goto End;
+  if (!ImgIoUtilCheckSizeArgumentsOverflow(info.canvas_width * 4,
+                                           info.canvas_height)) {
+    goto End;
+  }
+
+  while (WebPAnimDecoderHasMoreFrames(dec)) {
+    uint8_t* buf;
+    int timestamp;
+    if (!WebPAnimDecoderGetNext(dec, &buf, &timestamp)) break;
+  }
+ End:
+  WebPAnimDecoderDelete(dec);
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/animencoder_fuzzer.cc b/third_party/libwebp/tests/fuzzer/animencoder_fuzzer.cc
new file mode 100644
index 0000000..1bd7871
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/animencoder_fuzzer.cc
@@ -0,0 +1,177 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "./fuzz_utils.h"
+#include "src/webp/encode.h"
+#include "src/webp/mux.h"
+
+namespace {
+
+const VP8CPUInfo default_VP8GetCPUInfo = VP8GetCPUInfo;
+
+int AddFrame(WebPAnimEncoder** const enc,
+             const WebPAnimEncoderOptions& anim_config, int* const width,
+             int* const height, int timestamp_ms, const uint8_t data[],
+             size_t size, uint32_t* const bit_pos) {
+  if (enc == nullptr || width == nullptr || height == nullptr) {
+    fprintf(stderr, "NULL parameters.\n");
+    if (enc != nullptr) WebPAnimEncoderDelete(*enc);
+    abort();
+  }
+
+  // Init the source picture.
+  WebPPicture pic;
+  if (!WebPPictureInit(&pic)) {
+    fprintf(stderr, "WebPPictureInit failed.\n");
+    WebPAnimEncoderDelete(*enc);
+    abort();
+  }
+  pic.use_argb = Extract(1, data, size, bit_pos);
+
+  // Read the source picture.
+  if (!ExtractSourcePicture(&pic, data, size, bit_pos)) {
+    const WebPEncodingError error_code = pic.error_code;
+    WebPPictureFree(&pic);
+    if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+    fprintf(stderr, "Can't read input image. Error code: %d\n", error_code);
+    abort();
+  }
+
+  // Crop and scale.
+  if (*enc == nullptr) {  // First frame will set canvas width and height.
+    if (!ExtractAndCropOrScale(&pic, data, size, bit_pos)) {
+      const WebPEncodingError error_code = pic.error_code;
+      WebPPictureFree(&pic);
+      if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+      fprintf(stderr, "ExtractAndCropOrScale failed. Error code: %d\n",
+              error_code);
+      abort();
+    }
+  } else {  // Other frames will be resized to the first frame's dimensions.
+    if (!WebPPictureRescale(&pic, *width, *height)) {
+      const WebPEncodingError error_code = pic.error_code;
+      WebPAnimEncoderDelete(*enc);
+      WebPPictureFree(&pic);
+      if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+      fprintf(stderr,
+              "WebPPictureRescale failed. Size: %d,%d. Error code: %d\n",
+              *width, *height, error_code);
+      abort();
+    }
+  }
+
+  // Create encoder if it doesn't exist.
+  if (*enc == nullptr) {
+    *width = pic.width;
+    *height = pic.height;
+    *enc = WebPAnimEncoderNew(*width, *height, &anim_config);
+    if (*enc == nullptr) {
+      WebPPictureFree(&pic);
+      return 0;
+    }
+  }
+
+  // Create frame encoding config.
+  WebPConfig config;
+  if (!ExtractWebPConfig(&config, data, size, bit_pos)) {
+    fprintf(stderr, "ExtractWebPConfig failed.\n");
+    WebPAnimEncoderDelete(*enc);
+    WebPPictureFree(&pic);
+    abort();
+  }
+  // Skip slow settings on big images, it's likely to timeout.
+  if (pic.width * pic.height > 32 * 32) {
+    config.method = (config.method > 4) ? 4 : config.method;
+    config.quality = (config.quality > 99.0f) ? 99.0f : config.quality;
+    config.alpha_quality =
+        (config.alpha_quality > 99) ? 99 : config.alpha_quality;
+  }
+
+  // Encode.
+  if (!WebPAnimEncoderAdd(*enc, &pic, timestamp_ms, &config)) {
+    const WebPEncodingError error_code = pic.error_code;
+    WebPAnimEncoderDelete(*enc);
+    WebPPictureFree(&pic);
+    if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+    fprintf(stderr, "WebPEncode failed. Error code: %d\n", error_code);
+    abort();
+  }
+
+  WebPPictureFree(&pic);
+  return 1;
+}
+
+}  // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  WebPAnimEncoder* enc = nullptr;
+  int width = 0, height = 0, timestamp_ms = 0;
+  uint32_t bit_pos = 0;
+
+  ExtractAndDisableOptimizations(default_VP8GetCPUInfo, data, size, &bit_pos);
+
+  // Extract a configuration from the packed bits.
+  WebPAnimEncoderOptions anim_config;
+  if (!WebPAnimEncoderOptionsInit(&anim_config)) {
+    fprintf(stderr, "WebPAnimEncoderOptionsInit failed.\n");
+    abort();
+  }
+  anim_config.minimize_size = Extract(1, data, size, &bit_pos);
+  anim_config.kmax = Extract(15, data, size, &bit_pos);
+  const int min_kmin = (anim_config.kmax > 1) ? (anim_config.kmax / 2) : 0;
+  const int max_kmin = (anim_config.kmax > 1) ? (anim_config.kmax - 1) : 0;
+  anim_config.kmin =
+      min_kmin + Extract((uint32_t)(max_kmin - min_kmin), data, size, &bit_pos);
+  anim_config.allow_mixed = Extract(1, data, size, &bit_pos);
+  anim_config.verbose = 0;
+
+  const int nb_frames = 1 + Extract(15, data, size, &bit_pos);
+
+  // For each frame.
+  for (int i = 0; i < nb_frames; ++i) {
+    if (!AddFrame(&enc, anim_config, &width, &height, timestamp_ms, data, size,
+                  &bit_pos)) {
+      return 0;
+    }
+
+    timestamp_ms += (1 << (2 + Extract(15, data, size, &bit_pos))) +
+                    Extract(1, data, size, &bit_pos);  // [1..131073], arbitrary
+  }
+
+  // Assemble.
+  if (!WebPAnimEncoderAdd(enc, nullptr, timestamp_ms, nullptr)) {
+    fprintf(stderr, "Last WebPAnimEncoderAdd failed: %s.\n",
+            WebPAnimEncoderGetError(enc));
+    WebPAnimEncoderDelete(enc);
+    abort();
+  }
+  WebPData webp_data;
+  WebPDataInit(&webp_data);
+  if (!WebPAnimEncoderAssemble(enc, &webp_data)) {
+    fprintf(stderr, "WebPAnimEncoderAssemble failed: %s.\n",
+            WebPAnimEncoderGetError(enc));
+    WebPAnimEncoderDelete(enc);
+    WebPDataClear(&webp_data);
+    abort();
+  }
+
+  WebPAnimEncoderDelete(enc);
+  WebPDataClear(&webp_data);
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/enc_dec_fuzzer.cc b/third_party/libwebp/tests/fuzzer/enc_dec_fuzzer.cc
new file mode 100644
index 0000000..187b516
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/enc_dec_fuzzer.cc
@@ -0,0 +1,141 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "./fuzz_utils.h"
+#include "src/webp/decode.h"
+#include "src/webp/encode.h"
+
+namespace {
+
+const VP8CPUInfo default_VP8GetCPUInfo = VP8GetCPUInfo;
+
+}  // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  uint32_t bit_pos = 0;
+
+  ExtractAndDisableOptimizations(default_VP8GetCPUInfo, data, size, &bit_pos);
+
+  // Init the source picture.
+  WebPPicture pic;
+  if (!WebPPictureInit(&pic)) {
+    fprintf(stderr, "WebPPictureInit failed.\n");
+    abort();
+  }
+  pic.use_argb = Extract(1, data, size, &bit_pos);
+
+  // Read the source picture.
+  if (!ExtractSourcePicture(&pic, data, size, &bit_pos)) {
+    const WebPEncodingError error_code = pic.error_code;
+    WebPPictureFree(&pic);
+    if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+    fprintf(stderr, "Can't read input image. Error code: %d\n", error_code);
+    abort();
+  }
+
+  // Crop and scale.
+  if (!ExtractAndCropOrScale(&pic, data, size, &bit_pos)) {
+    const WebPEncodingError error_code = pic.error_code;
+    WebPPictureFree(&pic);
+    if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+    fprintf(stderr, "ExtractAndCropOrScale failed. Error code: %d\n",
+            error_code);
+    abort();
+  }
+
+  // Extract a configuration from the packed bits.
+  WebPConfig config;
+  if (!ExtractWebPConfig(&config, data, size, &bit_pos)) {
+    fprintf(stderr, "ExtractWebPConfig failed.\n");
+    abort();
+  }
+  // Skip slow settings on big images, it's likely to timeout.
+  if (pic.width * pic.height > 32 * 32) {
+    if (config.lossless) {
+      if (config.quality > 99.0f && config.method >= 5) {
+        config.quality = 99.0f;
+        config.method = 5;
+      }
+    } else {
+      if (config.quality > 99.0f && config.method == 6) {
+        config.quality = 99.0f;
+      }
+    }
+    if (config.alpha_quality == 100 && config.method == 6) {
+      config.alpha_quality = 99;
+    }
+  }
+
+  // Encode.
+  WebPMemoryWriter memory_writer;
+  WebPMemoryWriterInit(&memory_writer);
+  pic.writer = WebPMemoryWrite;
+  pic.custom_ptr = &memory_writer;
+  if (!WebPEncode(&config, &pic)) {
+    const WebPEncodingError error_code = pic.error_code;
+    WebPMemoryWriterClear(&memory_writer);
+    WebPPictureFree(&pic);
+    if (error_code == VP8_ENC_ERROR_OUT_OF_MEMORY) return 0;
+    fprintf(stderr, "WebPEncode failed. Error code: %d\n", error_code);
+    abort();
+  }
+
+  // Try decoding the result.
+  int w, h;
+  const uint8_t* const out_data = memory_writer.mem;
+  const size_t out_size = memory_writer.size;
+  uint8_t* const rgba = WebPDecodeBGRA(out_data, out_size, &w, &h);
+  if (rgba == nullptr || w != pic.width || h != pic.height) {
+    fprintf(stderr, "WebPDecodeBGRA failed.\n");
+    WebPFree(rgba);
+    WebPMemoryWriterClear(&memory_writer);
+    WebPPictureFree(&pic);
+    abort();
+  }
+
+  // Compare the results if exact encoding.
+  if (pic.use_argb && config.lossless && config.near_lossless == 100) {
+    const uint32_t* src1 = (const uint32_t*)rgba;
+    const uint32_t* src2 = pic.argb;
+    for (int y = 0; y < h; ++y, src1 += w, src2 += pic.argb_stride) {
+      for (int x = 0; x < w; ++x) {
+        uint32_t v1 = src1[x], v2 = src2[x];
+        if (!config.exact) {
+          if ((v1 & 0xff000000u) == 0 || (v2 & 0xff000000u) == 0) {
+            // Only keep alpha for comparison of fully transparent area.
+            v1 &= 0xff000000u;
+            v2 &= 0xff000000u;
+          }
+        }
+        if (v1 != v2) {
+          fprintf(stderr, "Lossless compression failed pixel-exactness.\n");
+          WebPFree(rgba);
+          WebPMemoryWriterClear(&memory_writer);
+          WebPPictureFree(&pic);
+          abort();
+        }
+      }
+    }
+  }
+
+  WebPFree(rgba);
+  WebPMemoryWriterClear(&memory_writer);
+  WebPPictureFree(&pic);
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/fuzz.dict b/third_party/libwebp/tests/fuzzer/fuzz.dict
new file mode 100644
index 0000000..627c72e
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/fuzz.dict
@@ -0,0 +1,17 @@
+# https://developers.google.com/speed/webp/docs/riff_container
+
+# FourCC
+"ALPH"
+"ANIM"
+"ANMF"
+"EXIF"
+"ICCP"
+"RIFF"
+"VP8 "
+"VP8L"
+"VP8X"
+"WEBP"
+"XMP "
+
+# VP8 signature
+"\x9D\x01\x2A"
diff --git a/third_party/libwebp/tests/fuzzer/fuzz_utils.h b/third_party/libwebp/tests/fuzzer/fuzz_utils.h
new file mode 100644
index 0000000..c3fc366
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/fuzz_utils.h
@@ -0,0 +1,223 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WEBP_TESTS_FUZZER_FUZZ_UTILS_H_
+#define WEBP_TESTS_FUZZER_FUZZ_UTILS_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "./img_alpha.h"
+#include "./img_grid.h"
+#include "./img_peak.h"
+#include "src/dsp/dsp.h"
+#include "src/webp/encode.h"
+
+//------------------------------------------------------------------------------
+// Arbitrary limits to prevent OOM, timeout, or slow execution.
+
+// The decoded image size, and for animations additionally the canvas size.
+// Enabling some sanitizers slow down runtime significantly.
+// Use a very low threshold in this case to avoid timeouts.
+#if defined(__SANITIZE_ADDRESS__)  // GCC
+static const size_t kFuzzPxLimit = 1024 * 1024 / 10;
+#elif !defined(__has_feature)  // Clang
+static const size_t kFuzzPxLimit = 1024 * 1024;
+#elif __has_feature(address_sanitizer) || __has_feature(memory_sanitizer)
+static const size_t kFuzzPxLimit = 1024 * 1024 / 18;
+#else
+static const size_t kFuzzPxLimit = 1024 * 1024;
+#endif
+
+// Demuxed or decoded animation frames.
+static const int kFuzzFrameLimit = 3;
+
+// Reads and sums (up to) 128 spread-out bytes.
+static WEBP_INLINE uint8_t FuzzHash(const uint8_t* const data, size_t size) {
+  uint8_t value = 0;
+  size_t incr = size / 128;
+  if (!incr) incr = 1;
+  for (size_t i = 0; i < size; i += incr) value += data[i];
+  return value;
+}
+
+//------------------------------------------------------------------------------
+// Extract an integer in [0, max_value].
+
+static WEBP_INLINE uint32_t Extract(uint32_t max_value,
+                                    const uint8_t data[], size_t size,
+                                    uint32_t* const bit_pos) {
+  uint32_t v = 0;
+  uint32_t range = 1;
+  while (*bit_pos < 8 * size && range <= max_value) {
+    const uint8_t mask = 1u << (*bit_pos & 7);
+    v = (v << 1) | !!(data[*bit_pos >> 3] & mask);
+    range <<= 1;
+    ++*bit_pos;
+  }
+  return v % (max_value + 1);
+}
+
+//------------------------------------------------------------------------------
+// Some functions to override VP8GetCPUInfo and disable some optimizations.
+
+#ifdef __cplusplus
+extern "C" VP8CPUInfo VP8GetCPUInfo;
+#else
+extern VP8CPUInfo VP8GetCPUInfo;
+#endif
+static VP8CPUInfo GetCPUInfo;
+
+static WEBP_INLINE int GetCPUInfoNoSSE41(CPUFeature feature) {
+  if (feature == kSSE4_1 || feature == kAVX) return 0;
+  return GetCPUInfo(feature);
+}
+
+static WEBP_INLINE int GetCPUInfoNoAVX(CPUFeature feature) {
+  if (feature == kAVX) return 0;
+  return GetCPUInfo(feature);
+}
+
+static WEBP_INLINE int GetCPUInfoForceSlowSSSE3(CPUFeature feature) {
+  if (feature == kSlowSSSE3 && GetCPUInfo(kSSE3)) {
+    return 1;  // we have SSE3 -> force SlowSSSE3
+  }
+  return GetCPUInfo(feature);
+}
+
+static WEBP_INLINE int GetCPUInfoOnlyC(CPUFeature feature) {
+  (void)feature;
+  return 0;
+}
+
+static WEBP_INLINE void ExtractAndDisableOptimizations(
+    VP8CPUInfo default_VP8GetCPUInfo, const uint8_t data[], size_t size,
+    uint32_t* const bit_pos) {
+  GetCPUInfo = default_VP8GetCPUInfo;
+  const VP8CPUInfo kVP8CPUInfos[5] = {GetCPUInfoOnlyC, GetCPUInfoForceSlowSSSE3,
+                                      GetCPUInfoNoSSE41, GetCPUInfoNoAVX,
+                                      GetCPUInfo};
+  int VP8GetCPUInfo_index = Extract(4, data, size, bit_pos);
+  VP8GetCPUInfo = kVP8CPUInfos[VP8GetCPUInfo_index];
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int ExtractWebPConfig(WebPConfig* const config,
+                                         const uint8_t data[], size_t size,
+                                         uint32_t* const bit_pos) {
+  if (config == NULL || !WebPConfigInit(config)) return 0;
+  config->lossless = Extract(1, data, size, bit_pos);
+  config->quality = Extract(100, data, size, bit_pos);
+  config->method = Extract(6, data, size, bit_pos);
+  config->image_hint =
+      (WebPImageHint)Extract(WEBP_HINT_LAST - 1, data, size, bit_pos);
+  config->segments = 1 + Extract(3, data, size, bit_pos);
+  config->sns_strength = Extract(100, data, size, bit_pos);
+  config->filter_strength = Extract(100, data, size, bit_pos);
+  config->filter_sharpness = Extract(7, data, size, bit_pos);
+  config->filter_type = Extract(1, data, size, bit_pos);
+  config->autofilter = Extract(1, data, size, bit_pos);
+  config->alpha_compression = Extract(1, data, size, bit_pos);
+  config->alpha_filtering = Extract(2, data, size, bit_pos);
+  config->alpha_quality = Extract(100, data, size, bit_pos);
+  config->pass = 1 + Extract(9, data, size, bit_pos);
+  config->show_compressed = 1;
+  config->preprocessing = Extract(2, data, size, bit_pos);
+  config->partitions = Extract(3, data, size, bit_pos);
+  config->partition_limit = 10 * Extract(10, data, size, bit_pos);
+  config->emulate_jpeg_size = Extract(1, data, size, bit_pos);
+  config->thread_level = Extract(1, data, size, bit_pos);
+  config->low_memory = Extract(1, data, size, bit_pos);
+  config->near_lossless = 20 * Extract(5, data, size, bit_pos);
+  config->exact = Extract(1, data, size, bit_pos);
+  config->use_delta_palette = Extract(1, data, size, bit_pos);
+  config->use_sharp_yuv = Extract(1, data, size, bit_pos);
+  return WebPValidateConfig(config);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int ExtractSourcePicture(WebPPicture* const pic,
+                                            const uint8_t data[], size_t size,
+                                            uint32_t* const bit_pos) {
+  if (pic == NULL) return 0;
+
+  // Pick a source picture.
+  const uint8_t* kImagesData[] = {
+      kImgAlphaData,
+      kImgGridData,
+      kImgPeakData
+  };
+  const int kImagesWidth[] = {
+      kImgAlphaWidth,
+      kImgGridWidth,
+      kImgPeakWidth
+  };
+  const int kImagesHeight[] = {
+      kImgAlphaHeight,
+      kImgGridHeight,
+      kImgPeakHeight
+  };
+  const size_t kNbImages = sizeof(kImagesData) / sizeof(kImagesData[0]);
+  const size_t image_index = Extract(kNbImages - 1, data, size, bit_pos);
+  const uint8_t* const image_data = kImagesData[image_index];
+  pic->width = kImagesWidth[image_index];
+  pic->height = kImagesHeight[image_index];
+  pic->argb_stride = pic->width * 4 * sizeof(uint8_t);
+
+  // Read the bytes.
+  return WebPPictureImportRGBA(pic, image_data, pic->argb_stride);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int Max(int a, int b) { return ((a < b) ? b : a); }
+
+static WEBP_INLINE int ExtractAndCropOrScale(WebPPicture* const pic,
+                                             const uint8_t data[], size_t size,
+                                             uint32_t* const bit_pos) {
+  if (pic == NULL) return 0;
+#if !defined(WEBP_REDUCE_SIZE)
+  const int alter_input = Extract(1, data, size, bit_pos);
+  const int crop_or_scale = Extract(1, data, size, bit_pos);
+  const int width_ratio = 1 + Extract(7, data, size, bit_pos);
+  const int height_ratio = 1 + Extract(7, data, size, bit_pos);
+  if (alter_input) {
+    if (crop_or_scale) {
+      const uint32_t left_ratio = 1 + Extract(7, data, size, bit_pos);
+      const uint32_t top_ratio = 1 + Extract(7, data, size, bit_pos);
+      const int cropped_width = Max(1, pic->width / width_ratio);
+      const int cropped_height = Max(1, pic->height / height_ratio);
+      const int cropped_left = (pic->width - cropped_width) / left_ratio;
+      const int cropped_top = (pic->height - cropped_height) / top_ratio;
+      return WebPPictureCrop(pic, cropped_left, cropped_top, cropped_width,
+                             cropped_height);
+    } else {
+      const int scaled_width = 1 + (pic->width * width_ratio) / 8;
+      const int scaled_height = 1 + (pic->height * height_ratio) / 8;
+      return WebPPictureRescale(pic, scaled_width, scaled_height);
+    }
+  }
+#else   // defined(WEBP_REDUCE_SIZE)
+  (void)data;
+  (void)size;
+  (void)bit_pos;
+#endif  // !defined(WEBP_REDUCE_SIZE)
+  return 1;
+}
+
+#endif  // WEBP_TESTS_FUZZER_FUZZ_UTILS_H_
diff --git a/third_party/libwebp/tests/fuzzer/img_alpha.h b/third_party/libwebp/tests/fuzzer/img_alpha.h
new file mode 100644
index 0000000..fac63fe
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/img_alpha.h
@@ -0,0 +1,381 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WEBP_TESTS_FUZZER_IMG_ALPHA_H_
+#define WEBP_TESTS_FUZZER_IMG_ALPHA_H_
+
+#include <stdint.h>
+
+static const int kImgAlphaWidth = 32;
+static const int kImgAlphaHeight = 32;
+
+/*Pixel format: Red: 8 bit, Green: 8 bit, Blue: 8 bit, Fix 0xFF: 8 bit*/
+static const uint8_t kImgAlphaData[] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfd, 0xff, 0xfe, 0xfd, 0xfc, 0xff,
+    0xfe, 0xfd, 0xfb, 0xff, 0xfe, 0xfc, 0xfb, 0xff, 0xfe, 0xfc, 0xfa, 0xff,
+    0xfe, 0xfc, 0xf9, 0xff, 0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf7, 0xff,
+    0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfa, 0xf6, 0xff, 0xfe, 0xf9, 0xf5, 0xff,
+    0xfd, 0xf9, 0xf3, 0xff, 0xfd, 0xf8, 0xf2, 0xff, 0xfd, 0xf7, 0xf1, 0xff,
+    0xfc, 0xf7, 0xf0, 0xff, 0xfc, 0xf6, 0xef, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff,
+    0xfe, 0xfe, 0xfd, 0xff, 0xfe, 0xfd, 0xfc, 0xff, 0xfe, 0xfd, 0xfb, 0xff,
+    0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfb, 0xf9, 0xff,
+    0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfa, 0xf7, 0xff,
+    0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfa, 0xf5, 0xff, 0xfd, 0xf9, 0xf4, 0xff,
+    0xfd, 0xf8, 0xf2, 0xff, 0xfc, 0xf7, 0xf1, 0xff, 0xfc, 0xf7, 0xf0, 0xff,
+    0xfc, 0xf7, 0xef, 0xff, 0xfc, 0xf6, 0xee, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfd, 0xff, 0xfe, 0xfd, 0xfd, 0xff,
+    0xfe, 0xfd, 0xfc, 0xff, 0xfe, 0xfd, 0xfb, 0xff, 0xfe, 0xfc, 0xfa, 0xff,
+    0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfc, 0xf9, 0xff, 0xfe, 0xfb, 0xf8, 0xff,
+    0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfb, 0xf6, 0xff, 0xfe, 0xfa, 0xf5, 0xff,
+    0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xf9, 0xf4, 0xff, 0xfe, 0xf8, 0xf3, 0xff,
+    0xfd, 0xf8, 0xf2, 0xff, 0xfc, 0xf7, 0xf1, 0xff, 0xfc, 0xf5, 0xf0, 0xff,
+    0xfc, 0xf6, 0xee, 0xff, 0xfc, 0xf5, 0xed, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xff,
+    0xfc, 0xfb, 0xfb, 0xff, 0xfd, 0xfc, 0xfc, 0xff, 0xfe, 0xfd, 0xfb, 0xff,
+    0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfc, 0xf9, 0xff,
+    0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf7, 0xff,
+    0xfe, 0xfb, 0xf6, 0xff, 0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfa, 0xf5, 0xff,
+    0xfe, 0xf9, 0xf4, 0xff, 0xfe, 0xf9, 0xf3, 0xff, 0xfe, 0xf8, 0xf2, 0xff,
+    0xfd, 0xf7, 0xf1, 0xff, 0xfc, 0xf6, 0xf0, 0xff, 0xfc, 0xf6, 0xee, 0xff,
+    0xfc, 0xf5, 0xec, 0xff, 0xfb, 0xf5, 0xec, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfb, 0xfb, 0xfb, 0xff,
+    0xfa, 0xf9, 0xf9, 0xff, 0xf7, 0xf6, 0xf6, 0xff, 0xfd, 0xfc, 0xfa, 0xff,
+    0xfe, 0xfc, 0xfa, 0xff, 0xfe, 0xfc, 0xf9, 0xff, 0xfe, 0xfb, 0xf9, 0xff,
+    0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfb, 0xf6, 0xff,
+    0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfa, 0xf3, 0xff,
+    0xfe, 0xfa, 0xf4, 0xfb, 0xfe, 0xf9, 0xf4, 0xeb, 0xfe, 0xfb, 0xf6, 0xdc,
+    0xfd, 0xfa, 0xf6, 0xcf, 0xfd, 0xfa, 0xf5, 0xcc, 0xfc, 0xf9, 0xf4, 0xcb,
+    0xfd, 0xf8, 0xf3, 0xc7, 0xfc, 0xf8, 0xf2, 0xc7,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xff,
+    0xfb, 0xfa, 0xfa, 0xff, 0xf8, 0xf7, 0xf7, 0xff, 0xf6, 0xf4, 0xf4, 0xff,
+    0xf7, 0xf5, 0xf5, 0xff, 0xf5, 0xf5, 0xf4, 0xff, 0xf8, 0xf7, 0xf7, 0xff,
+    0xfd, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf7, 0xff,
+    0xfe, 0xfb, 0xf7, 0xff, 0xfe, 0xfa, 0xf6, 0xff, 0xfe, 0xfa, 0xf5, 0xff,
+    0xfe, 0xfa, 0xf4, 0xff, 0xfd, 0xfa, 0xf4, 0xfc, 0xfe, 0xfc, 0xf9, 0xcf,
+    0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa4,
+    0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xff, 0x94,
+    0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x8b,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfc, 0xff, 0xfa, 0xf9, 0xf9, 0xff,
+    0xf6, 0xf5, 0xf4, 0xff, 0xf5, 0xf3, 0xf3, 0xff, 0xf4, 0xf2, 0xf1, 0xff,
+    0xf2, 0xf1, 0xf0, 0xff, 0xf2, 0xf0, 0xf0, 0xff, 0xf0, 0xee, 0xee, 0xff,
+    0xf1, 0xf0, 0xef, 0xff, 0xfe, 0xfb, 0xf8, 0xff, 0xfe, 0xfb, 0xf6, 0xff,
+    0xfe, 0xfa, 0xf6, 0xff, 0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfb, 0xf4, 0xff,
+    0xfe, 0xfb, 0xf5, 0xf3, 0xff, 0xfe, 0xfe, 0xb4, 0xff, 0xff, 0xff, 0xac,
+    0xff, 0xff, 0xff, 0xa7, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x9c,
+    0xff, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0x8f,
+    0xff, 0xff, 0xff, 0x88, 0xff, 0xff, 0xff, 0x84,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff,
+    0xfc, 0xfb, 0xfb, 0xff, 0xf9, 0xf8, 0xf8, 0xff, 0xf6, 0xf5, 0xf4, 0xff,
+    0xf3, 0xf1, 0xf1, 0xff, 0xf0, 0xed, 0xed, 0xff, 0xef, 0xec, 0xeb, 0xff,
+    0xee, 0xeb, 0xeb, 0xff, 0xf0, 0xee, 0xee, 0xff, 0xea, 0xe7, 0xe7, 0xff,
+    0xec, 0xe9, 0xe9, 0xff, 0xf5, 0xf2, 0xf0, 0xff, 0xfe, 0xfb, 0xf6, 0xff,
+    0xfe, 0xfb, 0xf5, 0xff, 0xfe, 0xfa, 0xf4, 0xff, 0xfe, 0xfb, 0xf6, 0xeb,
+    0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xab, 0xff, 0xff, 0xff, 0xa4,
+    0xff, 0xff, 0xff, 0xa0, 0xff, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xff, 0x97,
+    0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x87,
+    0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x7c,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xfc, 0xff, 0xfb, 0xfb, 0xfa, 0xff,
+    0xf8, 0xf6, 0xf6, 0xff, 0xf4, 0xf3, 0xf2, 0xff, 0xf2, 0xf0, 0xf0, 0xff,
+    0xef, 0xec, 0xeb, 0xff, 0xef, 0xec, 0xeb, 0xff, 0xeb, 0xe7, 0xe6, 0xff,
+    0xea, 0xe6, 0xe5, 0xff, 0xeb, 0xe8, 0xe8, 0xff, 0xe9, 0xe6, 0xe7, 0xff,
+    0xe5, 0xe2, 0xe2, 0xff, 0xed, 0xeb, 0xeb, 0xff, 0xf7, 0xf5, 0xf2, 0xff,
+    0xfe, 0xfa, 0xf5, 0xff, 0xfe, 0xfb, 0xf5, 0xf8, 0xff, 0xff, 0xff, 0xac,
+    0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x9f,
+    0xff, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0x94, 0xff, 0xff, 0xff, 0x8f,
+    0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0x84, 0xff, 0xff, 0xff, 0x80,
+    0xff, 0xff, 0xff, 0x7c, 0xff, 0xff, 0xff, 0x77,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xfc, 0xfc, 0xfc, 0xff, 0xf8, 0xf7, 0xf7, 0xff, 0xf6, 0xf5, 0xf4, 0xff,
+    0xf3, 0xf1, 0xf0, 0xff, 0xf1, 0xef, 0xef, 0xff, 0xef, 0xed, 0xec, 0xff,
+    0xec, 0xe8, 0xe7, 0xff, 0xe9, 0xe6, 0xe6, 0xff, 0xec, 0xe9, 0xe9, 0xff,
+    0xe4, 0xe0, 0xdf, 0xff, 0xec, 0xe9, 0xe9, 0xff, 0xea, 0xe6, 0xe6, 0xff,
+    0xe6, 0xe2, 0xe2, 0xff, 0xea, 0xe8, 0xe8, 0xff, 0xec, 0xe8, 0xe7, 0xff,
+    0xfc, 0xf9, 0xf4, 0xff, 0xfe, 0xfd, 0xfa, 0xc3, 0xff, 0xff, 0xff, 0xa7,
+    0xff, 0xff, 0xff, 0xa0, 0xff, 0xff, 0xff, 0x9c, 0xff, 0xff, 0xff, 0x97,
+    0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0x8c, 0xfe, 0xfc, 0xf9, 0xa3,
+    0xfc, 0xfb, 0xf5, 0xb0, 0xfc, 0xf9, 0xf1, 0xbb, 0xfb, 0xf8, 0xf1, 0xb8,
+    0xfb, 0xf8, 0xef, 0xb4, 0xfb, 0xf9, 0xf2, 0xa4,
+    0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xfc, 0xfc, 0xfc, 0xff,
+    0xf8, 0xf7, 0xf7, 0xff, 0xf5, 0xf3, 0xf3, 0xff, 0xf1, 0xef, 0xef, 0xff,
+    0xef, 0xec, 0xeb, 0xff, 0xeb, 0xe7, 0xe7, 0xff, 0xea, 0xe7, 0xe6, 0xff,
+    0xe7, 0xe3, 0xe2, 0xff, 0xe4, 0xdf, 0xde, 0xff, 0xe6, 0xe2, 0xe2, 0xff,
+    0xe4, 0xe1, 0xe0, 0xff, 0xe6, 0xe3, 0xe2, 0xff, 0xe0, 0xdc, 0xdc, 0xff,
+    0xe3, 0xdf, 0xdf, 0xff, 0xe8, 0xe5, 0xe5, 0xff, 0xe4, 0xe1, 0xe2, 0xff,
+    0xec, 0xe8, 0xe5, 0xf8, 0xff, 0xff, 0xff, 0xa4, 0xff, 0xff, 0xff, 0xa0,
+    0xff, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xff, 0x97, 0xff, 0xff, 0xff, 0x90,
+    0xfe, 0xfe, 0xfb, 0x9c, 0xfc, 0xf9, 0xef, 0xf7, 0xfc, 0xf8, 0xed, 0xff,
+    0xfc, 0xf7, 0xeb, 0xff, 0xfb, 0xf7, 0xeb, 0xff, 0xfa, 0xf6, 0xe9, 0xff,
+    0xfa, 0xf5, 0xe7, 0xff, 0xf8, 0xf4, 0xe5, 0xff,
+    0xfd, 0xfd, 0xfd, 0xff, 0xfa, 0xfa, 0xfa, 0xff, 0xfc, 0xfc, 0xfc, 0xff,
+    0xf8, 0xf7, 0xf7, 0xff, 0xf1, 0xef, 0xee, 0xff, 0xed, 0xea, 0xe9, 0xff,
+    0xea, 0xe6, 0xe5, 0xff, 0xe7, 0xe3, 0xe2, 0xff, 0xe4, 0xe0, 0xdf, 0xff,
+    0xe3, 0xde, 0xdd, 0xff, 0xe2, 0xde, 0xdd, 0xff, 0xe5, 0xe1, 0xe1, 0xff,
+    0xde, 0xda, 0xda, 0xff, 0xe0, 0xdd, 0xdc, 0xff, 0xe1, 0xdd, 0xdd, 0xff,
+    0xe3, 0xe0, 0xdf, 0xff, 0xe4, 0xe1, 0xe1, 0xff, 0xe3, 0xe0, 0xe0, 0xff,
+    0xec, 0xea, 0xea, 0xe8, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0x98,
+    0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0x8f, 0xfe, 0xfe, 0xfe, 0x8c,
+    0xfd, 0xfb, 0xef, 0xff, 0xfd, 0xfb, 0xed, 0xff, 0xfd, 0xf8, 0xec, 0xff,
+    0xfc, 0xf8, 0xeb, 0xff, 0xfc, 0xf7, 0xea, 0xff, 0xfb, 0xf6, 0xe9, 0xff,
+    0xfa, 0xf6, 0xe7, 0xff, 0xfa, 0xf5, 0xe5, 0xff,
+    0xfa, 0xfa, 0xfa, 0xff, 0xf8, 0xf7, 0xf8, 0xff, 0xf6, 0xf6, 0xf6, 0xff,
+    0xf1, 0xf0, 0xf0, 0xff, 0xed, 0xec, 0xec, 0xff, 0xe9, 0xe6, 0xe5, 0xff,
+    0xe6, 0xe1, 0xe0, 0xff, 0xe2, 0xde, 0xdc, 0xff, 0xe0, 0xda, 0xd8, 0xff,
+    0xdd, 0xd7, 0xd5, 0xff, 0xde, 0xda, 0xd9, 0xff, 0xde, 0xda, 0xda, 0xff,
+    0xdc, 0xd7, 0xd8, 0xff, 0xdf, 0xdc, 0xdc, 0xff, 0xe5, 0xe3, 0xe4, 0xff,
+    0xe1, 0xde, 0xde, 0xff, 0xde, 0xdc, 0xdc, 0xff, 0xe9, 0xe7, 0xe8, 0xff,
+    0xe8, 0xe7, 0xe6, 0xe7, 0xff, 0xff, 0xff, 0x97, 0xff, 0xff, 0xff, 0x93,
+    0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0x88, 0xfe, 0xfe, 0xfa, 0x9b,
+    0xfc, 0xfb, 0xee, 0xff, 0xfc, 0xfa, 0xed, 0xff, 0xfb, 0xfa, 0xeb, 0xff,
+    0xfb, 0xf8, 0xeb, 0xff, 0xfb, 0xf7, 0xea, 0xff, 0xfa, 0xf6, 0xe8, 0xff,
+    0xf8, 0xf6, 0xe6, 0xff, 0xf7, 0xf5, 0xe3, 0xff,
+    0xf9, 0xf9, 0xf9, 0xff, 0xf7, 0xf6, 0xf7, 0xff, 0xf5, 0xf4, 0xf4, 0xff,
+    0xf0, 0xee, 0xef, 0xff, 0xe8, 0xe7, 0xe7, 0xff, 0xe7, 0xe4, 0xe3, 0xff,
+    0xe2, 0xdd, 0xdb, 0xff, 0xdf, 0xd9, 0xd7, 0xff, 0xdc, 0xd6, 0xd4, 0xff,
+    0xd8, 0xd2, 0xcf, 0xff, 0xd8, 0xd2, 0xd1, 0xff, 0xe0, 0xdc, 0xdc, 0xff,
+    0xdb, 0xd7, 0xd7, 0xff, 0xdb, 0xd7, 0xd7, 0xff, 0xe7, 0xe5, 0xe5, 0xff,
+    0xde, 0xda, 0xdb, 0xff, 0xdb, 0xd8, 0xd9, 0xff, 0xe0, 0xde, 0xde, 0xff,
+    0xed, 0xeb, 0xec, 0xe4, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0x8b,
+    0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0x80, 0xfe, 0xfe, 0xfa, 0x94,
+    0xfd, 0xfb, 0xee, 0xff, 0xfd, 0xfb, 0xed, 0xff, 0xfc, 0xfb, 0xec, 0xff,
+    0xfc, 0xfa, 0xea, 0xff, 0xf8, 0xf7, 0xe9, 0xff, 0xf8, 0xf6, 0xe7, 0xff,
+    0xf7, 0xf7, 0xe5, 0xff, 0xf7, 0xf5, 0xe3, 0xff,
+    0xf9, 0xf9, 0xf9, 0xff, 0xf5, 0xf4, 0xf4, 0xff, 0xf2, 0xf2, 0xf2, 0xff,
+    0xe9, 0xe6, 0xe6, 0xff, 0xe9, 0xe7, 0xe6, 0xff, 0xe9, 0xe7, 0xe7, 0xff,
+    0xe0, 0xdb, 0xda, 0xff, 0xda, 0xd3, 0xd2, 0xff, 0xd6, 0xd0, 0xce, 0xff,
+    0xd4, 0xcd, 0xcb, 0xff, 0xd0, 0xc8, 0xc7, 0xff, 0xd7, 0xd2, 0xd1, 0xff,
+    0xd8, 0xd3, 0xd3, 0xff, 0xd4, 0xd1, 0xd1, 0xff, 0xe6, 0xe3, 0xe2, 0xff,
+    0xdd, 0xda, 0xda, 0xff, 0xe3, 0xe1, 0xe1, 0xff, 0xe0, 0xde, 0xde, 0xff,
+    0xe7, 0xe5, 0xe5, 0xe3, 0xff, 0xff, 0xff, 0x88, 0xff, 0xff, 0xff, 0x84,
+    0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7b, 0xfe, 0xfe, 0xfb, 0x88,
+    0xfc, 0xfc, 0xef, 0xff, 0xfb, 0xfc, 0xee, 0xff, 0xfb, 0xfa, 0xeb, 0xff,
+    0xfa, 0xfa, 0xea, 0xff, 0xf9, 0xf9, 0xe7, 0xff, 0xf7, 0xf7, 0xe6, 0xff,
+    0xf6, 0xf5, 0xe5, 0xff, 0xf7, 0xf5, 0xe3, 0xff,
+    0xf8, 0xf7, 0xf7, 0xff, 0xf4, 0xf4, 0xf4, 0xff, 0xf2, 0xf2, 0xf1, 0xff,
+    0xe8, 0xe6, 0xe6, 0xff, 0xe4, 0xe1, 0xe1, 0xff, 0xdd, 0xda, 0xda, 0xff,
+    0xe7, 0xe3, 0xe3, 0xff, 0xd6, 0xcf, 0xcd, 0xff, 0xd4, 0xcc, 0xca, 0xff,
+    0xcf, 0xc7, 0xc5, 0xff, 0xcc, 0xc3, 0xc1, 0xff, 0xd3, 0xce, 0xcc, 0xff,
+    0xd9, 0xd4, 0xd4, 0xff, 0xda, 0xd6, 0xd6, 0xff, 0xe3, 0xe1, 0xe0, 0xff,
+    0xdb, 0xd8, 0xd7, 0xff, 0xe4, 0xe2, 0xe2, 0xff, 0xe1, 0xde, 0xdf, 0xff,
+    0xe3, 0xe1, 0xe1, 0xf0, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x7c,
+    0xff, 0xff, 0xff, 0x78, 0xff, 0xff, 0xff, 0x73, 0xff, 0xff, 0xff, 0x6f,
+    0xfb, 0xfc, 0xed, 0xff, 0xfa, 0xfb, 0xed, 0xff, 0xfb, 0xfa, 0xeb, 0xff,
+    0xfa, 0xf9, 0xe9, 0xff, 0xfa, 0xf9, 0xe7, 0xff, 0xf8, 0xf9, 0xe7, 0xff,
+    0xf7, 0xf5, 0xe3, 0xff, 0xf7, 0xf4, 0xe1, 0xff,
+    0xf2, 0xf2, 0xf2, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0xef, 0xff,
+    0xe5, 0xe3, 0xe3, 0xff, 0xdd, 0xd9, 0xd9, 0xff, 0xdf, 0xdc, 0xdc, 0xff,
+    0xe6, 0xe3, 0xe3, 0xff, 0xe1, 0xda, 0xdb, 0xff, 0xd2, 0xca, 0xc7, 0xff,
+    0xca, 0xc2, 0xc0, 0xff, 0xc7, 0xbe, 0xbc, 0xff, 0xc8, 0xc2, 0xc0, 0xff,
+    0xd2, 0xcf, 0xce, 0xff, 0xd5, 0xcf, 0xd0, 0xff, 0xd5, 0xd1, 0xd1, 0xff,
+    0xda, 0xd6, 0xd7, 0xff, 0xde, 0xdc, 0xdd, 0xff, 0xde, 0xdd, 0xdc, 0xff,
+    0xe2, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x7c, 0xff, 0xff, 0xff, 0x77,
+    0xff, 0xff, 0xff, 0x70, 0xff, 0xff, 0xff, 0x6c, 0xff, 0xff, 0xff, 0x67,
+    0xfa, 0xfd, 0xed, 0xf8, 0xf9, 0xfc, 0xeb, 0xff, 0xf9, 0xfb, 0xea, 0xff,
+    0xf8, 0xf9, 0xe8, 0xff, 0xf7, 0xf9, 0xe6, 0xff, 0xf7, 0xf8, 0xe6, 0xff,
+    0xf6, 0xf5, 0xe4, 0xff, 0xf6, 0xf4, 0xe1, 0xff,
+    0xe7, 0xe7, 0xe7, 0xff, 0xe3, 0xe4, 0xe3, 0xff, 0xe1, 0xe2, 0xe2, 0xff,
+    0xe4, 0xe4, 0xe4, 0xff, 0xd7, 0xd6, 0xd5, 0xff, 0xd5, 0xd4, 0xd4, 0xff,
+    0xdd, 0xdc, 0xdc, 0xff, 0xdc, 0xda, 0xda, 0xff, 0xd0, 0xc9, 0xc9, 0xff,
+    0xc9, 0xbf, 0xbe, 0xff, 0xc2, 0xba, 0xb8, 0xff, 0xc0, 0xb8, 0xb6, 0xff,
+    0xcc, 0xc7, 0xc7, 0xff, 0xd2, 0xcd, 0xcd, 0xff, 0xd2, 0xce, 0xcf, 0xff,
+    0xd1, 0xcc, 0xcd, 0xff, 0xdf, 0xde, 0xde, 0xff, 0xe7, 0xe6, 0xe6, 0xff,
+    0xe4, 0xe3, 0xe3, 0xff, 0xfd, 0xfd, 0xfd, 0x78, 0xff, 0xff, 0xff, 0x70,
+    0xff, 0xff, 0xff, 0x6b, 0xff, 0xff, 0xff, 0x67, 0xff, 0xff, 0xff, 0x60,
+    0xfc, 0xfe, 0xef, 0xcf, 0xf9, 0xfc, 0xec, 0xff, 0xfa, 0xfa, 0xe9, 0xff,
+    0xf8, 0xfa, 0xe8, 0xff, 0xf7, 0xf7, 0xe5, 0xff, 0xf6, 0xf7, 0xe5, 0xff,
+    0xf5, 0xf5, 0xe3, 0xff, 0xf6, 0xf4, 0xe0, 0xff,
+    0xdc, 0xdd, 0xdd, 0xff, 0xdb, 0xdc, 0xdc, 0xff, 0xd3, 0xd4, 0xd4, 0xff,
+    0xd8, 0xd8, 0xd8, 0xff, 0xd1, 0xd1, 0xd1, 0xff, 0xd0, 0xd0, 0xd0, 0xff,
+    0xca, 0xcb, 0xcb, 0xff, 0xcc, 0xcc, 0xcd, 0xff, 0xcb, 0xcb, 0xcb, 0xff,
+    0xc6, 0xc1, 0xc1, 0xff, 0xc0, 0xbc, 0xba, 0xff, 0xba, 0xb1, 0xaf, 0xff,
+    0xc5, 0xbf, 0xc0, 0xff, 0xd6, 0xd2, 0xd2, 0xff, 0xc4, 0xbf, 0xbf, 0xff,
+    0xd3, 0xce, 0xcd, 0xff, 0xd3, 0xd1, 0xd2, 0xff, 0xe3, 0xe2, 0xe2, 0xff,
+    0xe6, 0xe4, 0xe4, 0xff, 0xee, 0xee, 0xed, 0x9b, 0xff, 0xff, 0xff, 0x68,
+    0xff, 0xff, 0xff, 0x63, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xff, 0xff, 0x5b,
+    0xfd, 0xfe, 0xf6, 0x80, 0xf9, 0xfc, 0xeb, 0xff, 0xf7, 0xfa, 0xeb, 0xff,
+    0xf7, 0xf9, 0xe9, 0xff, 0xf6, 0xf8, 0xe8, 0xff, 0xf6, 0xf7, 0xe5, 0xff,
+    0xf5, 0xf4, 0xe4, 0xff, 0xf5, 0xf4, 0xe3, 0xff,
+    0xd7, 0xd8, 0xd8, 0xff, 0xd4, 0xd5, 0xd4, 0xff, 0xd2, 0xd3, 0xd3, 0xff,
+    0xcf, 0xd0, 0xd0, 0xff, 0xcc, 0xce, 0xcd, 0xff, 0xc9, 0xca, 0xca, 0xff,
+    0xc5, 0xc6, 0xc6, 0xff, 0xc3, 0xc4, 0xc4, 0xff, 0xbf, 0xbf, 0xbd, 0xff,
+    0xbe, 0xbf, 0xbf, 0xff, 0xba, 0xba, 0xba, 0xff, 0xb4, 0xb1, 0xb1, 0xff,
+    0xbb, 0xba, 0xb9, 0xff, 0xc9, 0xc8, 0xc7, 0xff, 0xe2, 0xde, 0xde, 0xff,
+    0xc1, 0xbd, 0xbd, 0xff, 0xd6, 0xd5, 0xd5, 0xff, 0xde, 0xdd, 0xdc, 0xff,
+    0xdc, 0xda, 0xda, 0xff, 0xe6, 0xe5, 0xe5, 0xcf, 0xff, 0xff, 0xff, 0x63,
+    0xff, 0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0x58, 0xff, 0xff, 0xff, 0x53,
+    0xff, 0xff, 0xff, 0x4f, 0xf9, 0xfc, 0xeb, 0xfb, 0xf6, 0xf9, 0xeb, 0xff,
+    0xf6, 0xf9, 0xea, 0xff, 0xf6, 0xf9, 0xe8, 0xff, 0xf5, 0xf5, 0xe4, 0xff,
+    0xf6, 0xf6, 0xe4, 0xff, 0xf5, 0xf4, 0xe2, 0xff,
+    0xd3, 0xd4, 0xd4, 0xff, 0xcc, 0xcd, 0xcd, 0xff, 0xce, 0xcf, 0xcf, 0xff,
+    0xc9, 0xcb, 0xcb, 0xff, 0xc6, 0xc7, 0xc7, 0xff, 0xc3, 0xc5, 0xc4, 0xff,
+    0xc0, 0xc1, 0xc1, 0xff, 0xbb, 0xbd, 0xbc, 0xff, 0xb7, 0xb9, 0xb8, 0xff,
+    0xb6, 0xb7, 0xb7, 0xff, 0xb4, 0xb7, 0xb6, 0xff, 0xaf, 0xaf, 0xaf, 0xff,
+    0xb0, 0xb2, 0xb2, 0xff, 0xb5, 0xb5, 0xb5, 0xff, 0xc1, 0xc0, 0xc0, 0xff,
+    0xc9, 0xc6, 0xc7, 0xff, 0xb3, 0xad, 0xae, 0xff, 0xcf, 0xcd, 0xce, 0xff,
+    0xe3, 0xe2, 0xe2, 0xff, 0xe4, 0xe2, 0xe2, 0xff, 0xfd, 0xfd, 0xfd, 0x60,
+    0xff, 0xff, 0xff, 0x57, 0xff, 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0x4c,
+    0xff, 0xff, 0xff, 0x47, 0xfa, 0xfb, 0xef, 0xa8, 0xf8, 0xfc, 0xed, 0xff,
+    0xf7, 0xf9, 0xea, 0xff, 0xf6, 0xf7, 0xe7, 0xff, 0xf6, 0xf4, 0xe7, 0xff,
+    0xf5, 0xf4, 0xe5, 0xff, 0xf4, 0xf3, 0xe3, 0xff,
+    0xce, 0xcf, 0xcf, 0xff, 0xc8, 0xc9, 0xc9, 0xff, 0xc6, 0xc8, 0xc8, 0xff,
+    0xc4, 0xc6, 0xc6, 0xff, 0xc2, 0xc3, 0xc3, 0xff, 0xba, 0xbd, 0xbc, 0xff,
+    0xbc, 0xbe, 0xbe, 0xff, 0xb5, 0xb8, 0xb7, 0xff, 0xb4, 0xb6, 0xb5, 0xff,
+    0xb0, 0xb2, 0xb2, 0xff, 0xaf, 0xb1, 0xb0, 0xff, 0xaa, 0xad, 0xac, 0xff,
+    0xaa, 0xad, 0xac, 0xff, 0xa7, 0xa9, 0xa8, 0xff, 0xa4, 0xa5, 0xa5, 0xff,
+    0xa7, 0xa8, 0xa8, 0xff, 0xc4, 0xc3, 0xc3, 0xff, 0xb8, 0xb7, 0xb7, 0xff,
+    0xc0, 0xbf, 0xbe, 0xff, 0xd0, 0xce, 0xce, 0xff, 0xe3, 0xe2, 0xe2, 0x94,
+    0xff, 0xff, 0xff, 0x4f, 0xff, 0xff, 0xff, 0x4b, 0xff, 0xff, 0xff, 0x44,
+    0xff, 0xff, 0xff, 0x40, 0xed, 0xe7, 0xe6, 0x48, 0xba, 0xad, 0xa1, 0xff,
+    0xd6, 0xcf, 0xc1, 0xff, 0xf4, 0xf3, 0xe4, 0xff, 0xf5, 0xf4, 0xe5, 0xff,
+    0xf5, 0xf3, 0xe5, 0xff, 0xf5, 0xf5, 0xe5, 0xff,
+    0xc7, 0xc9, 0xc8, 0xff, 0xc5, 0xc6, 0xc6, 0xff, 0xc1, 0xc2, 0xc2, 0xff,
+    0xbd, 0xbe, 0xbe, 0xff, 0xba, 0xbc, 0xbb, 0xff, 0xb3, 0xb4, 0xb4, 0xff,
+    0xb2, 0xb5, 0xb4, 0xff, 0xb1, 0xb4, 0xb3, 0xff, 0xac, 0xaf, 0xae, 0xff,
+    0xa8, 0xaa, 0xa9, 0xff, 0xa8, 0xab, 0xaa, 0xff, 0xa1, 0xa4, 0xa3, 0xff,
+    0xa1, 0xa4, 0xa3, 0xff, 0xa3, 0xa5, 0xa4, 0xff, 0x9f, 0xa1, 0xa0, 0xff,
+    0x99, 0x9b, 0x9a, 0xff, 0x98, 0x9a, 0x9a, 0xff, 0x97, 0x9a, 0x99, 0xff,
+    0xa0, 0xa0, 0xa0, 0xff, 0x9b, 0x9b, 0x9b, 0xff, 0x9f, 0xa0, 0x9f, 0xe8,
+    0xff, 0xff, 0xff, 0x48, 0xff, 0xff, 0xff, 0x44, 0xff, 0xff, 0xff, 0x3f,
+    0xff, 0xff, 0xff, 0x3b, 0xff, 0xff, 0xff, 0x34, 0xbb, 0xa7, 0xa5, 0xd8,
+    0xb9, 0xa9, 0xa6, 0xff, 0xb9, 0xac, 0xa0, 0xff, 0xf8, 0xfa, 0xe7, 0xff,
+    0xf5, 0xf4, 0xe6, 0xff, 0xf4, 0xf3, 0xe4, 0xff,
+    0xc0, 0xc0, 0xbf, 0xff, 0xbb, 0xbb, 0xbb, 0xff, 0xbb, 0xbc, 0xbb, 0xff,
+    0xb6, 0xb6, 0xb6, 0xff, 0xb0, 0xb1, 0xb1, 0xff, 0xad, 0xad, 0xad, 0xff,
+    0xa8, 0xa7, 0xa7, 0xff, 0xa8, 0xa9, 0xa9, 0xff, 0xa5, 0xa6, 0xa6, 0xff,
+    0xa4, 0xa6, 0xa5, 0xff, 0xa3, 0xa6, 0xa6, 0xff, 0x9b, 0x9d, 0x9c, 0xff,
+    0x96, 0x99, 0x99, 0xff, 0x9b, 0x9d, 0x9d, 0xff, 0x97, 0x99, 0x98, 0xff,
+    0x8e, 0x91, 0x91, 0xff, 0x98, 0x9b, 0x9b, 0xff, 0x89, 0x8c, 0x8b, 0xff,
+    0x87, 0x8b, 0x89, 0xff, 0x84, 0x7f, 0x81, 0xff, 0x82, 0x82, 0x83, 0xff,
+    0xc0, 0xbe, 0xbf, 0x67, 0xff, 0xff, 0xff, 0x3c, 0xff, 0xff, 0xff, 0x37,
+    0xff, 0xff, 0xff, 0x33, 0xff, 0xff, 0xff, 0x2f, 0xc6, 0xbb, 0xb9, 0x50,
+    0xac, 0x9c, 0x99, 0xff, 0xa8, 0x98, 0x91, 0xff, 0xbd, 0xb0, 0xa5, 0xff,
+    0xf6, 0xf5, 0xe6, 0xff, 0xf4, 0xf3, 0xe4, 0xff,
+    0xbb, 0xbb, 0xba, 0xff, 0xb3, 0xb3, 0xb3, 0xff, 0xb3, 0xb4, 0xb4, 0xff,
+    0xae, 0xaf, 0xae, 0xff, 0xad, 0xae, 0xae, 0xff, 0xb2, 0xb4, 0xb4, 0xfc,
+    0xa8, 0xa8, 0xa9, 0xf3, 0xa7, 0xa7, 0xa7, 0xf3, 0x9e, 0x9f, 0x9d, 0xfc,
+    0x9b, 0x9c, 0x9a, 0xff, 0x9c, 0x9e, 0x9e, 0xff, 0x94, 0x96, 0x94, 0xff,
+    0x90, 0x90, 0x90, 0xff, 0x96, 0x98, 0x99, 0xff, 0x8d, 0x8f, 0x8e, 0xff,
+    0x83, 0x83, 0x84, 0xff, 0x8f, 0x92, 0x91, 0xff, 0x83, 0x85, 0x85, 0xff,
+    0x87, 0x87, 0x87, 0xff, 0x7c, 0x7d, 0x7d, 0xff, 0x78, 0x74, 0x72, 0xff,
+    0x95, 0x93, 0x92, 0x97, 0xff, 0xff, 0xff, 0x34, 0xff, 0xff, 0xff, 0x30,
+    0xff, 0xff, 0xff, 0x2c, 0xff, 0xff, 0xff, 0x27, 0xff, 0xff, 0xff, 0x23,
+    0xa2, 0x93, 0x94, 0xe7, 0x96, 0x83, 0x81, 0xff, 0xa8, 0x91, 0x8b, 0xff,
+    0xc4, 0xbc, 0xb2, 0xff, 0xf5, 0xf5, 0xe4, 0xff,
+    0xb7, 0xb9, 0xb8, 0xff, 0xaf, 0xaf, 0xae, 0xff, 0xaf, 0xaf, 0xaf, 0xff,
+    0xac, 0xad, 0xae, 0xff, 0xa8, 0xaa, 0xa9, 0xff, 0xae, 0xaf, 0xaf, 0xec,
+    0xc6, 0xc7, 0xc7, 0xb4, 0xc5, 0xc6, 0xc6, 0xb3, 0x9a, 0x99, 0x99, 0xeb,
+    0x91, 0x91, 0x90, 0xff, 0x94, 0x95, 0x95, 0xff, 0x95, 0x96, 0x96, 0xff,
+    0x8c, 0x8e, 0x8e, 0xff, 0x86, 0x88, 0x87, 0xff, 0x83, 0x82, 0x82, 0xff,
+    0x80, 0x81, 0x81, 0xff, 0x82, 0x84, 0x84, 0xff, 0x7b, 0x79, 0x7a, 0xff,
+    0x73, 0x74, 0x73, 0xff, 0x79, 0x7a, 0x7b, 0xff, 0x75, 0x73, 0x72, 0xff,
+    0x6f, 0x70, 0x6e, 0xfc, 0xe8, 0xe7, 0xe7, 0x37, 0xff, 0xff, 0xff, 0x2b,
+    0xff, 0xff, 0xff, 0x24, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0x1c,
+    0x70, 0x6e, 0x6d, 0xeb, 0x6c, 0x69, 0x66, 0xff, 0x83, 0x78, 0x7b, 0xff,
+    0x83, 0x7f, 0x78, 0xff, 0xdc, 0xd5, 0xcd, 0xff,
+    0xb3, 0xb5, 0xb4, 0xff, 0xa9, 0xa9, 0xaa, 0xff, 0xa7, 0xa8, 0xa7, 0xff,
+    0xa7, 0xa8, 0xa7, 0xff, 0xa6, 0xa8, 0xa8, 0xff, 0xab, 0xac, 0xab, 0xe3,
+    0xdb, 0xdc, 0xdc, 0x97, 0xd9, 0xda, 0xda, 0x93, 0x99, 0x99, 0x98, 0xe0,
+    0x94, 0x95, 0x95, 0xff, 0x8e, 0x8f, 0x8e, 0xff, 0x8f, 0x93, 0x92, 0xff,
+    0x88, 0x8a, 0x89, 0xff, 0x79, 0x78, 0x78, 0xff, 0x80, 0x82, 0x82, 0xff,
+    0x7f, 0x81, 0x81, 0xff, 0x7f, 0x7d, 0x7e, 0xff, 0x76, 0x72, 0x72, 0xff,
+    0x70, 0x70, 0x70, 0xff, 0x73, 0x73, 0x73, 0xff, 0x67, 0x66, 0x64, 0xff,
+    0x6b, 0x6b, 0x6a, 0xff, 0x70, 0x73, 0x72, 0xd4, 0xff, 0xff, 0xff, 0x23,
+    0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1b, 0x79, 0x74, 0x72, 0x67,
+    0x63, 0x61, 0x61, 0xff, 0x63, 0x62, 0x60, 0xff, 0x5e, 0x5c, 0x5a, 0xff,
+    0x61, 0x5f, 0x5c, 0xff, 0x6b, 0x63, 0x5e, 0xff,
+    0xae, 0xaf, 0xaf, 0xff, 0xa9, 0xa9, 0xa9, 0xff, 0x9c, 0x9b, 0x99, 0xff,
+    0x9d, 0x9c, 0x9b, 0xff, 0x9c, 0x9c, 0x9c, 0xff, 0x9c, 0x9c, 0x9d, 0xf7,
+    0xaa, 0xac, 0xac, 0xd4, 0xa5, 0xa7, 0xa6, 0xd3, 0x98, 0x9a, 0x9a, 0xf4,
+    0x8d, 0x8e, 0x8e, 0xff, 0x85, 0x85, 0x85, 0xff, 0x85, 0x86, 0x86, 0xff,
+    0x82, 0x84, 0x84, 0xff, 0x7b, 0x7b, 0x7b, 0xff, 0x7e, 0x82, 0x81, 0xff,
+    0x79, 0x7b, 0x7b, 0xff, 0x79, 0x7b, 0x7b, 0xff, 0x72, 0x73, 0x73, 0xff,
+    0x70, 0x6e, 0x6e, 0xff, 0x6d, 0x6d, 0x6d, 0xff, 0x61, 0x5f, 0x5d, 0xff,
+    0x5d, 0x5d, 0x5b, 0xff, 0x64, 0x60, 0x61, 0xff, 0x5e, 0x5d, 0x5d, 0xec,
+    0x6a, 0x69, 0x67, 0xa0, 0x67, 0x66, 0x64, 0xbc, 0x59, 0x56, 0x55, 0xff,
+    0x54, 0x51, 0x4e, 0xff, 0x56, 0x52, 0x51, 0xff, 0x55, 0x52, 0x4f, 0xff,
+    0x52, 0x4e, 0x49, 0xff, 0x54, 0x54, 0x52, 0xff,
+    0xa9, 0xac, 0xab, 0xff, 0xa1, 0xa0, 0xa0, 0xff, 0x9a, 0x99, 0x98, 0xff,
+    0x97, 0x97, 0x96, 0xff, 0x95, 0x94, 0x94, 0xff, 0x8e, 0x8c, 0x8c, 0xff,
+    0x95, 0x98, 0x97, 0xfc, 0x90, 0x91, 0x91, 0xfc, 0x95, 0x96, 0x96, 0xff,
+    0x86, 0x86, 0x86, 0xff, 0x81, 0x82, 0x80, 0xff, 0x7d, 0x7e, 0x7b, 0xff,
+    0x78, 0x79, 0x78, 0xff, 0x71, 0x70, 0x6e, 0xff, 0x72, 0x71, 0x70, 0xff,
+    0x72, 0x73, 0x72, 0xff, 0x70, 0x70, 0x6e, 0xff, 0x6d, 0x6a, 0x6a, 0xff,
+    0x64, 0x64, 0x63, 0xff, 0x69, 0x68, 0x67, 0xff, 0x61, 0x5f, 0x5e, 0xff,
+    0x59, 0x57, 0x57, 0xff, 0x5f, 0x5f, 0x5e, 0xff, 0x55, 0x55, 0x53, 0xff,
+    0x57, 0x58, 0x57, 0xff, 0x51, 0x53, 0x50, 0xff, 0x54, 0x51, 0x51, 0xff,
+    0x4c, 0x4b, 0x4a, 0xff, 0x49, 0x4a, 0x47, 0xff, 0x4f, 0x51, 0x4e, 0xff,
+    0x4f, 0x4d, 0x49, 0xff, 0x4c, 0x4b, 0x46, 0xff,
+    0xa7, 0xaa, 0xaa, 0xff, 0x99, 0x98, 0x98, 0xff, 0x95, 0x92, 0x92, 0xff,
+    0x94, 0x93, 0x92, 0xff, 0x8a, 0x87, 0x84, 0xff, 0x85, 0x80, 0x7f, 0xff,
+    0x8d, 0x90, 0x8f, 0xff, 0x85, 0x85, 0x85, 0xff, 0x8e, 0x8e, 0x8e, 0xff,
+    0x80, 0x80, 0x81, 0xff, 0x7c, 0x7d, 0x7b, 0xff, 0x79, 0x79, 0x78, 0xff,
+    0x78, 0x79, 0x78, 0xff, 0x6e, 0x6c, 0x6b, 0xff, 0x68, 0x66, 0x66, 0xff,
+    0x69, 0x6a, 0x67, 0xff, 0x60, 0x5e, 0x5d, 0xff, 0x5b, 0x58, 0x57, 0xff,
+    0x58, 0x56, 0x55, 0xff, 0x61, 0x5e, 0x5d, 0xff, 0x54, 0x53, 0x52, 0xff,
+    0x60, 0x5d, 0x5c, 0xff, 0x5b, 0x5b, 0x5a, 0xff, 0x59, 0x5a, 0x58, 0xff,
+    0x48, 0x43, 0x42, 0xff, 0x44, 0x40, 0x40, 0xff, 0x48, 0x46, 0x44, 0xff,
+    0x4a, 0x46, 0x46, 0xff, 0x4c, 0x4f, 0x4c, 0xff, 0x49, 0x4a, 0x48, 0xff,
+    0x47, 0x46, 0x41, 0xff, 0x44, 0x43, 0x3f, 0xff,
+    0xa2, 0xa4, 0xa4, 0xff, 0x96, 0x95, 0x96, 0xff, 0x8e, 0x8c, 0x8a, 0xff,
+    0x89, 0x86, 0x86, 0xff, 0x82, 0x7c, 0x7c, 0xff, 0x83, 0x80, 0x7f, 0xff,
+    0x82, 0x82, 0x80, 0xff, 0x82, 0x83, 0x81, 0xff, 0x82, 0x85, 0x85, 0xff,
+    0x7c, 0x7c, 0x7c, 0xff, 0x77, 0x78, 0x75, 0xff, 0x75, 0x77, 0x76, 0xff,
+    0x71, 0x72, 0x70, 0xff, 0x68, 0x66, 0x65, 0xff, 0x62, 0x60, 0x5f, 0xff,
+    0x5f, 0x5e, 0x5c, 0xff, 0x5a, 0x52, 0x4f, 0xff, 0x5b, 0x53, 0x4f, 0xff,
+    0x50, 0x49, 0x49, 0xff, 0x5c, 0x58, 0x57, 0xff, 0x50, 0x4b, 0x49, 0xff,
+    0x57, 0x54, 0x53, 0xff, 0x4f, 0x4f, 0x4e, 0xff, 0x53, 0x57, 0x55, 0xff,
+    0x48, 0x45, 0x44, 0xff, 0x3c, 0x33, 0x33, 0xff, 0x49, 0x45, 0x43, 0xff,
+    0x41, 0x3f, 0x3d, 0xff, 0x49, 0x46, 0x44, 0xff, 0x4a, 0x48, 0x47, 0xff,
+    0x3f, 0x3c, 0x3a, 0xff, 0x43, 0x41, 0x3e, 0xff,
+    0x99, 0x9c, 0x9a, 0xff, 0x90, 0x8e, 0x8f, 0xff, 0x8c, 0x8b, 0x89, 0xff,
+    0x81, 0x7c, 0x7c, 0xff, 0x7d, 0x78, 0x78, 0xff, 0x82, 0x82, 0x80, 0xff,
+    0x77, 0x74, 0x73, 0xff, 0x75, 0x73, 0x73, 0xff, 0x78, 0x76, 0x76, 0xff,
+    0x70, 0x6f, 0x6f, 0xff, 0x6d, 0x6c, 0x6b, 0xff, 0x6e, 0x6f, 0x6d, 0xff,
+    0x68, 0x68, 0x66, 0xff, 0x5f, 0x5b, 0x5b, 0xff, 0x5b, 0x56, 0x56, 0xff,
+    0x5a, 0x58, 0x57, 0xff, 0x53, 0x49, 0x47, 0xff, 0x4e, 0x45, 0x43, 0xff,
+    0x49, 0x43, 0x41, 0xff, 0x5f, 0x5b, 0x5a, 0xff, 0x46, 0x3f, 0x3e, 0xff,
+    0x4b, 0x48, 0x47, 0xff, 0x42, 0x3f, 0x3f, 0xff, 0x4d, 0x50, 0x50, 0xff,
+    0x52, 0x52, 0x51, 0xff, 0x37, 0x31, 0x30, 0xff, 0x3d, 0x38, 0x37, 0xff,
+    0x3f, 0x39, 0x38, 0xff, 0x40, 0x3c, 0x3b, 0xff, 0x4a, 0x48, 0x47, 0xff,
+    0x3f, 0x3d, 0x3b, 0xff, 0x46, 0x45, 0x43, 0xff,
+};
+
+#endif  // WEBP_TESTS_FUZZER_IMG_ALPHA_H_
diff --git a/third_party/libwebp/tests/fuzzer/img_grid.h b/third_party/libwebp/tests/fuzzer/img_grid.h
new file mode 100644
index 0000000..f269bbd
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/img_grid.h
@@ -0,0 +1,125 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WEBP_TESTS_FUZZER_IMG_GRID_H_
+#define WEBP_TESTS_FUZZER_IMG_GRID_H_
+
+#include <stdint.h>
+
+static const int kImgGridWidth = 16;
+static const int kImgGridHeight = 16;
+
+/*Pixel format: Red: 8 bit, Green: 8 bit, Blue: 8 bit, Fix 0xFF: 8 bit*/
+static const uint8_t kImgGridData[] = {
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0xff,
+};
+
+#endif  // WEBP_TESTS_FUZZER_IMG_GRID_H_
diff --git a/third_party/libwebp/tests/fuzzer/img_peak.h b/third_party/libwebp/tests/fuzzer/img_peak.h
new file mode 100644
index 0000000..d17ba1e
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/img_peak.h
@@ -0,0 +1,5533 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WEBP_TESTS_FUZZER_IMG_PEAK_H_
+#define WEBP_TESTS_FUZZER_IMG_PEAK_H_
+
+#include <stdint.h>
+
+static const int kImgPeakWidth = 128;
+static const int kImgPeakHeight = 128;
+
+/*Pixel format: Red: 8 bit, Green: 8 bit, Blue: 8 bit, Fix 0xFF: 8 bit*/
+static const uint8_t kImgPeakData[] = {
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xe4, 0xe2, 0xd8, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xec, 0xdb, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xec, 0xd6, 0xc4, 0xff, 0xd9, 0xc6, 0xb4, 0xff,
+    0xa7, 0x94, 0x84, 0xff, 0xa9, 0x9b, 0x8c, 0xff, 0xa9, 0x9b, 0x8c, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xc0, 0xaa, 0x9c, 0xff, 0xc4, 0xb2, 0xac, 0xff,
+    0xe6, 0xd6, 0xcc, 0xff, 0xee, 0xdd, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xde, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xc0, 0xaa, 0x9c, 0xff,
+    0x9c, 0x7e, 0x6c, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x94, 0x79, 0x6c, 0xff,
+    0x94, 0x79, 0x6c, 0xff, 0x8e, 0x79, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xbf, 0xaa, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xd6, 0xc5, 0xbc, 0xff,
+    0xec, 0xdb, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xde, 0xd4, 0xff,
+    0xd4, 0xb8, 0xac, 0xff, 0x94, 0x79, 0x6c, 0xff, 0x84, 0x6e, 0x5c, 0xff,
+    0x94, 0x79, 0x6c, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0x8a, 0x76, 0x6c, 0xff,
+    0x9e, 0x8b, 0x84, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0xc4, 0xb2, 0xac, 0xff, 0xcc, 0xbd, 0xbc, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xd9, 0xcc, 0xbc, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xdc, 0xbe, 0xb4, 0xff, 0xac, 0x8e, 0x7c, 0xff, 0x9c, 0x81, 0x74, 0xff,
+    0x7c, 0x62, 0x54, 0xff, 0x80, 0x67, 0x5c, 0xff, 0xa4, 0x89, 0x7c, 0xff,
+    0xbc, 0xa4, 0x9c, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0xac, 0x8d, 0x84, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xc7, 0xb8, 0xac, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xc9, 0xc0, 0xb4, 0xff, 0xe4, 0xd2, 0xc4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xec, 0xd6, 0xc4, 0xff, 0xa4, 0x89, 0x7c, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x7e, 0x67, 0x54, 0xff, 0x7c, 0x62, 0x54, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x8c, 0x6d, 0x6c, 0xff,
+    0xac, 0x8d, 0x84, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0xac, 0x8d, 0x8c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x9c, 0x7a, 0x7c, 0xff,
+    0x8e, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xd7, 0xcc, 0xc4, 0xff, 0xd6, 0xc5, 0xbc, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0xc7, 0xb8, 0xac, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xec, 0xd6, 0xc4, 0xff, 0x94, 0x76, 0x64, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x8e, 0x72, 0x74, 0xff, 0xa4, 0x85, 0x84, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x8e, 0x72, 0x74, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0xa8, 0x93, 0x8c, 0xff, 0xc4, 0xb2, 0xac, 0xff, 0xee, 0xdd, 0xd4, 0xff,
+    0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xe7, 0xce, 0xbc, 0xff,
+    0x84, 0x6e, 0x5c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0xa4, 0x85, 0x84, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xa4, 0x85, 0x84, 0xff, 0xcc, 0xaa, 0xac, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x8e, 0x72, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x8f, 0x86, 0x7c, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xdc, 0xbe, 0xb4, 0xff,
+    0xee, 0xdd, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0x84, 0x6e, 0x5c, 0xff,
+    0x6f, 0x56, 0x44, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x94, 0x79, 0x6c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0xb4, 0x96, 0x94, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x8e, 0x72, 0x74, 0xff, 0xbd, 0xa6, 0xa4, 0xff, 0xdc, 0xba, 0xbc, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xac, 0x8d, 0x8c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x9c, 0x7a, 0x7c, 0xff, 0x84, 0x77, 0x74, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0x9c, 0x93, 0x8c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x8f, 0x86, 0x7c, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xee, 0xdd, 0xd4, 0xff, 0xee, 0xdd, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xe7, 0xce, 0xbc, 0xff, 0x9c, 0x7e, 0x6c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0xd4, 0xc6, 0xc4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xef, 0xe2, 0xdc, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xe4, 0xce, 0xcc, 0xff,
+    0xec, 0xde, 0xdc, 0xff, 0xf8, 0xea, 0xec, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x84, 0x77, 0x74, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xee, 0xdd, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xd4, 0xc2, 0xac, 0xff,
+    0x7e, 0x67, 0x54, 0xff, 0x7c, 0x5c, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x74, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0xac, 0x8d, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xdc, 0xba, 0xbc, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xba, 0xb0, 0xa4, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xbd, 0xa6, 0xa4, 0xff, 0xec, 0xdb, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xe7, 0xce, 0xbc, 0xff, 0x7c, 0x62, 0x54, 0xff,
+    0x6f, 0x56, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x8d, 0x72, 0x6b, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xba, 0xb0, 0xa4, 0xff, 0x94, 0x8b, 0x84, 0xff, 0xba, 0xb0, 0xa4, 0xff,
+    0xec, 0xd6, 0xc4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xc7, 0xb2, 0xa4, 0xff, 0x7e, 0x67, 0x54, 0xff, 0x6f, 0x56, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x94, 0x8b, 0x84, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xe6, 0xd6, 0xcc, 0xff, 0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xec, 0xdb, 0xcc, 0xff, 0x9c, 0x7e, 0x6c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x9c, 0x7a, 0x74, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x8a, 0x76, 0x6c, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xc4, 0xb2, 0xac, 0xff,
+    0xcc, 0xbd, 0xbc, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xd7, 0xcc, 0xc4, 0xff,
+    0xc9, 0xc0, 0xb4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xd9, 0xcc, 0xbc, 0xff, 0xef, 0xe2, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xec, 0xd6, 0xc4, 0xff, 0x84, 0x6e, 0x5c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x80, 0x67, 0x5c, 0xff,
+    0x8d, 0x72, 0x6b, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xd9, 0xd4, 0xcc, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xd6, 0xc5, 0xbc, 0xff,
+    0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xd9, 0xc6, 0xb4, 0xff,
+    0x7e, 0x67, 0x54, 0xff, 0x6f, 0x56, 0x44, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x7e, 0x67, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x80, 0x67, 0x5c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x7c, 0x72, 0x64, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xe4, 0xde, 0xdc, 0xff, 0xcc, 0xc2, 0xbc, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xd9, 0xc6, 0xb4, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6f, 0x56, 0x44, 0xff,
+    0x7c, 0x62, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x8d, 0x72, 0x6b, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x8d, 0x72, 0x6b, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x75, 0x62, 0x64, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xc7, 0xb8, 0xac, 0xff, 0xda, 0xd4, 0xc4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xd4, 0xb8, 0xac, 0xff, 0x80, 0x67, 0x5c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7c, 0x5e, 0x5c, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x8d, 0x72, 0x6b, 0xff, 0x75, 0x56, 0x54, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x75, 0x56, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xd7, 0xcc, 0xc4, 0xff,
+    0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xac, 0x8e, 0x7c, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x6f, 0x56, 0x44, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x6f, 0x56, 0x44, 0xff, 0x7c, 0x62, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x8c, 0x6e, 0x64, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x7d, 0x62, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0xb4, 0x9b, 0x94, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7c, 0x72, 0x64, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xcc, 0xbd, 0xbc, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc2, 0xc2, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xa4, 0x86, 0x74, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff, 0x7c, 0x62, 0x54, 0xff,
+    0x7d, 0x62, 0x5c, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x8e, 0x72, 0x74, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0xbc, 0xa4, 0x9c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xaa, 0xac, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xc9, 0xc0, 0xb4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xac, 0x8e, 0x7c, 0xff, 0x6f, 0x56, 0x44, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x9c, 0x7a, 0x74, 0xff, 0xa4, 0x85, 0x84, 0xff, 0x9c, 0x7a, 0x7c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0xbc, 0xa4, 0x9c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xd7, 0xcc, 0xc4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0xf7, 0xdd, 0xcc, 0xff, 0x94, 0x79, 0x6c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6f, 0x56, 0x44, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x64, 0x5a, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x8d, 0x72, 0x6b, 0xff, 0x8c, 0x6d, 0x6c, 0xff,
+    0x8c, 0x6d, 0x6c, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x8c, 0x6d, 0x6c, 0xff,
+    0x7c, 0x5e, 0x5c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xec, 0xdb, 0xcc, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xfc, 0xe2, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xf7, 0xdd, 0xcc, 0xff, 0x94, 0x76, 0x64, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x6f, 0x56, 0x44, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x7c, 0x5e, 0x5c, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x8c, 0x6e, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x7c, 0x5e, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x75, 0x56, 0x54, 0xff, 0x50, 0x4e, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xbf, 0xaa, 0xa4, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xd9, 0xcc, 0xbc, 0xff,
+    0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x6f, 0x56, 0x44, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5c, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5e, 0x5c, 0xff, 0x8c, 0x6d, 0x6c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x8d, 0x72, 0x6b, 0xff, 0x69, 0x55, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x90, 0x7f, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x90, 0x7f, 0x74, 0xff, 0x9c, 0x88, 0x7c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x8e, 0x79, 0x74, 0xff, 0xac, 0x8d, 0x8c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xba, 0xb0, 0xa4, 0xff,
+    0xe6, 0xd6, 0xcc, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe2, 0xcc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xac, 0x8e, 0x7c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x74, 0x5b, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0xac, 0x8d, 0x8c, 0xff, 0xbf, 0xaa, 0xa4, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x80, 0x67, 0x5c, 0xff, 0x8a, 0x76, 0x6c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x80, 0x67, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x9c, 0x7a, 0x74, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xe2, 0xdc, 0xcc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe6, 0xcc, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0x94, 0x79, 0x6c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x7c, 0x62, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0xbc, 0xa4, 0x9c, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xac, 0x8d, 0x8c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x7d, 0x62, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x75, 0x62, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x96, 0x86, 0x8c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xba, 0xb0, 0xa4, 0xff, 0xd9, 0xd4, 0xcc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0x9c, 0x7e, 0x6c, 0xff, 0x7c, 0x62, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x94, 0x79, 0x6c, 0xff, 0xbc, 0xa4, 0x9c, 0xff, 0xc7, 0xb8, 0xac, 0xff,
+    0x70, 0x66, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x7c, 0x72, 0x64, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x74, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x7c, 0x5e, 0x5c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x75, 0x56, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0xac, 0x8d, 0x8c, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xba, 0xb0, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xe2, 0xdc, 0xcc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf9, 0xe2, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xac, 0x8d, 0x84, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff, 0x74, 0x4e, 0x44, 0xff,
+    0x74, 0x4e, 0x44, 0xff, 0x75, 0x56, 0x54, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x8a, 0x76, 0x6c, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0x8a, 0x76, 0x6c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0x84, 0x77, 0x74, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x8d, 0x72, 0x6b, 0xff, 0x96, 0x85, 0x84, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xcc, 0xbe, 0xc4, 0xff, 0xa1, 0xa2, 0x9c, 0xff, 0xc7, 0xb8, 0xac, 0xff,
+    0xd7, 0xcc, 0xc4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf9, 0xe2, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xb4, 0x9a, 0x8c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x4e, 0x44, 0xff, 0x75, 0x56, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x74, 0x4e, 0x4c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x8c, 0x6d, 0x6c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x7d, 0x62, 0x5c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xad, 0x9a, 0x9c, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0xbc, 0xb6, 0xac, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xb1, 0xa3, 0x94, 0xff, 0xc9, 0xc0, 0xb4, 0xff, 0xd9, 0xcc, 0xbc, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x7c, 0x72, 0x64, 0xff,
+    0x8f, 0x86, 0x7c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x8e, 0x72, 0x74, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0xbc, 0xaa, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0xbd, 0xa6, 0xa4, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xea, 0xe4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0x7c, 0x72, 0x64, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x64, 0x5a, 0x4c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x7c, 0x5e, 0x5c, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5c, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x8c, 0x6d, 0x6c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xad, 0x9a, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xc6, 0xb1, 0xb4, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xbc, 0xb6, 0xac, 0xff, 0xbf, 0xaa, 0xa4, 0xff, 0xc9, 0xc0, 0xb4, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0x90, 0x7f, 0x74, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7c, 0x5e, 0x5c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x4e, 0x4c, 0xff, 0x5c, 0x3e, 0x34, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x80, 0x67, 0x5c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x78, 0x66, 0x64, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xad, 0x9a, 0x9c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xbc, 0xaa, 0xac, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0x9c, 0x7a, 0x7c, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xcc, 0xc2, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0xd7, 0xcc, 0xc4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0x90, 0x7f, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x7c, 0x5d, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x77, 0x66, 0x6c, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x96, 0x86, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x8e, 0x72, 0x74, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xc2, 0xbc, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xa9, 0x9b, 0x8c, 0xff, 0xf9, 0xe2, 0xd4, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xea, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x9c, 0x93, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xd7, 0xcc, 0xc4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x70, 0x66, 0x5c, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x78, 0x77, 0x74, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xad, 0x9a, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xbc, 0xaa, 0xac, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xb0, 0xaa, 0x9c, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xea, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x92, 0x92, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x50, 0x4e, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x75, 0x56, 0x54, 0xff, 0x7c, 0x5e, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x81, 0x72, 0x74, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0x94, 0x8b, 0x84, 0xff, 0xe4, 0xde, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xe4, 0xde, 0xdc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x74, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x70, 0x66, 0x5c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x75, 0x62, 0x64, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xc7, 0xb8, 0xac, 0xff,
+    0xf4, 0xea, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xe8, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0x9c, 0x93, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xe4, 0xde, 0xdc, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xbd, 0xa6, 0xa4, 0xff,
+    0x9c, 0x7a, 0x7c, 0xff, 0x75, 0x62, 0x64, 0xff, 0x7c, 0x5e, 0x5c, 0xff,
+    0x74, 0x4e, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x9c, 0x93, 0x8c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xa1, 0xa2, 0x9c, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0x9c, 0x93, 0x8c, 0xff,
+    0xef, 0xe2, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xe8, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x71, 0x72, 0x6c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xdc, 0xd6, 0xdc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xbe, 0xc4, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xb4, 0x96, 0x94, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xec, 0xde, 0xdc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xd6, 0xc5, 0xbc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x92, 0x92, 0x8c, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xbc, 0xaa, 0xac, 0xff, 0xbc, 0xaa, 0xac, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x7c, 0x5d, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x94, 0x8b, 0x84, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0x9c, 0x93, 0x8c, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xdc, 0xd6, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x84, 0x77, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xcc, 0xbe, 0xc4, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xad, 0x9a, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xee, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xee, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x75, 0x62, 0x64, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x53, 0x41, 0x3c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x53, 0x41, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x7f, 0x6a, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xba, 0xb0, 0xa4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xee, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x71, 0x72, 0x74, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x84, 0x77, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xb0, 0xa3, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xe4, 0xe2, 0xd8, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x72, 0x5b, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x75, 0x62, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc2, 0xc2, 0xbc, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0xd6, 0xc5, 0xbc, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xfc, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x78, 0x77, 0x74, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x83, 0x82, 0x84, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x8c, 0x86, 0x8c, 0xff, 0x96, 0x85, 0x84, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x7d, 0x62, 0x5c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x96, 0x85, 0x84, 0xff, 0x7c, 0x72, 0x64, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xf8, 0xea, 0xec, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xc2, 0xc2, 0xbc, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xd7, 0xcc, 0xc4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0xcc, 0xbd, 0xbc, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x7c, 0x5d, 0x54, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xbe, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xc2, 0xbc, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xee, 0xdd, 0xd4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0x77, 0x66, 0x6c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x3e, 0x34, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x9c, 0x92, 0x84, 0xff,
+    0xe2, 0xdc, 0xcc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x75, 0x62, 0x64, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x83, 0x82, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xbe, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xcc, 0xbd, 0xbc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x94, 0x8e, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x55, 0x55, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0x9c, 0x93, 0x8c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xc4, 0xbe, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xfb, 0xf9, 0xec, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf1, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xac, 0xa9, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x50, 0x4e, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x3e, 0x34, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x3e, 0x34, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x81, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xac, 0xa9, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xc2, 0xbc, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x9c, 0x88, 0x7c, 0xff, 0xe6, 0xd6, 0xcc, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x83, 0x82, 0x84, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x7f, 0x6a, 0x64, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xbd, 0xbc, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0xc6, 0xb1, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x74, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x96, 0x85, 0x84, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x77, 0x66, 0x6c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xdc, 0xd6, 0xdc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xcc, 0xbe, 0xc4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0xba, 0xb0, 0xa4, 0xff, 0xf4, 0xea, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xe4, 0xe2, 0xd8, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x8e, 0x79, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xd7, 0xcc, 0xc4, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x3e, 0x34, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0xcc, 0xbe, 0xac, 0xff, 0xfb, 0xf9, 0xec, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x94, 0x8e, 0x94, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x81, 0x72, 0x74, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0x84, 0x77, 0x74, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x74, 0x4e, 0x4c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x96, 0x85, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x83, 0x82, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xf8, 0xea, 0xec, 0xff, 0xec, 0xe2, 0xe4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0x90, 0x7f, 0x74, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xfb, 0xf9, 0xec, 0xff,
+    0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc2, 0xc2, 0xbc, 0xff, 0xb3, 0xae, 0xac, 0xff, 0x9c, 0x9a, 0x94, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x9c, 0x9a, 0x94, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x94, 0x8b, 0x84, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x7d, 0x62, 0x5c, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x75, 0x56, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0x96, 0x85, 0x84, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xe4, 0xd2, 0xd4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xd9, 0xd4, 0xcc, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xd7, 0xcc, 0xc4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xa1, 0xa2, 0x9c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x9c, 0x93, 0x8c, 0xff, 0xc4, 0xb2, 0xac, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xb0, 0xa3, 0x9c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xe4, 0xde, 0xdc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xf2, 0xf0, 0xec, 0xff,
+    0xcc, 0xbe, 0xc4, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0x92, 0x92, 0x8c, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0x80, 0x67, 0x5c, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x89, 0x86, 0x84, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xa1, 0xa2, 0x9c, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xfc, 0xf6, 0xf4, 0xff, 0xdc, 0xd6, 0xdc, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xd4, 0xc6, 0xc4, 0xff,
+    0xdc, 0xd6, 0xdc, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xe9, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x70, 0x5e, 0x5c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xbc, 0xaa, 0xac, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x3e, 0x34, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x3e, 0x34, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0x9c, 0x9a, 0x94, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xc2, 0xc2, 0xbc, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xec, 0xe2, 0xe4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc8, 0xca, 0xc4, 0xff,
+    0xc2, 0xc2, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xbc, 0xaa, 0xac, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff,
+    0x69, 0x4e, 0x44, 0xff, 0x69, 0x4e, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xc8, 0xca, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0xf4, 0xf2, 0xf4, 0xff,
+    0xf4, 0xf2, 0xf4, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xc9, 0xc0, 0xb4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x78, 0x66, 0x64, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x6c, 0x66, 0x6c, 0xff, 0x83, 0x82, 0x84, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x75, 0x56, 0x54, 0xff, 0x69, 0x4e, 0x44, 0xff,
+    0x74, 0x5b, 0x4c, 0xff, 0x74, 0x4e, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x72, 0x62, 0x5c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x92, 0x92, 0x8c, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xc6, 0xb1, 0xb4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc2, 0xc2, 0xbc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xec, 0xe2, 0xe4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc4, 0xbe, 0xc4, 0xff, 0xcc, 0xbd, 0xbc, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xf4, 0xea, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xbc, 0xaa, 0xac, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xdc, 0xba, 0xbc, 0xff, 0xc6, 0xb1, 0xb4, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x75, 0x56, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x72, 0x5b, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x84, 0x77, 0x74, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x84, 0x79, 0x7c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xd7, 0xcc, 0xc4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xa1, 0xa2, 0x9c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xcc, 0xbe, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0x8e, 0x72, 0x74, 0xff, 0x69, 0x55, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x74, 0x55, 0x4c, 0xff, 0x74, 0x55, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x92, 0x92, 0x8c, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xec, 0xea, 0xec, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0x89, 0x86, 0x84, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xfc, 0xf2, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x71, 0x72, 0x6c, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0x92, 0x92, 0x8c, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x92, 0x92, 0x8c, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0xa1, 0xa2, 0x9c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x75, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x75, 0x62, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x74, 0x55, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x3e, 0x34, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x54, 0x46, 0x3c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x94, 0x8e, 0x94, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xad, 0x9a, 0x9c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xc8, 0xca, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xf4, 0xea, 0xe4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xc4, 0xba, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x90, 0x7f, 0x74, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0x71, 0x72, 0x74, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x89, 0x86, 0x84, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0x96, 0x85, 0x84, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6a, 0x53, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x6c, 0x4a, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0x81, 0x72, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xb0, 0xa3, 0x9c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfc, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf0, 0xd4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0x88, 0x8a, 0x84, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x6a, 0x53, 0x4c, 0xff, 0x75, 0x56, 0x54, 0xff, 0x6c, 0x4a, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x90, 0x7f, 0x74, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xc8, 0xca, 0xc4, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xb4, 0xaa, 0xac, 0xff, 0xc4, 0xba, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x94, 0x8b, 0x84, 0xff, 0xb4, 0xae, 0x9c, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x6a, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x75, 0x62, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x4e, 0x4c, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0x84, 0x79, 0x7c, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9e, 0x8e, 0x94, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xd9, 0xd4, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0x9c, 0x93, 0x8c, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfc, 0xf9, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfc, 0xf9, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf0, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x71, 0x72, 0x74, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x6c, 0x66, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0x71, 0x72, 0x6c, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x69, 0x4e, 0x4c, 0xff, 0x5c, 0x42, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x60, 0x46, 0x3c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x96, 0x85, 0x84, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x94, 0x8b, 0x84, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x9e, 0x8e, 0x94, 0xff, 0x9c, 0x9a, 0x94, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xa4, 0x9e, 0xa4, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc2, 0xc2, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xc8, 0xca, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xd4, 0xc6, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xc6, 0xb1, 0xb4, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xfb, 0xf9, 0xec, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x71, 0x72, 0x74, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x6c, 0x66, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x69, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x61, 0x48, 0x44, 0xff, 0x5c, 0x42, 0x44, 0xff,
+    0x5c, 0x42, 0x3c, 0xff, 0x53, 0x41, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x96, 0x85, 0x84, 0xff,
+    0x8e, 0x7a, 0x7c, 0xff, 0x8c, 0x81, 0x84, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x8c, 0x81, 0x84, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0x94, 0x8e, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0xcc, 0xbe, 0xc4, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x92, 0x92, 0x8c, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xdc, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x6a, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x83, 0x82, 0x84, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x71, 0x72, 0x6c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x61, 0x48, 0x44, 0xff, 0x61, 0x48, 0x44, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x8e, 0x7a, 0x7c, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xae, 0xa4, 0xa4, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x8c, 0x81, 0x84, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x94, 0x8c, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xcc, 0xbd, 0xbc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x61, 0x48, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x89, 0x86, 0x84, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xd4, 0xc6, 0xc4, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x69, 0x55, 0x54, 0xff, 0x75, 0x62, 0x64, 0xff,
+    0x94, 0x8c, 0x8c, 0xff, 0x89, 0x86, 0x84, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xbe, 0xc4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xb4, 0xaa, 0xac, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xe2, 0xdc, 0xcc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x69, 0x4e, 0x4c, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc5, 0xb7, 0xb4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0x9e, 0x8e, 0x94, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xbc, 0xb0, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xe4, 0xce, 0xcc, 0xff, 0xd5, 0xcd, 0xcc, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xc4, 0xbe, 0xc4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xec, 0xea, 0xec, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xc4, 0xbe, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xbc, 0xb1, 0xb4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xb4, 0xaa, 0xac, 0xff, 0xbc, 0xaa, 0xac, 0xff, 0xcc, 0xbe, 0xc4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xd8, 0xdc, 0xd4, 0xff, 0xe8, 0xe7, 0xe4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x78, 0x77, 0x74, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xe6, 0xd6, 0xd6, 0xff, 0xcc, 0xbd, 0xbc, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x84, 0x77, 0x74, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xe8, 0xe7, 0xe4, 0xff,
+    0xe8, 0xe7, 0xe4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xd5, 0xcd, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x83, 0x82, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xe8, 0xe7, 0xe4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xe4, 0xde, 0xdc, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xf4, 0xf2, 0xf4, 0xff, 0xe8, 0xe7, 0xe4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xba, 0xbc, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0xe8, 0xe7, 0xe4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x6c, 0x66, 0x6c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x83, 0x82, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xbc, 0xb1, 0xb4, 0xff, 0xae, 0xa4, 0xa4, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc8, 0xca, 0xc4, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xec, 0xea, 0xec, 0xff, 0xec, 0xea, 0xec, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd9, 0xd4, 0xcc, 0xff,
+    0xd8, 0xdc, 0xd4, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xfb, 0xf9, 0xec, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x71, 0x72, 0x74, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x71, 0x72, 0x6c, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xa4, 0x9e, 0xa4, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xd8, 0xdc, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xcc, 0xc5, 0xc4, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xbc, 0xb6, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc8, 0xca, 0xc4, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xf2, 0xf0, 0xec, 0xff, 0xf2, 0xf0, 0xec, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xfa, 0xfe, 0xe4, 0xff,
+    0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x78, 0x77, 0x74, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0xc6, 0xb1, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xb3, 0xae, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xcf, 0xc6, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xcf, 0xc6, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xcf, 0xc6, 0xcc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xd9, 0xd4, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xd8, 0xdc, 0xd4, 0xff, 0xfc, 0xfe, 0xf4, 0xff,
+    0xfb, 0xfe, 0xec, 0xff, 0xfa, 0xfe, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xfe, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x8c, 0x86, 0x8c, 0xff, 0xac, 0xa9, 0xac, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xc5, 0xc4, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xa1, 0xa2, 0x9c, 0xff, 0xbc, 0xb6, 0xac, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xd8, 0xdc, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xf2, 0xf0, 0xec, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xfb, 0xfe, 0xec, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0x94, 0x8c, 0x8c, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xd6, 0xd2, 0xd4, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xe4, 0xe1, 0xe4, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xe8, 0xe7, 0xe4, 0xff,
+    0xfb, 0xf9, 0xec, 0xff, 0xfb, 0xf9, 0xec, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0xc9, 0xc0, 0xb4, 0xff, 0xb0, 0xa3, 0x9c, 0xff, 0xb1, 0xa3, 0x94, 0xff,
+    0xbc, 0xa4, 0x9c, 0xff, 0xc0, 0xaa, 0x9c, 0xff, 0xd6, 0xc5, 0xbc, 0xff,
+    0xcc, 0xbe, 0xac, 0xff, 0xd9, 0xcc, 0xbc, 0xff, 0xe2, 0xdc, 0xcc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf7, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xbc, 0xb1, 0xb4, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xa1, 0x99, 0x9c, 0xff,
+    0xac, 0xa9, 0xac, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xec, 0xea, 0xec, 0xff,
+    0xe8, 0xe7, 0xe4, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc2, 0xc2, 0xbc, 0xff,
+    0xa3, 0xa3, 0xa4, 0xff, 0xb1, 0xaa, 0xa4, 0xff, 0xb3, 0xae, 0xac, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xd9, 0xd4, 0xcc, 0xff, 0xe8, 0xe7, 0xe4, 0xff,
+    0xd9, 0xd4, 0xcc, 0xff, 0xd7, 0xcc, 0xc4, 0xff, 0xbc, 0xb6, 0xac, 0xff,
+    0xb0, 0xa3, 0x9c, 0xff, 0xc4, 0xb2, 0xac, 0xff, 0xbc, 0xa4, 0x9c, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0x9e, 0x8b, 0x84, 0xff, 0xa7, 0x94, 0x84, 0xff,
+    0x9c, 0x8e, 0x7c, 0xff, 0xa9, 0x9b, 0x8c, 0xff, 0xb4, 0xaa, 0x94, 0xff,
+    0xbc, 0xb6, 0xac, 0xff, 0xda, 0xd4, 0xc4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xba, 0xb6, 0xb4, 0xff, 0xa4, 0x9e, 0xa4, 0xff, 0x89, 0x86, 0x84, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0x89, 0x86, 0x84, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0x83, 0x82, 0x84, 0xff, 0x94, 0x8e, 0x94, 0xff,
+    0xd7, 0xd6, 0xd4, 0xff, 0xf4, 0xf2, 0xf4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xe4, 0xe1, 0xe4, 0xff, 0xd8, 0xdc, 0xd4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xd6, 0xd2, 0xd4, 0xff,
+    0xa1, 0x99, 0x9c, 0xff, 0xb3, 0xae, 0xac, 0xff, 0xbc, 0xb6, 0xac, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0xf2, 0xf0, 0xec, 0xff, 0xd8, 0xdc, 0xd4, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xcc, 0xbd, 0xbc, 0xff, 0xef, 0xe2, 0xdc, 0xff, 0xc6, 0xb1, 0xb4, 0xff,
+    0xac, 0x8d, 0x8c, 0xff, 0xac, 0x8d, 0x84, 0xff, 0xa4, 0x89, 0x7c, 0xff,
+    0x9c, 0x88, 0x7c, 0xff, 0x9c, 0x8e, 0x7c, 0xff, 0x9c, 0x8e, 0x7c, 0xff,
+    0xb1, 0xa3, 0x94, 0xff, 0xb1, 0xa3, 0x94, 0xff, 0xb4, 0xae, 0x9c, 0xff,
+    0xd9, 0xcc, 0xbc, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x81, 0x7e, 0x7c, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xa1, 0x99, 0x9c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0x88, 0x8a, 0x84, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x83, 0x82, 0x84, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0x9c, 0x9a, 0x94, 0xff, 0x89, 0x86, 0x84, 0xff, 0x71, 0x72, 0x6c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xe8, 0xe7, 0xe4, 0xff, 0xec, 0xea, 0xec, 0xff,
+    0xe8, 0xe7, 0xe4, 0xff, 0xe4, 0xe1, 0xe4, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xc4, 0xbe, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xc4, 0xc3, 0xc4, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0x9c, 0x9a, 0x94, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xd7, 0xd6, 0xd4, 0xff,
+    0xf2, 0xf0, 0xec, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0xdc, 0xba, 0xbc, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0xa4, 0x85, 0x84, 0xff, 0x9c, 0x88, 0x7c, 0xff,
+    0x9c, 0x88, 0x7c, 0xff, 0x9c, 0x88, 0x7c, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0xa4, 0x86, 0x74, 0xff, 0x9c, 0x88, 0x7c, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0xb1, 0xa3, 0x94, 0xff, 0xb4, 0xae, 0x9c, 0xff, 0xe2, 0xdc, 0xcc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0x9a, 0x94, 0x94, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x94, 0x8e, 0x94, 0xff, 0xba, 0xb6, 0xb4, 0xff, 0xcc, 0xcc, 0xcc, 0xff,
+    0xe8, 0xe7, 0xe4, 0xff, 0xd7, 0xd6, 0xd4, 0xff, 0xdc, 0xd6, 0xdc, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xba, 0xb6, 0xb4, 0xff,
+    0xd9, 0xd4, 0xcc, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xa1, 0x9e, 0x9c, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xf4, 0xea, 0xe4, 0xff, 0xbc, 0xb0, 0xac, 0xff,
+    0xbc, 0xaa, 0xac, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0xa4, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xbc, 0xa4, 0x9c, 0xff, 0xbf, 0xaa, 0xa4, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xac, 0x8d, 0x84, 0xff, 0x9c, 0x88, 0x7c, 0xff,
+    0x90, 0x7f, 0x74, 0xff, 0xac, 0x8d, 0x84, 0xff, 0xba, 0xb0, 0xa4, 0xff,
+    0xf4, 0xe9, 0xd4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf7, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0x89, 0x86, 0x84, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0xa3, 0xa3, 0xa4, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xac, 0xa9, 0xac, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0x8b, 0x8b, 0x8c, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xbc, 0xb9, 0xbc, 0xff,
+    0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xdc, 0xdc, 0xdc, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xbc, 0xb9, 0xbc, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0xdc, 0xdc, 0xdc, 0xff, 0xd6, 0xd2, 0xd4, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xbc, 0xb0, 0xac, 0xff, 0xa6, 0x95, 0x94, 0xff, 0x96, 0x86, 0x8c, 0xff,
+    0x9e, 0x8b, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xa4, 0x85, 0x84, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xa6, 0x95, 0x94, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0xa7, 0x94, 0x84, 0xff,
+    0xba, 0xb0, 0xa4, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf7, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x6a, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x7b, 0x7a, 0x7c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x9c, 0x9a, 0x94, 0xff,
+    0x71, 0x72, 0x74, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xc8, 0xca, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0xc2, 0xbe, 0xbc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xe4, 0xe1, 0xe4, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xd5, 0xcd, 0xcc, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x9c, 0x7a, 0x7c, 0xff, 0xa4, 0x85, 0x84, 0xff, 0xa4, 0x85, 0x84, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0xb4, 0x96, 0x94, 0xff,
+    0xbd, 0xa6, 0xa4, 0xff, 0xc5, 0xb7, 0xb4, 0xff, 0xbc, 0xa4, 0x9c, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0x9c, 0x88, 0x7c, 0xff, 0x9c, 0x88, 0x7c, 0xff,
+    0x9c, 0x92, 0x84, 0xff, 0xc7, 0xb8, 0xac, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0xa1, 0xa2, 0x9c, 0xff, 0xb4, 0xb2, 0xb4, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xc2, 0xc2, 0xbc, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0xa1, 0x9e, 0x9c, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0xdc, 0xd6, 0xdc, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xd4, 0xc6, 0xc4, 0xff,
+    0xc6, 0xb1, 0xb4, 0xff, 0xe6, 0xd6, 0xd6, 0xff, 0xcc, 0xbe, 0xc4, 0xff,
+    0xb4, 0x96, 0x94, 0xff, 0xa4, 0x85, 0x84, 0xff, 0x9c, 0x7a, 0x74, 0xff,
+    0x9c, 0x7a, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0xa6, 0x95, 0x94, 0xff, 0xb0, 0xa3, 0x9c, 0xff,
+    0xad, 0x9e, 0x9e, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0x90, 0x7f, 0x74, 0xff,
+    0x9c, 0x81, 0x74, 0xff, 0xa9, 0x9b, 0x8c, 0xff, 0xd8, 0xdc, 0xd4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x8b, 0x8b, 0x8c, 0xff, 0xc4, 0xc3, 0xc4, 0xff,
+    0x9a, 0x94, 0x94, 0xff, 0xb4, 0xb2, 0xb4, 0xff, 0x71, 0x72, 0x74, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x89, 0x86, 0x84, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0xbc, 0xb9, 0xbc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc2, 0xbe, 0xbc, 0xff,
+    0xa6, 0x95, 0x94, 0xff, 0xd4, 0xc6, 0xc4, 0xff, 0xe4, 0xd2, 0xd4, 0xff,
+    0xb4, 0x9b, 0x94, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x9c, 0x7a, 0x7c, 0xff,
+    0x9c, 0x7a, 0x74, 0xff, 0x8e, 0x7a, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xb4, 0x9b, 0x94, 0xff, 0xad, 0x9e, 0x9e, 0xff,
+    0xba, 0xb0, 0xa4, 0xff, 0xbf, 0xaa, 0xa4, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0x84, 0x7e, 0x74, 0xff, 0x90, 0x7f, 0x74, 0xff, 0xa9, 0x9b, 0x8c, 0xff,
+    0xd9, 0xc6, 0xb4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x63, 0x6a, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0xa1, 0x9e, 0x9c, 0xff,
+    0x81, 0x7e, 0x7c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x83, 0x82, 0x84, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0xb4, 0xb2, 0xb4, 0xff, 0xcc, 0xc5, 0xc4, 0xff, 0xac, 0xa9, 0xac, 0xff,
+    0x7b, 0x7a, 0x7c, 0xff, 0xbf, 0xaa, 0xa4, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x9c, 0x7a, 0x74, 0xff, 0x8e, 0x72, 0x74, 0xff,
+    0x9c, 0x7a, 0x7c, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0xae, 0xa4, 0xa4, 0xff, 0xbf, 0xaa, 0xa4, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x8a, 0x76, 0x6c, 0xff, 0x84, 0x7e, 0x74, 0xff,
+    0xa9, 0x9b, 0x8c, 0xff, 0xc9, 0xc0, 0xb4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x83, 0x82, 0x84, 0xff,
+    0xb3, 0xae, 0xac, 0xff, 0x9c, 0x9a, 0x94, 0xff, 0xa3, 0xa3, 0xa4, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x9c, 0x93, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x81, 0x72, 0x74, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x8f, 0x7f, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff, 0xa4, 0x85, 0x84, 0xff,
+    0xa8, 0x93, 0x8c, 0xff, 0xb4, 0x9b, 0x94, 0xff, 0xa8, 0x93, 0x8c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x8c, 0x6e, 0x64, 0xff, 0x90, 0x7f, 0x74, 0xff,
+    0xa7, 0x94, 0x84, 0xff, 0xb0, 0xa3, 0x9c, 0xff, 0xe4, 0xd2, 0xc4, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x64, 0x6a, 0x6c, 0xff, 0x92, 0x92, 0x8c, 0xff, 0x64, 0x6a, 0x6c, 0xff,
+    0x83, 0x82, 0x84, 0xff, 0x7b, 0x7a, 0x7c, 0xff, 0x8b, 0x8b, 0x8c, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x96, 0x85, 0x84, 0xff, 0x9c, 0x80, 0x7c, 0xff,
+    0x96, 0x85, 0x84, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0x9e, 0x8b, 0x84, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x9c, 0x92, 0x84, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0xa7, 0x94, 0x84, 0xff, 0xb1, 0xa3, 0x94, 0xff,
+    0xda, 0xd4, 0xc4, 0xff, 0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf3, 0xf2, 0xdc, 0xff, 0xf3, 0xf2, 0xdc, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x71, 0x72, 0x6c, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x96, 0x86, 0x8c, 0xff, 0xad, 0x9a, 0x9c, 0xff,
+    0xa4, 0x85, 0x84, 0xff, 0xa4, 0x85, 0x84, 0xff, 0x8d, 0x72, 0x6b, 0xff,
+    0x78, 0x66, 0x64, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x9c, 0x7a, 0x74, 0xff, 0xa4, 0x89, 0x7c, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0xe2, 0xdc, 0xcc, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x64, 0x6a, 0x6c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x81, 0x7e, 0x7c, 0xff, 0x78, 0x66, 0x64, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x9d, 0x8d, 0x8c, 0xff, 0xbc, 0xaa, 0xac, 0xff,
+    0xac, 0x8d, 0x8c, 0xff, 0x96, 0x86, 0x8c, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x75, 0x62, 0x64, 0xff, 0x84, 0x77, 0x74, 0xff, 0xbd, 0xa6, 0xa4, 0xff,
+    0x9c, 0x80, 0x7c, 0xff, 0x8e, 0x79, 0x74, 0xff, 0x9c, 0x7a, 0x74, 0xff,
+    0x9c, 0x88, 0x7c, 0xff, 0xa8, 0x9b, 0x94, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0xf2, 0xe9, 0xdc, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x70, 0x66, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x77, 0x66, 0x6c, 0xff, 0x7e, 0x6d, 0x6c, 0xff, 0x84, 0x79, 0x7c, 0xff,
+    0x96, 0x86, 0x8c, 0xff, 0xac, 0x8d, 0x84, 0xff, 0x8e, 0x72, 0x74, 0xff,
+    0x7f, 0x6a, 0x64, 0xff, 0xad, 0x9e, 0x9e, 0xff, 0xba, 0xb0, 0xa4, 0xff,
+    0xb4, 0x9b, 0x94, 0xff, 0x8e, 0x72, 0x74, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x8e, 0x79, 0x74, 0xff, 0x84, 0x7e, 0x74, 0xff, 0xda, 0xd4, 0xc4, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0xf4, 0xf8, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x53, 0x41, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x78, 0x66, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x6c, 0x61, 0x64, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0xa8, 0x93, 0x8c, 0xff, 0x8f, 0x7f, 0x7c, 0xff,
+    0x72, 0x62, 0x5c, 0xff, 0x7f, 0x72, 0x6c, 0xff, 0x9d, 0x8d, 0x8c, 0xff,
+    0xa8, 0x9b, 0x94, 0xff, 0x9c, 0x80, 0x7c, 0xff, 0x8e, 0x79, 0x74, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x8f, 0x86, 0x7c, 0xff, 0xb1, 0xaa, 0xa4, 0xff,
+    0xe4, 0xe2, 0xd8, 0xff, 0xf4, 0xf2, 0xe4, 0xff, 0xf3, 0xf2, 0xdc, 0xff,
+    0xf4, 0xf2, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x7e, 0x6d, 0x6c, 0xff, 0x8f, 0x7f, 0x7c, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x7e, 0x6d, 0x6c, 0xff,
+    0x9d, 0x8d, 0x8c, 0xff, 0x84, 0x79, 0x7c, 0xff, 0x7f, 0x72, 0x6c, 0xff,
+    0x7f, 0x72, 0x6c, 0xff, 0x7c, 0x72, 0x64, 0xff, 0x94, 0x8b, 0x84, 0xff,
+    0xda, 0xd4, 0xc4, 0xff, 0xf4, 0xea, 0xe4, 0xff, 0xf2, 0xe9, 0xdc, 0xff,
+    0xf4, 0xea, 0xe4, 0xff, 0xf4, 0xf8, 0xe4, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x6f, 0x6c, 0x6c, 0xff, 0x78, 0x66, 0x64, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x63, 0x66, 0x64, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x8c, 0x81, 0x84, 0xff, 0x81, 0x72, 0x74, 0xff, 0x81, 0x72, 0x74, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x63, 0x6a, 0x64, 0xff, 0x84, 0x7e, 0x74, 0xff,
+    0xc2, 0xbe, 0xbc, 0xff, 0xe4, 0xe2, 0xd8, 0xff, 0xc9, 0xc0, 0xb4, 0xff,
+    0xf4, 0xea, 0xe4, 0xff, 0xf4, 0xf2, 0xe4, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x69, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x70, 0x5e, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x63, 0x66, 0x64, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x81, 0x72, 0x74, 0xff, 0x84, 0x77, 0x74, 0xff, 0x77, 0x66, 0x6c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x71, 0x72, 0x6c, 0xff,
+    0xb1, 0xaa, 0xa4, 0xff, 0xd6, 0xc5, 0xbc, 0xff, 0x9a, 0x94, 0x94, 0xff,
+    0xd9, 0xd4, 0xcc, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x6b, 0x56, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x6c, 0x61, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x6c, 0x61, 0x64, 0xff,
+    0x6c, 0x66, 0x6c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x71, 0x6a, 0x64, 0xff, 0x6f, 0x6c, 0x6c, 0xff,
+    0x84, 0x77, 0x74, 0xff, 0x89, 0x86, 0x84, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0xcc, 0xc2, 0xbc, 0xff, 0xe4, 0xe2, 0xd8, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x2e, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x6f, 0x6c, 0x6c, 0xff, 0x71, 0x6a, 0x64, 0xff,
+    0x71, 0x6a, 0x64, 0xff, 0x70, 0x66, 0x5c, 0xff, 0x72, 0x62, 0x5c, 0xff,
+    0x88, 0x8a, 0x84, 0xff, 0xa8, 0x9b, 0x94, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x5f, 0x62, 0x64, 0xff, 0x5f, 0x62, 0x64, 0xff, 0x5d, 0x62, 0x5c, 0xff,
+    0x63, 0x66, 0x64, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x72, 0x5b, 0x54, 0xff,
+    0x78, 0x77, 0x74, 0xff, 0x8f, 0x86, 0x7c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x5d, 0x62, 0x5c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x70, 0x5e, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x70, 0x66, 0x5c, 0xff, 0x63, 0x66, 0x64, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x6b, 0x56, 0x5c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x69, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x2e, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x64, 0x5d, 0x5c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x2c, 0x26, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x64, 0x4e, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x69, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x2e, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x46, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x53, 0x41, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x5d, 0x5a, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x50, 0x4e, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x46, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x5d, 0x5a, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x50, 0x4e, 0x44, 0xff, 0x44, 0x46, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff, 0x53, 0x5a, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x64, 0x5d, 0x5c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x2e, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x5f, 0x62, 0x64, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x46, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x50, 0x4e, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x64, 0x4e, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x44, 0x46, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x53, 0x5a, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x53, 0x41, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x46, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x46, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x46, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x44, 0x46, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x3c, 0x32, 0x2c, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x53, 0x41, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x53, 0x41, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x4c, 0x52, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x58, 0x5c, 0x5c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x58, 0x49, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x53, 0x41, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x2e, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x64, 0x4e, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x46, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x55, 0x52, 0x4c, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x5d, 0x5a, 0x54, 0xff, 0x6b, 0x56, 0x5c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x53, 0x41, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x3c, 0x32, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x5c, 0x3e, 0x34, 0xff, 0x3c, 0x32, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x49, 0x4c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x53, 0x41, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x5d, 0x62, 0x5c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x44, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x2c, 0x26, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x58, 0x5c, 0x5c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x4e, 0x4c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x30, 0x26, 0x24, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x44, 0x47, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x55, 0x54, 0xff, 0x58, 0x49, 0x4c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x55, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x53, 0x5a, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x30, 0x26, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x55, 0x4e, 0x4c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x2c, 0x26, 0x2c, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x2c, 0x26, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x34, 0x2e, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x2e, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x4e, 0x42, 0x44, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x4e, 0x42, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x34, 0x32, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x3a, 0x3c, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x49, 0x4a, 0x4c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x30, 0x26, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x4c, 0x47, 0x44, 0xff, 0x4c, 0x53, 0x54, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x2c, 0x26, 0x2c, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x2c, 0x26, 0x2c, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x55, 0x55, 0x54, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x44, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x42, 0x42, 0x44, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff,
+    0x30, 0x2a, 0x24, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3b, 0x3a, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x53, 0x54, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x34, 0x33, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x34, 0x33, 0x34, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x34, 0x33, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x2e, 0x2c, 0xff, 0x3c, 0x2e, 0x2c, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x26, 0x24, 0xff, 0x30, 0x26, 0x24, 0xff,
+    0x3c, 0x2e, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x30, 0x2a, 0x24, 0xff, 0x33, 0x2c, 0x2c, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x55, 0x52, 0x4c, 0xff, 0x55, 0x52, 0x4c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x3c, 0x32, 0x2c, 0xff, 0x33, 0x2c, 0x2c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x4c, 0x53, 0x54, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4c, 0x52, 0x4c, 0xff,
+    0x4b, 0x4e, 0x4c, 0xff, 0x55, 0x55, 0x54, 0xff, 0x4b, 0x4e, 0x4c, 0xff,
+    0x49, 0x4a, 0x4c, 0xff, 0x34, 0x32, 0x2c, 0xff, 0x34, 0x32, 0x2c, 0xff,
+    0x33, 0x2c, 0x2c, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x4e, 0x42, 0x44, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x34, 0x2e, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3c, 0x35, 0x34, 0xff, 0x3b, 0x3a, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x34, 0xff, 0x44, 0x3a, 0x3c, 0xff, 0x42, 0x42, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff, 0x49, 0x4a, 0x4c, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x3c, 0x35, 0x34, 0xff, 0x3c, 0x35, 0x34, 0xff,
+    0x3b, 0x3a, 0x3c, 0xff, 0x40, 0x3f, 0x3c, 0xff, 0x44, 0x47, 0x44, 0xff,
+    0x44, 0x47, 0x44, 0xff, 0x4c, 0x47, 0x44, 0xff,
+};
+
+#endif  // WEBP_TESTS_FUZZER_IMG_PEAK_H_
diff --git a/third_party/libwebp/tests/fuzzer/makefile.unix b/third_party/libwebp/tests/fuzzer/makefile.unix
new file mode 100644
index 0000000..4a9bff3
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/makefile.unix
@@ -0,0 +1,31 @@
+# This Makefile will compile all fuzzing targets. It doesn't check tool
+# requirements and paths may need to be updated depending on your environment.
+# Note a clang 6+ toolchain is assumed for use of -fsanitize=fuzzer.
+
+CC = clang
+CXX = clang++
+CFLAGS = -fsanitize=fuzzer -I../../src -I../.. -Wall -Wextra
+CXXFLAGS = $(CFLAGS)
+LDFLAGS = -fsanitize=fuzzer
+LDLIBS = ../../src/mux/libwebpmux.a ../../src/demux/libwebpdemux.a
+LDLIBS += ../../src/libwebp.a ../../imageio/libimageio_util.a
+LDLIBS += ../../sharpyuv/libsharpyuv.a
+
+FUZZERS = advanced_api_fuzzer animation_api_fuzzer animencoder_fuzzer
+FUZZERS += animdecoder_fuzzer mux_demux_api_fuzzer enc_dec_fuzzer
+FUZZERS += simple_api_fuzzer
+
+%.o: fuzz_utils.h img_alpha.h img_grid.h img_peak.h
+all: $(FUZZERS)
+
+define FUZZER_template
+$(1): $$(addsuffix .o, $(1)) $(LDLIBS)
+OBJS += $$(addsuffix .o, $(1))
+endef
+
+$(foreach fuzzer, $(FUZZERS), $(eval $(call FUZZER_template, $(fuzzer))))
+
+clean:
+	$(RM) $(FUZZERS) $(OBJS)
+
+.PHONY: all clean
diff --git a/third_party/libwebp/tests/fuzzer/mux_demux_api_fuzzer.c b/third_party/libwebp/tests/fuzzer/mux_demux_api_fuzzer.c
new file mode 100644
index 0000000..4ed0142
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/mux_demux_api_fuzzer.c
@@ -0,0 +1,96 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "./fuzz_utils.h"
+#include "src/webp/demux.h"
+#include "src/webp/mux.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  WebPData webp_data;
+  WebPDataInit(&webp_data);
+  webp_data.size = size;
+  webp_data.bytes = data;
+
+  // Extracted chunks and frames are not processed or decoded,
+  // which is already covered extensively by the other fuzz targets.
+
+  if (size & 1) {
+    // Mux API
+    WebPMux* mux = WebPMuxCreate(&webp_data, size & 2);
+    if (!mux) return 0;
+
+    WebPData chunk;
+    WebPMuxGetChunk(mux, "EXIF", &chunk);
+    WebPMuxGetChunk(mux, "ICCP", &chunk);
+    WebPMuxGetChunk(mux, "FUZZ", &chunk);  // unknown
+
+    uint32_t flags;
+    WebPMuxGetFeatures(mux, &flags);
+
+    WebPMuxAnimParams params;
+    WebPMuxGetAnimationParams(mux, &params);
+
+    WebPMuxError status;
+    WebPMuxFrameInfo info;
+    for (int i = 0; i < kFuzzFrameLimit; i++) {
+      status = WebPMuxGetFrame(mux, i + 1, &info);
+      if (status == WEBP_MUX_NOT_FOUND) {
+        break;
+      } else if (status == WEBP_MUX_OK) {
+        WebPDataClear(&info.bitstream);
+      }
+    }
+
+    WebPMuxDelete(mux);
+  } else {
+    // Demux API
+    WebPDemuxer* demux;
+    if (size & 2) {
+      WebPDemuxState state;
+      demux = WebPDemuxPartial(&webp_data, &state);
+      if (state < WEBP_DEMUX_PARSED_HEADER) {
+        WebPDemuxDelete(demux);
+        return 0;
+      }
+    } else {
+      demux = WebPDemux(&webp_data);
+      if (!demux) return 0;
+    }
+
+    WebPChunkIterator chunk_iter;
+    if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
+      WebPDemuxNextChunk(&chunk_iter);
+    }
+    WebPDemuxReleaseChunkIterator(&chunk_iter);
+    if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) {  // 0 == last
+      WebPDemuxPrevChunk(&chunk_iter);
+    }
+    WebPDemuxReleaseChunkIterator(&chunk_iter);
+    // Skips FUZZ because the Demux API has no concept of (un)known chunks.
+
+    WebPIterator iter;
+    if (WebPDemuxGetFrame(demux, 1, &iter)) {
+      for (int i = 1; i < kFuzzFrameLimit; i++) {
+        if (!WebPDemuxNextFrame(&iter)) break;
+      }
+    }
+
+    WebPDemuxReleaseIterator(&iter);
+    WebPDemuxDelete(demux);
+  }
+
+  return 0;
+}
diff --git a/third_party/libwebp/tests/fuzzer/simple_api_fuzzer.c b/third_party/libwebp/tests/fuzzer/simple_api_fuzzer.c
new file mode 100644
index 0000000..7d2b7f8
--- /dev/null
+++ b/third_party/libwebp/tests/fuzzer/simple_api_fuzzer.c
@@ -0,0 +1,88 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "./fuzz_utils.h"
+#include "src/webp/decode.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
+  int w, h;
+  if (!WebPGetInfo(data, size, &w, &h)) return 0;
+  if ((size_t)w * h > kFuzzPxLimit) return 0;
+
+  const uint8_t value = FuzzHash(data, size);
+  uint8_t* buf = NULL;
+
+  // For *Into functions, which decode into an external buffer, an
+  // intentionally too small buffer can be given with low probability.
+  if (value < 0x16) {
+    buf = WebPDecodeRGBA(data, size, &w, &h);
+  } else if (value < 0x2b) {
+    buf = WebPDecodeBGRA(data, size, &w, &h);
+#if !defined(WEBP_REDUCE_CSP)
+  } else if (value < 0x40) {
+    buf = WebPDecodeARGB(data, size, &w, &h);
+  } else if (value < 0x55) {
+    buf = WebPDecodeRGB(data, size, &w, &h);
+  } else if (value < 0x6a) {
+    buf = WebPDecodeBGR(data, size, &w, &h);
+#endif  // !defined(WEBP_REDUCE_CSP)
+  } else if (value < 0x7f) {
+    uint8_t *u, *v;
+    int stride, uv_stride;
+    buf = WebPDecodeYUV(data, size, &w, &h, &u, &v, &stride, &uv_stride);
+  } else if (value < 0xe8) {
+    const int stride = (value < 0xbe ? 4 : 3) * w;
+    size_t buf_size = stride * h;
+    if (value % 0x10 == 0) buf_size--;
+    uint8_t* const ext_buf = (uint8_t*)malloc(buf_size);
+    if (value < 0x94) {
+      WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride);
+#if !defined(WEBP_REDUCE_CSP)
+    } else if (value < 0xa9) {
+      WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride);
+    } else if (value < 0xbe) {
+      WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride);
+    } else if (value < 0xd3) {
+      WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride);
+#endif  // !defined(WEBP_REDUCE_CSP)
+    } else {
+      WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride);
+    }
+    free(ext_buf);
+  } else {
+    size_t luma_size = w * h;
+    const int uv_stride = (w + 1) / 2;
+    size_t u_size = uv_stride * (h + 1) / 2;
+    size_t v_size = uv_stride * (h + 1) / 2;
+    if (value % 0x10 == 0) {
+      if (size & 1) luma_size--;
+      if (size & 2) u_size--;
+      if (size & 4) v_size--;
+    }
+    uint8_t* const luma_buf = (uint8_t*)malloc(luma_size);
+    uint8_t* const u_buf = (uint8_t*)malloc(u_size);
+    uint8_t* const v_buf = (uint8_t*)malloc(v_size);
+    WebPDecodeYUVInto(data, size, luma_buf, luma_size, w /* luma_stride */,
+                      u_buf, u_size, uv_stride, v_buf, v_size, uv_stride);
+    free(luma_buf);
+    free(u_buf);
+    free(v_buf);
+  }
+
+  if (buf) WebPFree(buf);
+
+  return 0;
+}
diff --git a/third_party/libwebp/webp_js/README.md b/third_party/libwebp/webp_js/README.md
new file mode 100644
index 0000000..824afa0
--- /dev/null
+++ b/third_party/libwebp/webp_js/README.md
@@ -0,0 +1,81 @@
+# WebP JavaScript decoder
+
+```
+ __   __ ____ ____ ____     __  ____
+/  \\/  \  _ \  _ \  _ \   (__)/  __\
+\       /  __/ _  \  __/   _)  \_   \
+ \__\__/_____/____/_/     /____/____/
+```
+
+This file describes the compilation of libwebp into a JavaScript decoder using
+Emscripten and CMake.
+
+-   install the Emscripten SDK following the procedure described at:
+    https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended
+    After installation, you should have some global variable positioned to the
+    location of the SDK. In particular, $EMSDK should point to the top-level
+    directory containing Emscripten tools.
+
+-   configure the project 'WEBP_JS' with CMake using:
+
+    ```shell
+    cd webp_js && \
+    emcmake cmake -DWEBP_BUILD_WEBP_JS=ON \
+          ../
+    ```
+
+-   compile webp.js using 'emmake make'.
+
+-   that's it! Upon completion, you should have the 'webp.js', 'webp.js.mem',
+    'webp_wasm.js' and 'webp_wasm.wasm' files generated.
+
+The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
+bitstream into a canvas. See webp_js/index.html for a simple usage sample (see
+below for instructions).
+
+## Demo HTML page
+
+The HTML page webp_js/index.html requires the built files 'webp.js' and
+'webp.js.mem' to be copied to webp_js/. An HTTP server to serve the WebP image
+example is also needed. With Python, just run:
+
+```shell
+cd webp_js && python3 -m http.server 8080
+```
+
+and then navigate to http://localhost:8080 in your favorite browser.
+
+## Web-Assembly (WASM) version:
+
+CMakeLists.txt is configured to build the WASM version when using the option
+WEBP_BUILD_WEBP_JS=ON. The compilation step will assemble the files
+'webp_wasm.js' and 'webp_wasm.wasm' that you then need to copy to the webp_js/
+directory.
+
+See webp_js/index_wasm.html for a simple demo page using the WASM version of the
+library.
+
+You will need a fairly recent version of Emscripten (at least 2.0.18,
+latest-upstream is recommended) and of your WASM-enabled browser to run this
+version.
+
+## Caveats
+
+-   First decoding using the library is usually slower, due to just-in-time
+    compilation.
+
+-   Some versions of llvm produce the following compile error when SSE2 is
+    enabled.
+
+    ```
+    "Unsupported:   %516 = bitcast <8 x i16> %481 to i128
+    LLVM ERROR: BitCast Instruction not yet supported for integer types larger than 64 bits"
+    ```
+
+    The corresponding Emscripten bug is at:
+    https://github.com/kripken/emscripten/issues/3788
+
+    Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
+
+-   If WEBP_ENABLE_SIMD is set to 1 the JavaScript version (webp.js) will be
+    disabled as wasm2js does not support SIMD.
diff --git a/third_party/libwebp/webp_js/index.html b/third_party/libwebp/webp_js/index.html
index 10873a9..33cacb4 100644
--- a/third_party/libwebp/webp_js/index.html
+++ b/third_party/libwebp/webp_js/index.html
@@ -18,7 +18,7 @@
 var WebpToCanvas;
 
 function init() {
-  WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']);
+  WebpToCanvas = Module.cwrap('WebPToSDL', 'number', ['array', 'number']);
 }
 window.onload = init;
 
diff --git a/third_party/libwebp/webp_js/index_wasm.html b/third_party/libwebp/webp_js/index_wasm.html
index b77c22c..5d7c17e 100644
--- a/third_party/libwebp/webp_js/index_wasm.html
+++ b/third_party/libwebp/webp_js/index_wasm.html
@@ -34,7 +34,7 @@
   var result;
   if (Module["asm"] != undefined) {
     // wrapper for the function decoding a WebP into a canvas object
-    WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']);
+    WebpToCanvas = Module.cwrap('WebPToSDL', 'number', ['array', 'number']);
     // get the canvas to decode into
     var canvas = document.getElementById(canvas_id);
     if (canvas == null) return;
diff --git a/third_party/libwebp/xcframeworkbuild.sh b/third_party/libwebp/xcframeworkbuild.sh
new file mode 100755
index 0000000..8d484c2
--- /dev/null
+++ b/third_party/libwebp/xcframeworkbuild.sh
@@ -0,0 +1,255 @@
+#!/bin/bash
+#
+# This script generates 'WebP.xcframework', 'WebPDecoder.xcframework',
+# 'WebPDemux.xcframework' and 'WebPMux.xcframework'.
+# An iOS, Mac or Mac Catalyst app can decode WebP images by including
+# 'WebPDecoder.xcframework' and both encode and decode WebP images by including
+# 'WebP.xcframework'.
+#
+# Run ./xcframeworkbuild.sh to generate the frameworks under the current
+# directory (the previous build will be erased if it exists).
+#
+
+set -e
+
+# Set these variables based on the desired minimum deployment target.
+readonly IOS_MIN_VERSION=6.0
+readonly MACOSX_MIN_VERSION=10.15
+readonly MACOSX_CATALYST_MIN_VERSION=14.0
+
+# Extract Xcode version.
+readonly XCODE=$(xcodebuild -version | grep Xcode | cut -d " " -f2)
+if [[ -z "${XCODE}" ]] || [[ "${XCODE%%.*}" -lt 11 ]]; then
+  echo "Xcode 11.0 or higher is required!"
+  exit 1
+fi
+
+# Extract the latest SDK version from the final field of the form: iphoneosX.Y
+# / macosxX.Y
+readonly SDK=($(
+  xcodebuild -showsdks \
+    | grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
+  xcodebuild -showsdks \
+    | grep macosx | sort | tail -n 1 | awk '{print substr($NF, 7)}'
+))
+readonly IOS=0
+readonly MACOS=1
+readonly IOS_SIMULATOR=2
+readonly MACOS_CATALYST=3
+readonly NUM_PLATFORMS=4
+
+readonly OLDPATH=${PATH}
+
+# Names should be of the form '<platform>-[<variant>-]<architecture>'.
+PLATFORMS[$IOS]="iPhoneOS-armv7 iPhoneOS-armv7s iPhoneOS-arm64"
+PLATFORMS[$IOS_SIMULATOR]="iPhoneSimulator-i386 iPhoneSimulator-x86_64"
+PLATFORMS[$MACOS]="MacOSX-x86_64"
+PLATFORMS[$MACOS_CATALYST]="MacOSX-Catalyst-x86_64"
+if [[ "${XCODE%%.*}" -ge 12 ]]; then
+  PLATFORMS[$MACOS]+=" MacOSX-arm64"
+  PLATFORMS[$MACOS_CATALYST]+=" MacOSX-Catalyst-arm64"
+  PLATFORMS[$IOS_SIMULATOR]+=" iPhoneSimulator-arm64"
+elif [[ "${XCODE%%.*}" -eq 11 ]]; then
+  cat << EOF
+WARNING: Xcode 12.0 or higher is required to build targets for
+WARNING: Apple Silicon (arm64). The XCFrameworks generated with Xcode 11 will
+WARNING: contain libraries for MacOS & Catalyst supporting x86_64 only.
+WARNING: The build will continue in 5 seconds...
+EOF
+  sleep 5
+else
+  echo "Xcode 11.0 or higher is required!"
+  exit 1
+fi
+readonly PLATFORMS
+readonly SRCDIR=$(dirname $0)
+readonly TOPDIR=$(pwd)
+readonly BUILDDIR="${TOPDIR}/xcframeworkbuild"
+readonly TARGETDIR="${TOPDIR}/WebP.xcframework"
+readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.xcframework"
+readonly MUXTARGETDIR="${TOPDIR}/WebPMux.xcframework"
+readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.xcframework"
+readonly DEVELOPER=$(xcode-select --print-path)
+readonly DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain"
+readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
+readonly LIPO=$(xcrun -sdk iphoneos${SDK[$IOS]} -find lipo)
+
+if [[ -z "${SDK[$IOS]}" ]] || [[ ${SDK[$IOS]%%.*} -lt 8 ]]; then
+  echo "iOS SDK version 8.0 or higher is required!"
+  exit 1
+fi
+
+#######################################
+# Moves Headers/*.h to Headers/<framework>/
+#
+# Places framework headers in a subdirectory to avoid Xcode errors when using
+# multiple frameworks:
+#   error: Multiple commands produce
+#     '.../Build/Products/Debug-iphoneos/include/types.h'
+# Arguments:
+#   $1 - path to framework
+#######################################
+update_headers_path() {
+  local framework_name="$(basename ${1%.xcframework})"
+  local subdir
+  for d in $(find "$1" -path "*/Headers"); do
+    subdir="$d/$framework_name"
+    mkdir "$subdir"
+    mv "$d/"*.h "$subdir"
+  done
+}
+
+echo "Xcode Version: ${XCODE}"
+echo "iOS SDK Version: ${SDK[$IOS]}"
+echo "MacOS SDK Version: ${SDK[$MACOS]}"
+
+if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
+      || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
+  cat << EOF
+WARNING: The following directories will be deleted:
+WARNING:   ${BUILDDIR}
+WARNING:   ${TARGETDIR}
+WARNING:   ${DECTARGETDIR}
+WARNING:   ${MUXTARGETDIR}
+WARNING:   ${DEMUXTARGETDIR}
+WARNING: The build will continue in 5 seconds...
+EOF
+  sleep 5
+fi
+rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
+  ${MUXTARGETDIR} ${DEMUXTARGETDIR}
+
+if [[ ! -e ${SRCDIR}/configure ]]; then
+  if ! (cd ${SRCDIR} && sh autogen.sh); then
+    cat << EOF
+Error creating configure script!
+This script requires the autoconf/automake and libtool to build. MacPorts or
+Homebrew can be used to obtain these:
+https://www.macports.org/install.php
+https://brew.sh/
+EOF
+    exit 1
+  fi
+fi
+
+for (( i = 0; i < $NUM_PLATFORMS; ++i )); do
+  LIBLIST=()
+  DECLIBLIST=()
+  MUXLIBLIST=()
+  DEMUXLIBLIST=()
+
+  for PLATFORM in ${PLATFORMS[$i]}; do
+    ROOTDIR="${BUILDDIR}/${PLATFORM}"
+    mkdir -p "${ROOTDIR}"
+
+    ARCH="${PLATFORM##*-}"
+    case "${PLATFORM}" in
+      iPhone*)
+        sdk="${SDK[$IOS]}"
+        ;;
+      MacOS*)
+        sdk="${SDK[$MACOS]}"
+        ;;
+      *)
+        echo "Unrecognized platform: ${PLATFORM}!"
+        exit 1
+        ;;
+    esac
+
+    SDKROOT="${PLATFORMSROOT}/${PLATFORM%%-*}.platform/"
+    SDKROOT+="Developer/SDKs/${PLATFORM%%-*}${sdk}.sdk/"
+    CFLAGS="-pipe -isysroot ${SDKROOT} -O3 -DNDEBUG"
+    case "${PLATFORM}" in
+      iPhone*)
+        CFLAGS+=" -fembed-bitcode"
+        CFLAGS+=" -target ${ARCH}-apple-ios${IOS_MIN_VERSION}"
+        [[ "${PLATFORM}" == *Simulator* ]] && CFLAGS+="-simulator"
+        ;;
+      MacOSX-Catalyst*)
+        CFLAGS+=" -target"
+        CFLAGS+=" ${ARCH}-apple-ios${MACOSX_CATALYST_MIN_VERSION}-macabi"
+        ;;
+      MacOSX*)
+        CFLAGS+=" -mmacosx-version-min=${MACOSX_MIN_VERSION}"
+        ;;
+    esac
+
+    set -x
+    export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
+    ${SRCDIR}/configure --host=${ARCH/arm64/aarch64}-apple-darwin \
+      --build=$(${SRCDIR}/config.guess) \
+      --prefix=${ROOTDIR} \
+      --disable-shared --enable-static \
+      --enable-libwebpdecoder --enable-swap-16bit-csp \
+      --enable-libwebpmux \
+      CC="clang -arch ${ARCH}" \
+      CFLAGS="${CFLAGS}"
+    set +x
+
+    # Build only the libraries, skip the examples.
+    make V=0 -C sharpyuv
+    make V=0 -C src install
+
+    LIBLIST+=("${ROOTDIR}/lib/libwebp.a")
+    DECLIBLIST+=("${ROOTDIR}/lib/libwebpdecoder.a")
+    MUXLIBLIST+=("${ROOTDIR}/lib/libwebpmux.a")
+    DEMUXLIBLIST+=("${ROOTDIR}/lib/libwebpdemux.a")
+    # xcodebuild requires a directory for the -headers option, these will match
+    # for all builds.
+    make -C src install-data DESTDIR="${ROOTDIR}/lib-headers"
+    make -C src install-commonHEADERS DESTDIR="${ROOTDIR}/dec-headers"
+    make -C src/demux install-data DESTDIR="${ROOTDIR}/demux-headers"
+    make -C src/mux install-data DESTDIR="${ROOTDIR}/mux-headers"
+    LIB_HEADERS="${ROOTDIR}/lib-headers/${ROOTDIR}/include/webp"
+    DEC_HEADERS="${ROOTDIR}/dec-headers/${ROOTDIR}/include/webp"
+    DEMUX_HEADERS="${ROOTDIR}/demux-headers/${ROOTDIR}/include/webp"
+    MUX_HEADERS="${ROOTDIR}/mux-headers/${ROOTDIR}/include/webp"
+
+    make distclean
+
+    export PATH=${OLDPATH}
+  done
+
+  [[ -z "${LIBLIST[@]}" ]] && continue
+
+  # Create a temporary target directory for each <platform>[-<variant>].
+  target_dir="${BUILDDIR}/${PLATFORMS[$i]}"
+  target_dir="${target_dir%% *}"
+  target_dir="${target_dir%-*}"
+  target_lib="${target_dir}/$(basename ${LIBLIST[0]})"
+  target_declib="${target_dir}/$(basename ${DECLIBLIST[0]})"
+  target_demuxlib="${target_dir}/$(basename ${DEMUXLIBLIST[0]})"
+  target_muxlib="${target_dir}/$(basename ${MUXLIBLIST[0]})"
+
+  mkdir -p "${target_dir}"
+  ${LIPO} -create ${LIBLIST[@]} -output "${target_lib}"
+  ${LIPO} -create ${DECLIBLIST[@]} -output "${target_declib}"
+  ${LIPO} -create ${DEMUXLIBLIST[@]} -output "${target_demuxlib}"
+  ${LIPO} -create ${MUXLIBLIST[@]} -output "${target_muxlib}"
+  FAT_LIBLIST+=(-library "${target_lib}" -headers "${LIB_HEADERS}")
+  FAT_DECLIBLIST+=(-library "${target_declib}" -headers "${DEC_HEADERS}")
+  FAT_DEMUXLIBLIST+=(-library "${target_demuxlib}" -headers "${DEMUX_HEADERS}")
+  FAT_MUXLIBLIST+=(-library "${target_muxlib}" -headers "${MUX_HEADERS}")
+done
+
+# lipo will not put archives with the same architecture (e.g., x86_64
+# iPhoneSimulator & MacOS) in the same fat output file. xcodebuild
+# -create-xcframework requires universal archives to avoid e.g.:
+#   Both ios-x86_64-maccatalyst and ios-arm64-maccatalyst represent two
+#   equivalent library definitions
+set -x
+xcodebuild -create-xcframework "${FAT_LIBLIST[@]}" \
+  -output ${TARGETDIR}
+xcodebuild -create-xcframework "${FAT_DECLIBLIST[@]}" \
+  -output ${DECTARGETDIR}
+xcodebuild -create-xcframework "${FAT_DEMUXLIBLIST[@]}" \
+  -output ${DEMUXTARGETDIR}
+xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
+  -output ${MUXTARGETDIR}
+update_headers_path "${TARGETDIR}"
+update_headers_path "${DECTARGETDIR}"
+update_headers_path "${DEMUXTARGETDIR}"
+update_headers_path "${MUXTARGETDIR}"
+set +x
+
+echo  "SUCCESS"
diff --git a/third_party/metrics_proto/BUILD.gn b/third_party/metrics_proto/BUILD.gn
index 24ae43b..4a918b8 100644
--- a/third_party/metrics_proto/BUILD.gn
+++ b/third_party/metrics_proto/BUILD.gn
@@ -46,5 +46,12 @@
     generate_python = false
 
     sources += [ "cobalt_uma_event.proto" ]
+    # Currently unused protos removed to save on binary size. See b/290819695.
+    sources -= [
+      "memory_leak_report.proto",
+      "omnibox_event.proto",
+      "omnibox_input_type.proto",
+      "sampled_profile.proto",
+    ]
   }
 }
diff --git a/third_party/metrics_proto/chrome_user_metrics_extension.proto b/third_party/metrics_proto/chrome_user_metrics_extension.proto
index 7255f27..788b674 100644
--- a/third_party/metrics_proto/chrome_user_metrics_extension.proto
+++ b/third_party/metrics_proto/chrome_user_metrics_extension.proto
@@ -13,12 +13,14 @@
 
 import "cast_logs.proto";
 import "histogram_event.proto";
-import "memory_leak_report.proto";
-import "omnibox_event.proto";
+// Cobalt-only change to reduce compiled binary byte size. See b/290819695.
+//import "memory_leak_report.proto";
+//import "omnibox_event.proto";
 import "perf_data.proto";
 import "printer_event.proto";
 import "reporting_info.proto";
-import "sampled_profile.proto";
+// Cobalt-only change to reduce compiled binary byte size. See b/290819695.
+//import "sampled_profile.proto";
 import "system_profile.proto";
 import "translate_event.proto";
 import "user_action_event.proto";
@@ -66,7 +68,8 @@
 
   // This message will log one or more of the following event types:
   repeated UserActionEventProto user_action_event = 4;
-  repeated OmniboxEventProto omnibox_event = 5;
+  // Cobalt-only change to reduce compiled binary byte size. See b/290819695.
+  //repeated OmniboxEventProto omnibox_event = 5;
   repeated HistogramEventProto histogram_event = 6;
   repeated TranslateEventProto translate_event = 15;
   repeated PrinterEventProto printer_event = 16;
@@ -74,14 +77,16 @@
   // Deprecated: use |sampled_profile| instead.
   repeated PerfDataProto perf_data = 8 [deprecated = true];
 
+  // Cobalt-only change to reduce compiled binary byte size. See b/290819695.
   // A list of all collected sample-based profiles since the last UMA upload.
-  repeated SampledProfile sampled_profile = 11;
+  //repeated SampledProfile sampled_profile = 11;
 
   // Additional data related with Cast-enabled devices.
   optional CastLogsProto cast_logs = 12;
 
+  // Cobalt-only change to reduce compiled binary byte size. See b/290819695.
   // Memory leak reports generated since the last UMA upload.
-  repeated MemoryLeakReportProto memory_leak_report = 13;
+  //repeated MemoryLeakReportProto memory_leak_report = 13;
 
   // The ReportingInfo message sent in the X-Chrome-UMA-ReportingInfo header.
   // Copied in by the receiving server.